Exemple #1
0
def nearest_neighbor_operator(fine_matrix, coarse_grid, basis, params):
    A = [gpt.mcomplex(coarse_grid, len(basis)) for i in range(9)]

    create_links(
        A, fine_matrix, basis, make_hermitian=params["make_hermitian"], save_links=True
    )

    level = (
        1 if isinstance(fine_matrix.otype, gpt.ot_matrix_complex_additive_group) else 0
    )
    return gpt.qcd.fermion.coarse_fermion(A, level=level)
Exemple #2
0
mask[0, 1, 2, 3] = 1
vc[:] = vc[0, 0, 0, 0]
vcmask = g.eval(mask * vc)
assert g.norm2(vcmask[0, 0, 0, 0]) < 1e-13
assert g.norm2(vcmask[0, 1, 2, 3] - vc_comp) < 1e-13

# demonstrate sign flip needed for MG
sign = g.vcomplex([1] * 15 + [-1] * 15, 30)
vc_comp = g.vcomplex([1] + [1.5] * 14 + [-1.5] * 14 + [-2], 30)
vc @= sign * vc
eps2 = g.norm2(vc[0, 0, 0, 0] - vc_comp)
assert eps2 < 1e-13

# demonstrate matrix * vector
ntest = 30
mc_comp = g.mcomplex([[rng.cnormal() for i in range(ntest)]
                      for j in range(ntest)], ntest)
mc = g.mcomplex(grid, ntest)
mc[:] = mc_comp
vc_comp = g.vcomplex([rng.cnormal() for i in range(ntest)], ntest)
vc = g.vcomplex(grid, ntest)
vc[:] = vc_comp
assert g.norm2(mc[0, 0, 0, 0] - mc_comp) < 1e-10

vc2 = g.eval(mc * vc)
vc2_comp = mc_comp * vc_comp
vc3 = g.eval(mc_comp * vc)
assert g.norm2(vc2[0, 0, 0, 0] - vc2_comp) < 1e-10
eps2 = g.norm2(vc2 - vc3) / g.norm2(vc2)
assert eps2 < 1e-10

# test transpose and adjoint of mcomplex
Exemple #3
0
    def __init__(self, mat_f, params):
        # save parameters
        self.params = params

        # fine grid from fine matrix
        if issubclass(type(mat_f), g.matrix_operator):
            self.grid = [mat_f.grid[1]]
        else:
            self.grid = [mat_f.grid]

        # grid sizes - allow specifying in two ways
        if "grid" in params:
            self.grid.extend(params["grid"])
        elif "blocksize" in params:
            for i, bs in enumerate(params["blocksize"]):
                assert type(bs) == list
                self.grid.append(g.block.grid(self.grid[i], bs))
        else:
            assert 0

        # dependent sizes
        self.nlevel = len(self.grid)
        self.ncoarselevel = self.nlevel - 1
        self.finest = 0
        self.coarsest = self.nlevel - 1

        # other parameters
        self.nblockortho = g.util.to_list(params["nblockortho"],
                                          self.nlevel - 1)
        self.check_blockortho = g.util.to_list(params["check_blockortho"],
                                               self.nlevel - 1)
        self.nbasis = g.util.to_list(params["nbasis"], self.nlevel - 1)
        self.make_hermitian = g.util.to_list(params["make_hermitian"],
                                             self.nlevel - 1)
        self.save_links = g.util.to_list(params["save_links"], self.nlevel - 1)
        self.npreortho = g.util.to_list(params["npreortho"], self.nlevel - 1)
        self.npostortho = g.util.to_list(params["npostortho"], self.nlevel - 1)
        self.vector_type = g.util.to_list(params["vector_type"],
                                          self.nlevel - 1)
        self.distribution = g.util.to_list(params["distribution"],
                                           self.nlevel - 1)
        self.solver = g.util.to_list(params["solver"], self.nlevel - 1)

        # verbosity
        self.verbose = g.default.is_verbose("multi_grid_setup")

        # print prefix
        self.print_prefix = [
            "mg_setup: level %d:" % i for i in range(self.nlevel)
        ]

        # easy access to current level and neighbors
        self.lvl = [i for i in range(self.nlevel)]
        self.nf_lvl = [i - 1 for i in range(self.nlevel)]
        self.nc_lvl = [i + 1 for i in range(self.nlevel)]
        self.nf_lvl[self.finest] = None
        self.nc_lvl[self.coarsest] = None

        # halved nbasis
        self.nb = []
        for lvl, b in enumerate(self.nbasis):
            assert b % 2 == 0
            self.nb.append(b // 2)

        # assertions
        assert self.nlevel >= 2
        assert g.util.entries_have_length(
            [
                self.nblockortho,
                self.nbasis,
                self.make_hermitian,
                self.save_links,
                self.npreortho,
                self.npostortho,
                self.vector_type,
                self.distribution,
                self.solver,
                self.nb,
            ],
            self.nlevel - 1,
        )

        # timing
        self.t = [
            g.timer("mg_setup_lvl_%d" % (lvl)) for lvl in range(self.nlevel)
        ]

        # matrices (coarse ones initialized later)
        self.mat = [mat_f] + [None] * (self.nlevel - 1)

        # setup random basis vectors on all levels but coarsest
        self.basis = [None] * self.nlevel
        for lvl, grid in enumerate(self.grid):
            if lvl == self.coarsest:
                continue
            elif lvl == self.finest:
                self.basis[lvl] = [
                    g.vspincolor(grid) for __ in range(self.nbasis[lvl])
                ]
            else:
                self.basis[lvl] = [
                    g.vcomplex(grid, self.nbasis[self.nf_lvl[lvl]])
                    for __ in range(self.nbasis[lvl])
                ]
            self.distribution[lvl](self.basis[lvl][0:self.nb[lvl]])

        # setup a block map on all levels but coarsest
        self.blockmap = [None] * self.nlevel
        for lvl in self.lvl:
            if lvl == self.coarsest:
                continue
            else:
                self.blockmap[lvl] = g.block.map(self.grid[self.nc_lvl[lvl]],
                                                 self.basis[lvl])

        # setup coarse link fields on all levels but finest
        self.A = [None] * self.nlevel
        for lvl in range(self.finest + 1, self.nlevel):
            self.A[lvl] = [
                g.mcomplex(self.grid[lvl], self.nbasis[self.nf_lvl[lvl]])
                for __ in range(9)
            ]

        # setup a solver history
        self.history = [[None]] * (self.nlevel - 1)

        # rest of setup
        self.__call__()
Exemple #4
0
################################################################################
# Test all other representations
################################################################################
for eps_ref, grid in [(1e-6, grid_sp), (1e-12, grid_dp)]:
    for representation in [
        g.matrix_su2_fundamental,
        g.matrix_su2_adjoint,
        g.matrix_su3_fundamental,
        g.u1,
        g.complex,
        g.real,
        lambda grid: g.vreal(grid, 8),
        lambda grid: g.mreal(grid, 8),
        lambda grid: g.vcomplex(grid, 8),
        lambda grid: g.mcomplex(grid, 8),
    ]:
        U = representation(grid)
        g.message(f"Test {U.otype.__name__} on grid {grid.precision.__name__}")
        rng.element(U)
        check_element(U)
        check_representation(U, eps_ref)
        for method in ["defect_left", "defect_right"]:
            g.project(U, method)
            check_element(U)
        V = representation(grid)
        rng.element(V)
        check_inner_product(U, V, eps_ref)


################################################################################
Exemple #5
0
basis_f = [g.vspincolor(grid_f) for __ in range(nbasis_f // 2)]
rng.cnormal(basis_f)

# split fine basis into chiral halfs
g.qcd.fermion.coarse.split_chiral(basis_f)

# setup fine block map
bm_f = g.block.map(grid_c, basis_f)

# orthonormalize fine basis
for i in range(nblockortho):
    g.message("Block ortho step %d" % i)
    bm_f.orthonormalize()

# create coarse link fields
A_c = [g.mcomplex(grid_c, nbasis_f) for __ in range(9)]
g.qcd.fermion.coarse.create_links(A_c, mat_f, basis_f, {
    "make_hermitian": False,
    "save_links": True
})

# create coarse operator from links
mat_c = g.qcd.fermion.coarse_fermion(A_c, level=0)


# save typing
def vec_c_full():
    return g.vcomplex(mat_c.F_grid, nbasis_f)


def vec_c_half():
Exemple #6
0
        b = op[1](m[0, 0, 0, 0, 1, 2])
        eps2 = (abs(a - b) / abs(a))**2.0
        g.message(
            f"Test {op[1].__name__}: {a} == {b} with argument {m[0, 0, 0, 0, 1, 2]}: {eps2}"
        )
        assert eps2 < eps**2.0

# test inv
for grid, eps in [(grid_dp, 1e-14), (grid_sp, 1e-6)]:
    g.message(f"""

    Test log,exp,det,tr for {grid.precision.__name__}

""")
    for dtype in [
            g.mspincolor, g.mcolor, g.mspin, lambda grid: g.mcomplex(grid, 8)
    ]:
        rng = g.random("test")
        m = rng.cnormal(dtype(grid))
        minv = g.matrix.inv(m)
        eye = g.identity(m)
        eps2 = g.norm2(m * minv - eye) / (12 * grid.fsites)
        g.message(f"test M*M^-1 = 1 for {m.otype.__name__}: {eps2}")
        assert eps2 < eps**2

        # make logarithm well defined
        m @= eye + 0.01 * m
        m2 = g.matrix.exp(g.matrix.log(m))
        eps2 = g.norm2(m - m2) / g.norm2(m)
        g.message(f"exp(log(m)) == m: {eps2}")
        assert eps2 < eps**2.0
Exemple #7
0
basis_f = [g.vspincolor(grid_f) for __ in range(nbasis_f // 2)]
rng.cnormal(basis_f)

# split fine basis into chiral halfs
g.qcd.fermion.coarse.split_chiral(basis_f)

# setup fine block map
bm_f = g.block.map(grid_c, basis_f)

# orthonormalize fine basis
for i in range(nblockortho):
    g.message("Block ortho step %d" % i)
    bm_f.orthonormalize()

# create coarse link fields
A_c = [g.mcomplex(grid_c, nbasis_f) for __ in range(9)]
Asaved_c = [g.mcomplex(grid_c, nbasis_f) for __ in range(9)]
g.qcd.fermion.coarse.create_links(
    A_c, mat_f, basis_f, {"make_hermitian": False, "save_links": False}
)
g.qcd.fermion.coarse.create_links(
    Asaved_c, mat_f, basis_f, {"make_hermitian": False, "save_links": True}
)

# compare link fields
for p in range(9):
    err2 = g.norm2(A_c[p] - Asaved_c[p]) / g.norm2(A_c[p])
    g.message(
        f"Relative deviation of Asaved_c[{p}] from A_c[{p}] = {err2:e}",
    )
    assert err2 <= tol_links
Exemple #8
0
N = g.default.get_int("--N", 1000)
nbasis = g.default.get_int("--nbasis", 40)
level = g.default.get_int("--level", 0)

for precision in [g.single, g.double]:
    grid = g.grid(g.default.get_ivec("--grid", [6, 6, 6, 6], 4), precision)
    g.message(f"""
Coarse Operator Benchmark with
    fdimensions  : {grid.fdimensions}
    precision    : {precision.__name__}
    nbasis       : {nbasis}
    level        : {level}
""")

    # Coarse operator
    A = [g.mcomplex(grid, nbasis) for __ in range(9)]
    rng.cnormal(A)
    co = g.qcd.fermion.coarse(A, {"level": level})

    # Source and destination
    src = g.vcomplex(grid, nbasis)
    dst = g.vcomplex(grid, nbasis)
    rng.cnormal(src)

    # Flops
    flops_per_site = 2 * nbasis * (36 * nbasis - 1)
    flops = flops_per_site * src.grid.gsites * N
    nbytes = ((9 * 2 * nbasis + 9 * 2 * nbasis * nbasis + 2 * nbasis) *
              precision.nbytes * src.grid.gsites * N)

    # Warmup