def choose_params(params: Parameters) -> BlockedParameters: print("dxsp_blocked.choose_params") pattern = Matrix.load_pattern(params.mtx_filename) #TODO: Choose bk,bn better bm = 8 if params.bm is None else params.bm bn = 8 if params.bn is None else params.bn bk = 8 if params.bk is None else params.bk params.bm = bm params.bn = bn params.bk = bk # TODO: Currently does not support fringe Bk, Bn = params.k // bk, params.n // bn patterns = [] blocks = Matrix.full(Bk, Bn, -1) x = 0 for Bni in range(Bn): for Bki in range(Bk): block = pattern[(Bki * bk):((Bki + 1) * bk), (Bni * bn):((Bni + 1) * bn)] found = False for pi in range(len(patterns)): if patterns[pi] == block: blocks[Bki, Bni] = pi found = True if not found: blocks[Bki, Bni] = x x += 1 patterns.append(block) return BlockedParameters(params, blocks, patterns)
def choose_params(p: Parameters, dense: bool = True) -> LibxsmmParameters: if p.output_filename is None: p.output_filename = "libxsmm_gemms.h" if p.output_funcname is None: p.output_funcname = f"gemm_{p.m}x{p.n}x{p.k}" return LibxsmmParameters(p, dense)
def __init__(self, reldir: str, nnzs: int, bk: int): bm = 8 bn = 8 bk = bk m = 64 n = 64 k = 64 self.name = f"jump_penalty_{bk}_{nnzs}" self.reldir = reldir self.pattern = Matrix.rand_bool(nnzs, k, n, 1066) self.mtx_filename = reldir + self.name + ".mtx" self.basic_params = Parameters(algorithm="dxsp_general", mtx_filename=self.mtx_filename, output_funcname=self.name, m=m, n=n, k=k, lda=m, ldb=0, ldc=m, bm=bm, bn=bn, bk=bk)
def all_params(): basename = "poc" p = Parameters(algorithm="micro", mtx_filename="src/cpptests/star.mtx", m=8, n=15, k=9, lda=8, ldb=0, ldc=8) p1 = libxsmm_params(p) p1.mtx_format = "csc" p1.output_funcname = basename + "_libxsmm" p1.output_filename = EXP1_LIBXSMM_H p1.ldb = p.k p1.bk = 0 p1.bn = 0 p2 = micro_params(p) p2.mtx_format = "csc" p2.bk = 0 p2.bn = 0 p2.output_funcname = basename + "_micro_csc" return [p1, p2]
def choose_params(params: Parameters) -> TiledParameters: """ Augment the generic user-supplied parameters with optimal tiled-specific ones""" print("dxsp_tiled.choose_params") full_mtx = Matrix.load_pattern(params.mtx_filename) #TODO: Choose optimal bm,bn,bk given m,n,k,full_mtx bm = 8 if params.bm is None else params.bm bn = 8 if params.bn is None else params.bn bk = 8 if params.bk is None else params.bk params.bm = bm params.bn = bn params.bk = bk #TODO: Generate better funcname params.output_funcname = f"gemm_tiled_{params.m}x{params.n}x{params.k}" # Take tile pattern to be upper left-hand corner # TODO: Take logical union of all tiles pattern_mtx = full_mtx[:bk,:bn] return TiledParameters(params, pattern_mtx)
def main(args): # Decide whether to handle this request or delegate it if (args.sparsity == "sparse" and args.arch == "knl" and args.prefetch == "nopf" and args.precision == "DP"): try: params = Parameters(algorithm=ALGORITHM, **args.__dict__) sparsemmgen.main(params) except Exception as e: print(f"{e.__class__.__name__}: {e}") traceback.print_tb(e.__traceback__) delegate() else: delegate()
class UnrolledSizingExperiment: name = "exp_unrolled_sizing" reldir = "experiments/unrolled_sizing/generated/" text = "Unrolled sizing experiment" executable = name script = name + ".sh" mtx_filename = reldir + name + ".mtx" basic_params = Parameters(algorithm = "dxsp_general", mtx_filename = mtx_filename, m = 96, n = 96, k = 96, bm = 0, bn = 0, bk = 0, lda = 96, ldb = 0, ldc = 96) def make(self): libxsmm_file = self.reldir + "libxsmm_gemms.h" if (os.path.isfile(libxsmm_file)): os.remove(libxsmm_file) harness = HarnessBuilder() harness.imports += '#include "libxsmm_gemms.h"\n' for param in self.all_params(): harness.add_test(param) cpp_filename = self.reldir + self.name + ".cpp" harness.make(cpp_filename) def all_params(self): self.pattern = Matrix.rand_bool(500, 96, 96, 1066) self.pattern.store(self.mtx_filename) yield self.make_libxsmm_test() options = [1,2,3,4,6,8,12,16,24,32] for bm in [8, 16, 24, 32]: for bn in options: for bk in options: if (bn + bk) * (bm/8) <= 32: print(f"{bm}, {bn}, {bk}") yield self.make_unrolled_test(bm, bn, bk) def make_unrolled_test(self, bm, bn, bk): self.basic_params.bm = bm self.basic_params.bn = bn self.basic_params.bk = bk pp = unrolled_params(self.basic_params) pp.mtx_format = "bcsc" pp.output_funcname = f"unrolled_{bm}_{bn}_{bk}" pp.ldb = 0 return pp def make_jump_test(self, bm, bn, bk): self.basic_params.bm = bm self.basic_params.bn = bn self.basic_params.bk = bk pp = general_params(self.basic_params) pp.mtx_format = "bcsc" pp.output_funcname = f"general_{bm}_{bn}_{bk}" return pp def make_libxsmm_test(self): pp = libxsmm_params(self.basic_params) pp.mtx_format = "dense" pp.output_funcname = "libxsmm" pp.output_filename = self.reldir + "libxsmm_gemms.h" pp.ldb = pp.k return pp
class SeisSolStarExperiment: name = "exp_seissol_star" reldir = "experiments/seissol_star/generated/" text = "SeisSol star kernel experiment" executable = name script = name + ".sh" libxsmm_filename = reldir + "libxsmm_gemms.h" seissol_star.store(reldir + "seissol_star_9x15.mtx") seissol_star_tiny.store(reldir + "seissol_star_9x9.mtx") seissol_star_big.store(reldir + "seissol_star_9x27.mtx") seissol_star_huge.store(reldir + "seissol_star_27x27.mtx") scenarios = [ Parameters(algorithm="dxsp_unrolled", mtx_filename=reldir + "seissol_star_9x15.mtx", output_funcname=name + "_9x15", m=40, n=15, k=9, lda=40, ldb=0, ldc=40, bm=8, bn=15, bk=9), Parameters(algorithm="dxsp_unrolled", mtx_filename=reldir + "seissol_star_9x9.mtx", output_funcname=name + "_9x9", m=40, n=9, k=9, lda=40, ldb=0, ldc=40, bm=8, bn=9, bk=9), Parameters(algorithm="dxsp_unrolled", mtx_filename=reldir + "seissol_star_9x27.mtx", output_funcname=name + "_9x27", m=40, n=27, k=9, lda=40, ldb=0, ldc=40, bm=8, bn=9, bk=9), Parameters(algorithm="dxsp_unrolled", mtx_filename=reldir + "seissol_star_27x27.mtx", output_funcname=name + "_27x27", m=40, n=27, k=27, lda=40, ldb=0, ldc=40, bm=8, bn=9, bk=9) ] def make(self): if (os.path.isfile(self.libxsmm_filename)): os.remove(self.libxsmm_filename) param_space = [] for params in self.scenarios: param_space += [ self.make_libxsmm_test(params), self.make_breuer_test(params, "_breuer"), self.make_breuer_test(params, "_breuer2"), self.make_unrolled_test(params), self.make_jump_test(params) ] harness = HarnessBuilder() harness.imports += '#include "libxsmm_gemms.h"\n' for param in param_space: harness.add_test(param) cpp_filename = self.reldir + self.name + ".cpp" harness.make(cpp_filename) def make_libxsmm_test(self, params): p = libxsmm_params(params) p.mtx_format = "dense" p.output_funcname += "_libxsmm" p.output_filename = self.reldir + "libxsmm_gemms.h" p.ldb = p.k return p def make_breuer_test(self, params, suffix): p = libxsmm_params(params, False) p.mtx_format = "csc" p.output_funcname += suffix p.output_filename = self.reldir + "libxsmm_gemms.h" p.ldb = 0 return p def make_unrolled_test(self, params): pp = unrolled_params(params) pp.mtx_format = "bcsc" pp.output_funcname += "_unrolled" pp.ldb = 0 return pp def make_jump_test(self, params): pp = general_params(params) pp.mtx_format = "bcsc" pp.output_funcname += "_general" return pp
parser.add_argument("ldb", type=int, help="Leading dimension of B (zero if B is sparse)") parser.add_argument("ldc", type=int, help="Leading dimension of C") parser.add_argument("--bm", type=int, help="Size of m-blocks") parser.add_argument("--bn", type=int, help="Size of n-blocks") parser.add_argument("--bk", type=int, help="Size of k-blocks") parser.add_argument("mtx_filename", help="Path to MTX file describing the sparse matrix") parser.add_argument("--mtx_format", help="Constraint on sparsity pattern", choices=mtx_formats, default="Any") parser.add_argument("--output_format", help="Output format", choices=output_formats, default="cpp") parser.add_argument("--output_funcname", help="Name for generated C++ function") parser.add_argument("--output_filename", help="Path to destination C++ file") parser.add_argument("-v", "--verbose", action="store_true") args = parser.parse_args() params = Parameters(**args.__dict__) main(params)