Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reduction support in yaksa #1

Open
wants to merge 5 commits into
base: pr/accumulate
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 66 additions & 7 deletions src/backend/gencomm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
## loop through the derived and basic types to generate individual
## pack functions
derived_types = [ "hvector", "blkhindx", "hindexed", "contig", "resized" ]
type_map = { }
type_ops = [["pack", "acc_unpack"], ["pack", "acc_unpack"], ["pack", "acc_unpack"], ["pack", "acc_unpack", "sum"], ["pack", "acc_unpack", "sum"], \
["pack", "acc_unpack", "sum"], ["pack", "acc_unpack", "sum"], ["pack", "acc_unpack", "sum"], ["pack", "acc_unpack", "sum"], ["pack", "acc_unpack", "sum"]]


########################################################################################
Expand All @@ -24,6 +27,11 @@ def child_type_str(typelist):

def switcher_builtin_element(backend, OUTFILE, blklens, typelist, pupstr, key, val):
yutils.display(OUTFILE, "case %s:\n" % key.upper())
d = val
if (key == "YAKSA_TYPE__long_double"):
d = "long double";
n = int
n = type_map.get(d, "-1")

if (len(typelist) == 0):
t = ""
Expand All @@ -43,16 +51,28 @@ def switcher_builtin_element(backend, OUTFILE, blklens, typelist, pupstr, key, v
else:
yutils.display(OUTFILE, "default:\n")
yutils.display(OUTFILE, "if (max_nesting_level >= %d) {\n" % nesting_level)
yutils.display(OUTFILE, "%s->pack = yaksuri_%si_%s_blklen_%s_%s;\n" % (backend, backend, pupstr, blklen, val))
yutils.display(OUTFILE, "%s->acc_unpack = yaksuri_%si_acc_un%s_blklen_%s_%s;\n" % (backend, backend, pupstr, blklen, val))
for p in type_ops[n]:
if (backend != "seq" and p != "pack" and p!="acc_unpack"):
continue
yutils.display(OUTFILE, "%s->%s = yaksuri_%si_%s%s_blklen_%s_%s;\n" % (backend, p, backend, p, pupstr, blklen, val))
#yutils.display(OUTFILE, "%s->acc_unpack = yaksuri_%si_acc_un%s_blklen_%s_%s;\n" % (backend, backend, pupstr, blklen, val))
yutils.display(OUTFILE, "}\n")
yutils.display(OUTFILE, "break;\n")
yutils.display(OUTFILE, "}\n")
else:
elif (t != ""):
yutils.display(OUTFILE, "if (max_nesting_level >= %d) {\n" % nesting_level)
yutils.display(OUTFILE, "%s->pack = yaksuri_%si_%s_%s;\n" % (backend, backend, pupstr, val))
yutils.display(OUTFILE, "%s->acc_unpack = yaksuri_%si_acc_un%s_%s;\n" % (backend, backend, pupstr, val))
for p in type_ops[n]:
if (backend != "seq" and p != "pack" and p!="acc_unpack"):
continue
yutils.display(OUTFILE, "%s->%s = yaksuri_%si_%s%s_%s;\n" % (backend, p, backend, p, pupstr, val))
#yutils.display(OUTFILE, "%s->acc_unpack = yaksuri_%si_acc_un%s_%s;\n" % (backend, backend, pupstr, val))
yutils.display(OUTFILE, "}\n")
else:
for p in type_ops[n]:
if (p == "pack" or p == "acc_unpack"):
continue
yutils.display(OUTFILE, "%s->%s = yaksuri_%si_%s_%s;\n" % (backend, p, backend, p, val))
#yutils.display(OUTFILE, "}\n")

if (t != ""):
typelist.append(t)
Expand Down Expand Up @@ -97,6 +117,11 @@ def switcher(backend, OUTFILE, blklens, builtin_types, builtin_maps, typelist, p
########################################################################################
def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_maps):
##### generate the switching logic to select pup functions
n = 0
for b in builtin_types:
type_map[b] = n
n = n + 1

filename = "src/backend/%s/pup/yaksuri_%si_populate_pupfns.c" % (backend, backend)
yutils.copyright_c(filename)
OUTFILE = open(filename, "a")
Expand Down Expand Up @@ -133,6 +158,10 @@ def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_ma
yutils.display(OUTFILE, "}\n")
yutils.display(OUTFILE, "break;\n")
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "case YAKSI_TYPE_KIND__BUILTIN:\n")
yutils.display(OUTFILE, "rc = yaksuri_%si_populate_pupfns_builtin(type);\n" % backend)
yutils.display(OUTFILE, "break;\n")
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "default:\n")
yutils.display(OUTFILE, " break;\n")
yutils.display(OUTFILE, "}\n")
Expand Down Expand Up @@ -170,7 +199,8 @@ def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_ma
yutils.display(OUTFILE, "}\n")
yutils.display(OUTFILE, "\n")

pupstr = "pack_%s_%s" % (dtype1, dtype2)
pupstr = "_%s_%s" % (dtype1, dtype2)

typelist = [ dtype1, dtype2 ]
switcher(backend, OUTFILE, blklens, builtin_types, builtin_maps, typelist, pupstr, pup_max_nesting - 1)
yutils.display(OUTFILE, "\n")
Expand Down Expand Up @@ -205,14 +235,41 @@ def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_ma
yutils.display(OUTFILE, "}\n")
yutils.display(OUTFILE, "\n")

pupstr = "pack_%s" % dtype1
pupstr = "_%s" % dtype1
typelist = [ dtype1 ]
switcher_builtin(backend, OUTFILE, blklens, builtin_types, builtin_maps, typelist, pupstr)
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "return rc;\n")
yutils.display(OUTFILE, "}\n")
OUTFILE.close()

filename = "src/backend/%s/pup/yaksuri_%si_populate_pupfns_builtin.c" % (backend, backend)
yutils.copyright_c(filename)
OUTFILE = open(filename, "a")
yutils.display(OUTFILE, "#include <stdio.h>\n")
yutils.display(OUTFILE, "#include <stdlib.h>\n")
yutils.display(OUTFILE, "#include <wchar.h>\n")
yutils.display(OUTFILE, "#include \"yaksi.h\"\n")
yutils.display(OUTFILE, "#include \"yaksu.h\"\n")
yutils.display(OUTFILE, "#include \"yaksuri_%si.h\"\n" % backend)
yutils.display(OUTFILE, "#include \"yaksuri_%si_populate_pupfns.h\"\n" % backend)
yutils.display(OUTFILE, "#include \"yaksuri_%si_pup.h\"\n" % backend)
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "int yaksuri_%si_populate_pupfns_builtin(yaksi_type_s * type)\n" % backend)
yutils.display(OUTFILE, "{\n")
yutils.display(OUTFILE, "int rc = YAKSA_SUCCESS;\n")
yutils.display(OUTFILE, "yaksuri_%si_type_s *%s = (yaksuri_%si_type_s *) type->backend.%s.priv;\n" \
% (backend, backend, backend, backend))
yutils.display(OUTFILE, "\n")

pupstr = ""
typelist = [ ]
switcher_builtin(backend, OUTFILE, blklens, builtin_types, builtin_maps, typelist, pupstr)
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "return rc;\n")
yutils.display(OUTFILE, "}\n")
OUTFILE.close()

##### generate the Makefile for the pup function selection functions
filename = "src/backend/%s/pup/Makefile.populate_pupfns.mk" % backend
yutils.copyright_makefile(filename)
Expand All @@ -222,6 +279,7 @@ def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_ma
for dtype2 in derived_types:
yutils.display(OUTFILE, "\tsrc/backend/%s/pup/yaksuri_%si_populate_pupfns_%s_%s.c \\\n" % (backend, backend, dtype1, dtype2))
yutils.display(OUTFILE, "\tsrc/backend/%s/pup/yaksuri_%si_populate_pupfns_%s_builtin.c \\\n" % (backend, backend, dtype1))
yutils.display(OUTFILE, "\tsrc/backend/%s/pup/yaksuri_%si_populate_pupfns_builtin.c \\\n" % (backend, backend))
yutils.display(OUTFILE, "\tsrc/backend/%s/pup/yaksuri_%si_populate_pupfns.c\n" % (backend, backend))
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "noinst_HEADERS += \\\n")
Expand All @@ -239,6 +297,7 @@ def populate_pupfns(pup_max_nesting, backend, blklens, builtin_types, builtin_ma
for dtype2 in derived_types:
yutils.display(OUTFILE, "int yaksuri_%si_populate_pupfns_%s_%s(yaksi_type_s * type);\n" % (backend, dtype1, dtype2))
yutils.display(OUTFILE, "int yaksuri_%si_populate_pupfns_%s_builtin(yaksi_type_s * type);\n" % (backend, dtype1))
yutils.display(OUTFILE, "int yaksuri_%si_populate_pupfns_builtin(yaksi_type_s * type);\n" % backend)
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "#endif /* YAKSURI_%sI_POPULATE_PUPFNS_H_INCLUDED */\n" % backend.upper())
OUTFILE.close()
111 changes: 86 additions & 25 deletions src/backend/seq/genpup.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,48 @@ def resized(suffix, b, blklen, last):
########################################################################################
##### Core kernels
########################################################################################
def generate_kernels(b, darray, blklen):
def generate_kernels(b, darray, blklen, op):
global num_paren_open
global s

# we don't need pup kernels for basic types
if (len(darray) == 0):
if (op == "pack" or op == "acc_unpack"):
return
s = "int yaksuri_seqi_%s_" % op + b.replace(" ", "_")
yutils.display(OUTFILE, "%s(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type)\n" % s),
yutils.display(OUTFILE, "{\n")

##### variable declarations
# generic variables
yutils.display(OUTFILE, "int rc = YAKSA_SUCCESS;\n");
yutils.display(OUTFILE, "const %s *restrict sbuf = (const %s *) inbuf;\n" % (b, b));
yutils.display(OUTFILE, "%s *restrict dbuf = (%s *) outbuf;\n" % (b, b));
yutils.display(OUTFILE, "\n");

yutils.display(OUTFILE, "for (int i = 0; i < count; i++) {\n")
num_paren_open += 1
if (op == "sum"):
yutils.display(OUTFILE, "dbuf[i] += sbuf[i];\n")

for x in range(num_paren_open):
yutils.display(OUTFILE, "}\n")
num_paren_open = 0
yutils.display(OUTFILE, "\n");
yutils.display(OUTFILE, "return rc;\n")
yutils.display(OUTFILE, "}\n\n")

return

# individual blocklength optimization is only for
# hvector and blkhindx
if (darray[-1] != "hvector" and darray[-1] != "blkhindx" and blklen != "generic"):
return

for func in "pack","acc_unpack":
funclist = [ ]
funclist.append(op)

for func in funclist:
##### figure out the function name to use
s = "int yaksuri_seqi_%s_" % func
for d in darray:
Expand Down Expand Up @@ -172,8 +200,11 @@ def generate_kernels(b, darray, blklen):

if (func == "pack"):
yutils.display(OUTFILE, "dbuf[idx++] = sbuf[%s];\n" % s)
else:
elif (func == "acc_unpack"):
yutils.display(OUTFILE, "dbuf[%s] = sbuf[idx++];\n" % s)
else:
yutils.display(OUTFILE, "dbuf[%s] += sbuf[idx++];\n" % s)

for x in range(num_paren_open):
yutils.display(OUTFILE, "}\n")
num_paren_open = 0
Expand All @@ -196,6 +227,27 @@ def generate_kernels(b, darray, blklen):
print("===> ERROR: pup-max-nesting must be positive")
sys.exit(1)

n = 0;
for b in builtin_types:
gencomm.type_map[b] = n;
n = n + 1;

##### generate the reduction kernels for built-in types
for b in builtin_types:
filename = "src/backend/seq/pup/yaksuri_seqi_pup_%s.c" % (b.replace(" ","_"))
yutils.copyright_c(filename)
OUTFILE = open(filename, "a")
yutils.display(OUTFILE, "#include <string.h>\n")
yutils.display(OUTFILE, "#include <stdint.h>\n")
yutils.display(OUTFILE, "#include <wchar.h>\n")
yutils.display(OUTFILE, "#include \"yaksuri_seqi_pup.h\"\n")
yutils.display(OUTFILE, "\n")
for p in gencomm.type_ops[gencomm.type_map.get(b)]:
emptylist = [ ]
generate_kernels(b, emptylist, 0, p)

OUTFILE.close()

##### generate the core pack/acc_unpack kernels (single level)
for b in builtin_types:
for d in gencomm.derived_types:
Expand All @@ -207,13 +259,12 @@ def generate_kernels(b, darray, blklen):
yutils.display(OUTFILE, "#include <wchar.h>\n")
yutils.display(OUTFILE, "#include \"yaksuri_seqi_pup.h\"\n")
yutils.display(OUTFILE, "\n")

emptylist = [ ]
emptylist.append(d)
for blklen in blklens:
generate_kernels(b, emptylist, blklen)
emptylist.pop()

for p in gencomm.type_ops[gencomm.type_map.get(b)]:
emptylist = [ ]
emptylist.append(d)
for blklen in blklens:
generate_kernels(b, emptylist, blklen, p)
emptylist.pop()
OUTFILE.close()

##### generate the core pack/acc_unpack kernels (more than one level)
Expand All @@ -230,18 +281,17 @@ def generate_kernels(b, darray, blklen):
yutils.display(OUTFILE, "#include <wchar.h>\n")
yutils.display(OUTFILE, "#include \"yaksuri_seqi_pup.h\"\n")
yutils.display(OUTFILE, "\n")

for darray in darraylist:
darray.append(d1)
darray.append(d2)
for blklen in blklens:
generate_kernels(b, darray, blklen)
darray.pop()
darray.pop()

for p in gencomm.type_ops[gencomm.type_map.get(b)]:
for darray in darraylist:
darray.append(d1)
darray.append(d2)
for blklen in blklens:
generate_kernels(b, darray, blklen, p)
darray.pop()
darray.pop()
OUTFILE.close()

##### generate the core pack/acc_unpack kernel declarations
##### generate the core pack/acc_unpack and reduction kernel declarations
filename = "src/backend/seq/pup/yaksuri_seqi_pup.h"
yutils.copyright_c(filename)
OUTFILE = open(filename, "a")
Expand All @@ -253,6 +303,14 @@ def generate_kernels(b, darray, blklen):
yutils.display(OUTFILE, "#include \"yaksi.h\"\n")
yutils.display(OUTFILE, "\n")

for b in builtin_types:
for p in gencomm.type_ops[gencomm.type_map.get(b)]:
if (p == "pack" or p == "acc_unpack"):
continue
s = "int yaksuri_seqi_%s_" % p + b.replace(" ", "_")
yutils.display(OUTFILE, "%s" % s),
yutils.display(OUTFILE, "(const void *inbuf, void *outbuf, uintptr_t count, yaksi_type_s * type);\n")

darraylist = [ ]
yutils.generate_darrays(gencomm.derived_types, darraylist, args.pup_max_nesting)
for b in builtin_types:
Expand All @@ -268,9 +326,8 @@ def generate_kernels(b, darray, blklen):
and blklen != "generic"):
continue

for func in "pack","acc_unpack":
##### figure out the function name to use
s = "int yaksuri_seqi_%s_" % func
for p in gencomm.type_ops[gencomm.type_map.get(b)]:
s = "int yaksuri_seqi_%s_" % p
for d in darray:
s = s + "%s_" % d
# hvector and hindexed get blklen-specific function names
Expand All @@ -290,12 +347,16 @@ def generate_kernels(b, darray, blklen):
OUTFILE = open(filename, "a")
yutils.display(OUTFILE, "libyaksa_la_SOURCES += \\\n")
for b in builtin_types:
#reduction kernels for built-in types
yutils.display(OUTFILE, "\tsrc/backend/seq/pup/yaksuri_seqi_pup_%s.c \\\n" % \
(b.replace(" ","_")))
for d1 in gencomm.derived_types:
#for p in type_ops[type_map.get(b)]:
yutils.display(OUTFILE, "\tsrc/backend/seq/pup/yaksuri_seqi_pup_%s_%s.c \\\n" % \
(d1, b.replace(" ","_")))
(d1, b.replace(" ","_")))
for d2 in gencomm.derived_types:
yutils.display(OUTFILE, "\tsrc/backend/seq/pup/yaksuri_seqi_pup_%s_%s_%s.c \\\n" % \
(d1, d2, b.replace(" ","_")))
(d1, d2, b.replace(" ","_")))
yutils.display(OUTFILE, "\tsrc/backend/seq/pup/yaksuri_seq_pup.c\n")
yutils.display(OUTFILE, "\n")
yutils.display(OUTFILE, "noinst_HEADERS += \\\n")
Expand Down
2 changes: 1 addition & 1 deletion src/backend/seq/include/yaksuri_seq_post.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ int yaksuri_seq_pup_is_supported(yaksi_type_s * type, bool * is_supported);
int yaksuri_seq_ipack(const void *inbuf, void *outbuf, uintptr_t count, yaksi_info_s * info,
yaksi_type_s * type);
int yaksuri_seq_iacc_unpack(const void *inbuf, void *outbuf, uintptr_t count, yaksi_info_s * info,
yaksi_type_s * type);
yaksi_type_s * type, yaksa_op_t op);

#endif /* YAKSURI_SEQ_H_INCLUDED */
1 change: 1 addition & 0 deletions src/backend/seq/include/yaksuri_seqi.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
typedef struct yaksuri_seqi_type_s {
int (*pack) (const void *inbuf, void *outbuf, uintptr_t count, struct yaksi_type_s *);
int (*acc_unpack) (const void *inbuf, void *outbuf, uintptr_t count, struct yaksi_type_s *);
int (*sum) (const void *inbuf, void *outbuf, uintptr_t count, struct yaksi_type_s *);
} yaksuri_seqi_type_s;

#define YAKSURI_SEQI_INFO__DEFAULT_IOV_PUP_THRESHOLD (16384)
Expand Down
Loading