Exemple #1
0
def fill_su2_components_into_suN(dst, su2_comps, su2_indices, cache=None):

    if isinstance(dst, gpt.lattice):
        n_colors = dst.otype.Nc
        separated = gpt.separate_color(dst)
    elif isinstance(dst, dict):
        n_keys = len(dst)
        n_colors = int(np.sqrt(n_keys))
        assert (int(n_colors) - 1, int(n_colors) - 1) in dst
        separated = dst

    if cache is None:
        zero = gpt.complex(separated[0, 0].grid)
        zero[:] = 0.0
        one = gpt.complex(separated[0, 0].grid)
        one[:] = 1.0
    else:
        zero, one = cache

    i1, i2 = su2_indices

    separated[i1, i1] @= su2_comps[0] + 1j * su2_comps[3]
    separated[i1, i2] @= su2_comps[2] + 1j * su2_comps[1]
    separated[i2, i1] @= -su2_comps[2] + 1j * su2_comps[1]
    separated[i2, i2] @= su2_comps[0] - 1j * su2_comps[3]
    for ii in range(n_colors):
        for jj in range(n_colors):
            if ii not in [i1, i2] or jj not in [i1, i2]:
                separated[ii, jj] @= one if ii == jj else zero

    if isinstance(dst, gpt.lattice):
        gpt.merge_color(dst, separated)
Exemple #2
0
def fundamental_to_adjoint(U_a, U_f):
    grid = U_f.grid
    T = U_f.otype.cartesian().generators(grid.precision.complex_dtype)
    V = {}
    for a in range(len(T)):
        for b in range(len(T)):
            V[a,
              b] = gpt.eval(2.0 * gpt.trace(T[a] * U_f * T[b] * gpt.adj(U_f)))
    gpt.merge_color(U_a, V)
Exemple #3
0
def color_transpose(l):
    xc = gpt.separate_color(l)
    Nc = l[:].shape[-1]
    y = {}
    for i in range(Nc):
        for j in range(Nc):
            y[i, j] = xc[j, i]
    dst = gpt.mspincolor(l.grid)
    gpt.merge_color(dst, y)
    return dst
Exemple #4
0
def fundamental_to_adjoint(U_a, U_f):
    """
    Convert fundamental to adjoint representation.  For now only SU(2) is supported.

    Input: fundamental gauge field

    Output: adjoint gauge field
    """
    grid = U_f.grid
    T = U_f.otype.generators(grid.precision.complex_dtype)
    V = {}
    for a in range(len(T)):
        for b in range(len(T)):
            V[a, b] = g.eval(2.0 * g.trace(T[a] * U_f * T[b] * g.adj(U_f)))
    g.merge_color(U_a, V)
Exemple #5
0
def diquark(Q1, Q2):
    eps = g.epsilon(Q1.otype.shape[2])
    R = g.lattice(Q1)

    # D_{a2,a1} = epsilon_{a1,b1,c1}*epsilon_{a2,b2,c2}*spin_transpose(Q1_{b1,b2})*Q2_{c1,c2}
    Q1 = g.separate_color(Q1)
    Q2 = g.separate_color(Q2)

    D = {x: g.lattice(Q1[x]) for x in Q1}
    for d in D:
        D[d][:] = 0

    for i1, sign1 in eps:
        for i2, sign2 in eps:
            D[i2[0], i1[0]] += (sign1 * sign2 * Q1[i1[1], i2[1]] *
                                g.transpose(Q2[i1[2], i2[2]]))

    g.merge_color(R, D)
    return R
Exemple #6
0
def project_to_suN_step(dest, unprojected):
    t_total = -gpt.time()
    t_product, t_separate, t_merge, t_su2extract, t_su2fill, t_calcnorm, t_applynorm = [
        0.0 for _ in range(7)
    ]

    vol = dest.grid.fsites
    n_colors = dest.otype.Nc
    tmp = gpt.mcolor(dest.grid)

    zero = gpt.complex(dest.grid)
    zero[:] = 0.0
    one = gpt.complex(dest.grid)
    one[:] = 1.0

    square = gpt.component.pow(2)
    norm = gpt.complex(dest.grid)

    for su2_index in range(n_colors * (n_colors - 1) // 2):

        index, i1, i2 = 0, None, None
        for ii in range(1, n_colors):
            for jj in range(n_colors - ii):
                if index == su2_index and i1 is None:
                    i1 = jj
                    i2 = ii + jj
                index += 1

        t_product -= gpt.time()
        tmp @= dest * unprojected
        t_product += gpt.time()

        t_separate -= gpt.time()
        tmp_sep = gpt.separate_color(tmp)
        t_separate += gpt.time()

        t_su2extract -= gpt.time()
        su2_components = extract_su2_components(tmp_sep, [i1, i2])
        t_su2extract += gpt.time()

        t_calcnorm -= gpt.time()
        norm @= gpt.component.inv(
            gpt.component.sqrt(
                gpt.eval(su2_components[0] * su2_components[0] +
                         su2_components[1] * su2_components[1] +
                         su2_components[2] * su2_components[2] +
                         su2_components[3] * su2_components[3])))
        t_calcnorm += gpt.time()

        t_applynorm -= gpt.time()
        su2_components[0] @= su2_components[0] * norm
        su2_components[1] @= -su2_components[1] * norm
        su2_components[2] @= -su2_components[2] * norm
        su2_components[3] @= -su2_components[3] * norm
        t_applynorm += gpt.time()

        t_su2fill -= gpt.time()
        fill_su2_components_into_suN(tmp_sep,
                                     su2_components, [i1, i2],
                                     cache=[zero, one])
        t_su2fill += gpt.time()

        t_merge -= gpt.time()
        gpt.merge_color(tmp, tmp_sep)
        t_merge += gpt.time()

        t_product -= gpt.time()
        dest @= tmp * dest
        t_product += gpt.time()

    t_total += gpt.time()

    if gpt.default.is_verbose("project_to_suN_step"):
        t_profiled = t_product + t_separate + t_merge + t_su2extract + t_su2fill + t_calcnorm + t_applynorm
        t_unprofiled = t_total - t_profiled

        gpt.message("project_to_suN_step: total", t_total, "s")
        gpt.message("project_to_suN_step: t_product", t_product, "s",
                    round(100 * t_product / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_separate", t_separate, "s",
                    round(100 * t_separate / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_merge", t_merge, "s",
                    round(100 * t_merge / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_su2extract", t_su2extract, "s",
                    round(100 * t_su2extract / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_su2fill", t_su2fill, "s",
                    round(100 * t_su2fill / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_calcnorm", t_calcnorm, "s",
                    round(100 * t_calcnorm / t_total, 1), "%")
        gpt.message("project_to_suN_step: t_applynorm", t_applynorm, "s",
                    round(100 * t_applynorm / t_total, 1), "%")
        gpt.message("project_to_suN_step: unprofiled", t_unprofiled, "s",
                    round(100 * t_unprofiled / t_total, 1), "%")
Exemple #7
0
        assert eps < 1e-13

for c1 in range(3):
    for c2 in range(3):
        eps = np.linalg.norm(
            msc[0, 0, 0, 0].array[:, :, c1, c2] - xc[c1, c2][0, 0, 0, 0].array
        )
        assert eps < 1e-13


msc2 = g.lattice(msc)

g.merge_spin(msc2, xs)
assert g.norm2(msc2 - msc) < 1e-13

g.merge_color(msc2, xc)
assert g.norm2(msc2 - msc) < 1e-13

assert (
    g.norm2(g.separate_color(xs[1, 2])[2, 0] - g.separate_spin(xc[2, 0])[1, 2]) < 1e-13
)


################################################################################
# Setup lattices
################################################################################
l_rb = [field(grid_rb) for i in range(Nlat)]
l = [field(grid) for i in range(Nlat)]
for i in range(Nlat):
    l_rb[i].checkerboard(g.odd)
rng.cnormal(l_rb)
Exemple #8
0
    t0 = g.time()
    for n in range(N):
        plan(lhs, rhs)
    t1 = g.time()
    g.message("%-50s %g GB/s %g s" % ("copy_plan:", GB / (t1 - t0),
                                      (t1 - t0) / N))

# spin/color separate/merge
msc = g.mspincolor(grid)
rng.cnormal(msc)

# 2 * N for read/write
GB = 2 * N * msc.otype.nfloats * grid.precision.nbytes * grid.fsites / 1e9

xc = g.separate_color(msc)
g.merge_color(msc, xc)
t0 = g.time()
for n in range(N):
    xc = g.separate_color(msc)
t1 = g.time()
for n in range(N):
    g.merge_color(msc, xc)
t2 = g.time()
g.message("%-50s %g GB/s %g s" % ("separate_color:", GB / (t1 - t0),
                                  (t1 - t0) / N))
g.message("%-50s %g GB/s %g s" % ("merge_color:", GB / (t2 - t1),
                                  (t2 - t1) / N))

xs = g.separate_spin(msc)
g.merge_spin(msc, xs)
t0 = g.time()
Exemple #9
0
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
Exemple #10
0
def reunitize(gauge):
    #     'project' site-local matrix to SU(N).
    #        * roughly equivalent to Grids 'ProjectOnGroup'
    #        * uses the "modified Gram-Schmidt process"
    #        * intended to remove numerical rounding errors during HMC
    #        * can be unstable for very large N or input far away from SU(N) (not an issue for intended usecase)
    if type(gauge) == list:
        for u in gauge:
            reunitize(u)
        return

    t_total, t_sep, t_merge, t_c, t_norm, t_det = 0, 0, 0, 0, 0, 0

    t_total -= gpt.time()

    assert type(gauge) == gpt.lattice
    shape = gauge.otype.shape
    assert len(shape) == 2 and shape[0] == shape[1]
    n_color = shape[0]

    t_sep -= gpt.time()
    tmp = gpt.separate_color(gauge)
    t_sep += gpt.time()

    c = gpt.complex(tmp[0, 0].grid)
    norm = gpt.complex(tmp[0, 0].grid)

    # step 1: (modified) Gram-Schmidt process to get a unitary matrix
    for i in range(n_color):
        for j in range(i):
            t_c -= gpt.time()
            c @= gpt.conj(tmp[j, 0]) * tmp[i, 0]
            for k in range(1, n_color):
                c += gpt.conj(tmp[j, k]) * tmp[i, k]

            for k in range(n_color):
                tmp[i, k] -= c * tmp[j, k]
            t_c += gpt.time()

        t_norm -= gpt.time()
        norm @= gpt.component.pow(2) * gpt.component.abs(tmp[i, 0])
        for k in range(1, n_color):
            norm += gpt.component.pow(2) * gpt.component.abs(tmp[i, k])
        norm @= gpt.component.inv(gpt.component.sqrt(norm))

        for k in range(n_color):
            tmp[i, k] *= norm
        t_norm += gpt.time()

    t_merge -= gpt.time()
    gpt.merge_color(gauge, tmp)
    t_merge += gpt.time()

    # step 2: fix the determinant (NOTE: Grids 'ProjectOnGroup' skips this step)
    t_det -= gpt.time()
    gauge *= gpt.component.pow(-1. / n_color) * gpt.matrix.det(gauge)
    t_det += gpt.time()

    t_total += gpt.time()

    if gpt.default.is_verbose("reunitize"):
        t_unprofiled = t_total - t_sep - t_merge - t_norm - t_c - t_det
        gpt.message("reunitize: total", t_total, "s")
        gpt.message("reunitize: t_separate", t_sep, "s",
                    round(100 * t_sep / t_total, 1), "%")
        gpt.message("reunitize: t_merge", t_merge, "s",
                    round(100 * t_merge / t_total, 1), "%")
        gpt.message("reunitize: t_c", t_c, "s", round(100 * t_c / t_total, 1),
                    "%")
        gpt.message("reunitize: t_norm", t_norm, "s",
                    round(100 * t_norm / t_total, 1), "%")
        gpt.message("reunitize: t_det", t_det, "s",
                    round(100 * t_det / t_total, 1), "%")
        gpt.message("reunitize: unprofiled", t_unprofiled, "s",
                    round(100 * t_unprofiled / t_total, 1), "%")