From 3c9769211856d5b89c1bd66f9e6999ba3834441b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6nig?= <jan.hoenig@fau.de> Date: Thu, 11 Nov 2021 18:03:31 +0100 Subject: [PATCH] All todos done so far --- pystencils_benchmark/__init__.py | 1 + pystencils_benchmark/benchmark.py | 139 +++++++++++------- pystencils_benchmark/enums.py | 8 + pystencils_benchmark/templates/Clang.mk | 19 +++ .../templates/{include_GCC.mk => GCC.mk} | 0 .../{include_GCCdebug.mk => GCCdebug.mk} | 4 +- .../templates/{include_ICC.mk => ICC.mk} | 0 pystencils_benchmark/templates/Makefile | 21 +-- .../templates/include_Clang.mk | 24 --- pystencils_benchmark/templates/main.c | 92 ++++++------ requirements.txt | 3 +- test.ipynb | 130 ---------------- test.py | 45 ++++++ 13 files changed, 215 insertions(+), 271 deletions(-) create mode 100644 pystencils_benchmark/enums.py create mode 100644 pystencils_benchmark/templates/Clang.mk rename pystencils_benchmark/templates/{include_GCC.mk => GCC.mk} (100%) rename pystencils_benchmark/templates/{include_GCCdebug.mk => GCCdebug.mk} (69%) rename pystencils_benchmark/templates/{include_ICC.mk => ICC.mk} (100%) delete mode 100644 pystencils_benchmark/templates/include_Clang.mk delete mode 100644 test.ipynb create mode 100755 test.py diff --git a/pystencils_benchmark/__init__.py b/pystencils_benchmark/__init__.py index 611cedd..6f5f32c 100644 --- a/pystencils_benchmark/__init__.py +++ b/pystencils_benchmark/__init__.py @@ -1 +1,2 @@ +from .enums import Compiler from .benchmark import generate_benchmark, kernel_header, kernel_source diff --git a/pystencils_benchmark/benchmark.py b/pystencils_benchmark/benchmark.py index 1b4dcae..25c9044 100644 --- a/pystencils_benchmark/benchmark.py +++ b/pystencils_benchmark/benchmark.py @@ -1,6 +1,10 @@ +from typing import Union, List +from collections import namedtuple from pathlib import Path from jinja2 import Environment, PackageLoader, StrictUndefined +import numpy as np + from pystencils.backends.cbackend import generate_c, get_headers from pystencils.astnodes import KernelFunction, PragmaBlock from pystencils.enums import Backend @@ -8,13 +12,13 @@ from pystencils.data_types import get_base_type from pystencils.sympyextensions import prod from pystencils.integer_functions import modulo_ceil -import numpy as np +from pystencils_benchmark.enums import Compiler -def generate_benchmark(kernel_ast: KernelFunction, +def generate_benchmark(kernel_asts: Union[KernelFunction, List[KernelFunction]], path: Path = None, *, - dialect: Backend = Backend.C) -> None: + compiler: Compiler = Compiler.GCC) -> None: if path is None: path = Path('.') else: @@ -24,20 +28,39 @@ def generate_benchmark(kernel_ast: KernelFunction, include_path = path / 'include' include_path.mkdir(parents=True, exist_ok=True) - kernel_name = kernel_ast.function_name + if isinstance(kernel_asts, KernelFunction): + kernel_asts = [kernel_asts] + + for kernel_ast in kernel_asts: + kernel_name = kernel_ast.function_name - header = kernel_header(kernel_ast, dialect) - with open(include_path / f'{kernel_name}.h', 'w+') as f: - f.write(header) + header = kernel_header(kernel_ast) + with open(include_path / f'{kernel_name}.h', 'w+') as f: + f.write(header) - source = kernel_source(kernel_ast, dialect) - with open(src_path / f'{kernel_name}.c', 'w+') as f: - f.write(source) + source = kernel_source(kernel_ast) + with open(src_path / f'{kernel_name}.c', 'w+') as f: + f.write(source) with open(src_path / 'main.c', 'w+') as f: - f.write(kernel_main(kernel_ast)) + f.write(kernel_main(kernel_asts)) copy_static_files(path) + compiler_toolchain(path, compiler) + + +def compiler_toolchain(path: Path, compiler: Compiler) -> None: + name = compiler.name + jinja_context = { + 'compiler': name, + } + + env = Environment(loader=PackageLoader('pystencils_benchmark'), undefined=StrictUndefined) + files = ['Makefile', f'{name}.mk'] + for file_name in files: + with open(path / file_name, 'w+') as f: + template = env.get_template(file_name).render(**jinja_context) + f.write(template) def copy_static_files(path: Path) -> None: @@ -47,8 +70,7 @@ def copy_static_files(path: Path) -> None: include_path.mkdir(parents=True, exist_ok=True) env = Environment(loader=PackageLoader('pystencils_benchmark'), undefined=StrictUndefined) - files = ['Makefile', 'aligned_malloc.h', 'timing.h', 'timing.c', 'include_Clang.mk', 'include_GCC.mk', - 'include_ICC.mk', 'include_GCCdebug.mk'] + files = ['aligned_malloc.h', 'timing.h', 'timing.c'] for file_name in files: template = env.get_template(file_name).render() if file_name[-1] == 'h': @@ -61,61 +83,64 @@ def copy_static_files(path: Path) -> None: f.write(template) -def kernel_main(kernel: KernelFunction, timing: bool = True): +def kernel_main(kernels_ast: List[KernelFunction], timing: bool = True): """ Return C code of a benchmark program for the given kernel. Args: - kernel: the pystencils AST object as returned by create_kernel + kernels_ast: A list of the pystencils AST object as returned by create_kernel for benchmarking timing: add timing output to the code, prints time per iteration to stdout Returns: C code as string """ - kernel_name = kernel.function_name - accessed_fields = {f.name: f for f in kernel.fields_accessed} - constants = [] - fields = [] - call_parameters = [] - for p in kernel.get_parameters(): - if not p.is_field_parameter: - constants.append((p.symbol.name, str(p.symbol.dtype))) - call_parameters.append(p.symbol.name) - else: - assert p.is_field_pointer, "Benchmark implemented only for kernels with fixed loop size" - field = accessed_fields[p.field_name] - dtype = str(get_base_type(p.symbol.dtype)) - np_dtype = get_base_type(p.symbol.dtype).numpy_dtype - size_data_type = np_dtype.itemsize - - dim0_size = field.shape[-1] - dim1_size = np.prod(field.shape[:-1]) - elements = prod(field.shape) - - if kernel.instruction_set: - align = kernel.instruction_set['width'] * size_data_type - padding_elements = modulo_ceil(dim0_size, kernel.instruction_set['width']) - dim0_size - padding_bytes = padding_elements * size_data_type - ghost_layers = max(max(kernel.ghost_layers)) - - size = dim1_size * padding_bytes + np.prod(field.shape) * size_data_type - - assert align % np_dtype.itemsize == 0 - offset = ((dim0_size + padding_elements + ghost_layers) % kernel.instruction_set['width']) * size_data_type - - fields.append((p.field_name, dtype, elements, size, offset, align)) - call_parameters.append(p.field_name) + Kernel = namedtuple('Kernel', ['name', 'constants', 'fields', 'call_parameters', 'call_argument_list']) + kernels = [] + includes = set() + for kernel in kernels_ast: + name = kernel.function_name + accessed_fields = {f.name: f for f in kernel.fields_accessed} + constants = [] + fields = [] + call_parameters = [] + for p in kernel.get_parameters(): + if not p.is_field_parameter: + constants.append((p.symbol.name, str(p.symbol.dtype))) + call_parameters.append(p.symbol.name) else: - size = elements * size_data_type - fields.append((p.field_name, dtype, elements, size, 0, 0)) - call_parameters.append(p.field_name) + assert p.is_field_pointer, "Benchmark implemented only for kernels with fixed loop size" + field = accessed_fields[p.field_name] + dtype = str(get_base_type(p.symbol.dtype)) + np_dtype = get_base_type(p.symbol.dtype).numpy_dtype + size_data_type = np_dtype.itemsize + + dim0_size = field.shape[-1] + dim1_size = np.prod(field.shape[:-1]) + elements = prod(field.shape) + + if kernel.instruction_set: + align = kernel.instruction_set['width'] * size_data_type + padding_elements = modulo_ceil(dim0_size, kernel.instruction_set['width']) - dim0_size + padding_bytes = padding_elements * size_data_type + ghost_layers = max(max(kernel.ghost_layers)) + + size = dim1_size * padding_bytes + np.prod(field.shape) * size_data_type + + assert align % np_dtype.itemsize == 0 + offset = ((dim0_size + padding_elements + ghost_layers) % kernel.instruction_set['width']) * size_data_type + + fields.append((p.field_name, dtype, elements, size, offset, align)) + call_parameters.append(p.field_name) + else: + size = elements * size_data_type + fields.append((p.field_name, dtype, elements, size, 0, 0)) + call_parameters.append(p.field_name) + kernels.append(Kernel(name=name, fields=fields, constants=constants, call_parameters=call_parameters, + call_argument_list=",".join(call_parameters))) + + includes.add(f'#include "{name}.h"\n') - includes = f'#include "{kernel_name}.h"\n' jinja_context = { - 'kernel_code': generate_c(kernel, dialect=Backend.C), - 'kernel_name': kernel_name, - 'fields': fields, - 'constants': constants, - 'call_argument_list': ",".join(call_parameters), + 'kernels': kernels, 'includes': includes, 'timing': timing, } diff --git a/pystencils_benchmark/enums.py b/pystencils_benchmark/enums.py new file mode 100644 index 0000000..ec56c8a --- /dev/null +++ b/pystencils_benchmark/enums.py @@ -0,0 +1,8 @@ +from enum import Enum, auto + + +class Compiler(Enum): + GCC = auto() + GCCdebug = auto() + Clang = auto() + ICC = auto() diff --git a/pystencils_benchmark/templates/Clang.mk b/pystencils_benchmark/templates/Clang.mk new file mode 100644 index 0000000..61eee7f --- /dev/null +++ b/pystencils_benchmark/templates/Clang.mk @@ -0,0 +1,19 @@ +CC = clang +LINKER = $(CC) + +ANSI_CFLAGS = -ansi +ANSI_CFLAGS += -std=c99 +ANSI_CFLAGS += -pedantic +ANSI_CFLAGS += -Wextra + +CFLAGS = -O3 -Wno-format -Wall $(ANSI_CFLAGS) -fopenmp +# More warning pls +#CFLAGS += -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return +# Maybe too much warnings +#CFLAGS += -Wcast-qual -Wswitch-default -Wconversion -Wunreachable-code +# Specific C flags +CFLAGS := $(CFLAGS) -Wstrict-prototypes +LFLAGS = -fopenmp +DEFINES = -D_GNU_SOURCE -DNDEBUG +INCLUDES = +LIBS = diff --git a/pystencils_benchmark/templates/include_GCC.mk b/pystencils_benchmark/templates/GCC.mk similarity index 100% rename from pystencils_benchmark/templates/include_GCC.mk rename to pystencils_benchmark/templates/GCC.mk diff --git a/pystencils_benchmark/templates/include_GCCdebug.mk b/pystencils_benchmark/templates/GCCdebug.mk similarity index 69% rename from pystencils_benchmark/templates/include_GCCdebug.mk rename to pystencils_benchmark/templates/GCCdebug.mk index 1685617..f453f0d 100644 --- a/pystencils_benchmark/templates/include_GCCdebug.mk +++ b/pystencils_benchmark/templates/GCCdebug.mk @@ -5,10 +5,8 @@ ANSI_CFLAGS = -ansi ANSI_CFLAGS += -std=c99 ANSI_CFLAGS += -pedantic ANSI_CFLAGS += -Wextra -ANSI_CFLAGS += -O0 -ANSI_CFLAGS += -g -CFLAGS = -Wno-format -Wall $(ANSI_CFLAGS) +CFLAGS = -O0 -g -Wno-format -Wall $(ANSI_CFLAGS) FCFLAGS = LFLAGS = DEFINES = -D_GNU_SOURCE diff --git a/pystencils_benchmark/templates/include_ICC.mk b/pystencils_benchmark/templates/ICC.mk similarity index 100% rename from pystencils_benchmark/templates/include_ICC.mk rename to pystencils_benchmark/templates/ICC.mk diff --git a/pystencils_benchmark/templates/Makefile b/pystencils_benchmark/templates/Makefile index 5490559..b9b8cfc 100644 --- a/pystencils_benchmark/templates/Makefile +++ b/pystencils_benchmark/templates/Makefile @@ -1,4 +1,4 @@ -TAG = GCC +TAG = {{compiler}} #CONFIGURE BUILD SYSTEM TARGET = benchmark-$(TAG) @@ -8,13 +8,13 @@ MAKE_DIR = ./ Q ?= @ #DO NOT EDIT BELOW -include $(MAKE_DIR)/include_$(TAG).mk +include $(MAKE_DIR)/$(TAG).mk INCLUDES += -I./include VPATH = $(SRC_DIR) ASM = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.s,$(wildcard $(SRC_DIR)/*.c)) OBJ = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o,$(wildcard $(SRC_DIR)/*.c)) -CPPFLAGS := $(CPPFLAGS) $(DEFINES) $(INCLUDES) +CFLAGS := $(CFLAGS) $(DEFINES) $(INCLUDES) ${TARGET}: $(BUILD_DIR) $(OBJ) @@ -25,8 +25,8 @@ asm: $(BUILD_DIR) $(ASM) $(BUILD_DIR)/%.o: %.c @echo "===> COMPILE $@" - $(Q)$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ - $(Q)$(CC) $(CPPFLAGS) -MT $(@:.d=.o) -MM $< > $(BUILD_DIR)/$*.d + $(Q)$(CC) -c $(CFLAGS) $< -o $@ + $(Q)$(CC) $(CFLAGS) -MT $(@:.d=.o) -MM $< > $(BUILD_DIR)/$*.d $(BUILD_DIR)/%.s: %.c @echo "===> GENERATE ASM $@" @@ -44,16 +44,7 @@ ifeq ($(findstring $(MAKECMDGOALS),clean),) -include $(OBJ:.o=.d) endif -.PHONY: clean distclean debug debug-clean debug-distclean - -debug: - @make TAG=GCCdebug - -debug-clean: - @make clean TAG=GCCdebug - -debug-distclean: - @make distclean TAG=GCCdebug +.PHONY: clean distclean clean: @echo "===> CLEAN" diff --git a/pystencils_benchmark/templates/include_Clang.mk b/pystencils_benchmark/templates/include_Clang.mk deleted file mode 100644 index dab3ce3..0000000 --- a/pystencils_benchmark/templates/include_Clang.mk +++ /dev/null @@ -1,24 +0,0 @@ -CC = clang -CXX = clang++ -FC = gfortran -LINKER = $(CXX) - -ANSI_CFLAGS = -ansi -ANSI_CFLAGS += -std=c++0x -ANSI_CFLAGS += -pedantic -ANSI_CFLAGS += -Wextra - -CFLAGS = -O3 -Wno-format -Wall $(ANSI_CFLAGS) -# More warning pls -CFLAGS += -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -# Maybe too much warnings -CFLAGS += -Wcast-qual -Wswitch-default -Wconversion -Wunreachable-code -CXXFLAGS := $(CFLAGS) -# Specific C flags -CFLAGS := $(CFLAGS) -Wstrict-prototypes -FCFLAGS = -CPPFLAGS = -std=c++0x -LFLAGS = #-fopenmp -DEFINES = -D_GNU_SOURCE -DNDEBUG -INCLUDES = #-I/usr/lib/gcc/x86_64-linux-gnu/4.8/include/ -LIBS = #-L/usr/lib/x86_64-linux-gnu/libomp.so.5 diff --git a/pystencils_benchmark/templates/main.c b/pystencils_benchmark/templates/main.c index f15e9ab..7f8ea99 100644 --- a/pystencils_benchmark/templates/main.c +++ b/pystencils_benchmark/templates/main.c @@ -5,56 +5,66 @@ #include <stdio.h> #include <assert.h> -{{ includes }} +#include "timing.h" + +{%- for include in includes %} +{{ include }} +{%- endfor %} #define RESTRICT __restrict__ #define FUNC_PREFIX -void timing(double* wcTime, double* cpuTime); - int main(int argc, char **argv) { - {%- for field_name, dataType, elements, size, offset, alignment in fields %} - // Initialization {{field_name}} - {%- if alignment > 0 %} - {{dataType}} * {{field_name}} = ({{dataType}} *) aligned_malloc_with_offset({{size}}, {{alignment}}, {{offset}}); - {%- else %} - {{dataType}} * {{field_name}} = ({{dataType}} *) malloc({{size}}); - {%- endif %} - for (unsigned long long i = 0; i < {{elements}}; ++i) - {{field_name}}[i] = 0.23; - {%- endfor %} - - {%- for constantName, dataType in constants %} - // Constant {{constantName}} - {{dataType}} {{constantName}}; - {{constantName}} = 0.23; - {%- endfor %} - - for(int warmup = 1; warmup >= 0; --warmup) { - int repeat = 2; - if(warmup == 0) { - repeat = atoi(argv[1]); + if(argc < 2) { + printf("Usage: %s <n_repeat>\n", argv[0]); + return -1; } + int n_repeat = atoi(argv[1]); + {%- for kernel in kernels %} + { + {%- for field_name, dataType, elements, size, offset, alignment in kernel.fields %} + // Initialization {{field_name}} + {%- if alignment > 0 %} + {{dataType}} * {{field_name}} = ({{dataType}} *) aligned_malloc_with_offset({{size}}, {{alignment}}, {{offset}}); + {%- else %} + {{dataType}} * {{field_name}} = ({{dataType}} *) malloc({{size}}); + {%- endif %} + for (unsigned long long i = 0; i < {{elements}}; ++i) + {{field_name}}[i] = 0.23; + {%- endfor %} - {%- if timing %} - double wcStartTime, cpuStartTime, wcEndTime, cpuEndTime; - timing(&wcStartTime, &cpuStartTime); - {%- endif %} + {%- for constantName, dataType in kernel.constants %} + // Constant {{constantName}} + {{dataType}} {{constantName}}; + {{constantName}} = 0.23; + {%- endfor %} - for (; repeat > 0; --repeat) - { - {{kernel_name}}({{call_argument_list}}); - } - {%- if timing %} - timing(&wcEndTime, &cpuEndTime); - if( warmup == 0) - printf("%e\n", (wcEndTime - wcStartTime) / atoi(argv[1]) ); - {%- endif %} + for(int warmup = 1; warmup >= 0; --warmup) { + int repeat = 2; + if(warmup == 0) { + repeat = n_repeat; + } + + {%- if timing %} + double wcStartTime, cpuStartTime, wcEndTime, cpuEndTime; + timing(&wcStartTime, &cpuStartTime); + {%- endif %} - } + for (; repeat > 0; --repeat) + { + {{kernel.name}}({{kernel.call_argument_list}}); + } + {%- if timing %} + timing(&wcEndTime, &cpuEndTime); + if( warmup == 0) + printf("%s\t%e\n", "{{kernel.name}}",(wcEndTime - wcStartTime) / n_repeat ); + {%- endif %} + } - {%- for field_name, dataType, elements, size, offset, alignment in fields %} - free({{field_name}}); - {%- endfor %} + {%- for field_name, dataType, elements, size, offset, alignment in kernel.fields %} + free({{field_name}}); + {%- endfor %} + } + {%- endfor %} } diff --git a/requirements.txt b/requirements.txt index ef5420a..14f8297 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ Jinja2>=3.0.2 pystencils>=0.4.1 -setuptools>=44.0.0 \ No newline at end of file +setuptools>=44.0.0 +numpy>=1.21.4 \ No newline at end of file diff --git a/test.ipynb b/test.ipynb deleted file mode 100644 index e6ac951..0000000 --- a/test.ipynb +++ /dev/null @@ -1,130 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pystencils as ps\n", - "from pystencils_benchmark import generate_benchmark\n", - "from pathlib import Path" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "outputs": [], - "source": [ - "config = ps.CreateKernelConfig(function_name='vadd')" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } - }, - { - "cell_type": "code", - "execution_count": 3, - "outputs": [], - "source": [ - "a, b, c = ps.fields(a=np.ones(4000000), b=np.ones(4000000), c=np.ones(4000000))" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } - }, - { - "cell_type": "code", - "execution_count": 4, - "outputs": [], - "source": [ - "@ps.kernel\n", - "def vadd():\n", - " a[0] @= b[0] + c[0]" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } - }, - { - "cell_type": "code", - "execution_count": 5, - "outputs": [ - { - "data": { - "text/plain": "<IPython.core.display.HTML object>", - "text/html": "<style>pre { line-height: 125%; }\ntd.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\nspan.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\ntd.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\nspan.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n.highlight .hll { background-color: #ffffcc }\n.highlight { background: #f8f8f8; }\n.highlight .c { color: #408080; font-style: italic } /* Comment */\n.highlight .err { border: 1px solid #FF0000 } /* Error */\n.highlight .k { color: #008000; font-weight: bold } /* Keyword */\n.highlight .o { color: #666666 } /* Operator */\n.highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n.highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n.highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n.highlight .gd { color: #A00000 } /* Generic.Deleted */\n.highlight .ge { font-style: italic } /* Generic.Emph */\n.highlight .gr { color: #FF0000 } /* Generic.Error */\n.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n.highlight .gi { color: #00A000 } /* Generic.Inserted */\n.highlight .go { color: #888888 } /* Generic.Output */\n.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n.highlight .gs { font-weight: bold } /* Generic.Strong */\n.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n.highlight .gt { color: #0044DD } /* Generic.Traceback */\n.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n.highlight .kp { color: #008000 } /* Keyword.Pseudo */\n.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n.highlight .kt { color: #B00040 } /* Keyword.Type */\n.highlight .m { color: #666666 } /* Literal.Number */\n.highlight .s { color: #BA2121 } /* Literal.String */\n.highlight .na { color: #7D9029 } /* Name.Attribute */\n.highlight .nb { color: #008000 } /* Name.Builtin */\n.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n.highlight .no { color: #880000 } /* Name.Constant */\n.highlight .nd { color: #AA22FF } /* Name.Decorator */\n.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n.highlight .nf { color: #0000FF } /* Name.Function */\n.highlight .nl { color: #A0A000 } /* Name.Label */\n.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n.highlight .nv { color: #19177C } /* Name.Variable */\n.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n.highlight .w { color: #bbbbbb } /* Text.Whitespace */\n.highlight .mb { color: #666666 } /* Literal.Number.Bin */\n.highlight .mf { color: #666666 } /* Literal.Number.Float */\n.highlight .mh { color: #666666 } /* Literal.Number.Hex */\n.highlight .mi { color: #666666 } /* Literal.Number.Integer */\n.highlight .mo { color: #666666 } /* Literal.Number.Oct */\n.highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n.highlight .sc { color: #BA2121 } /* Literal.String.Char */\n.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n.highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n.highlight .sx { color: #008000 } /* Literal.String.Other */\n.highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n.highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n.highlight .ss { color: #19177C } /* Literal.String.Symbol */\n.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n.highlight .fm { color: #0000FF } /* Name.Function.Magic */\n.highlight .vc { color: #19177C } /* Name.Variable.Class */\n.highlight .vg { color: #19177C } /* Name.Variable.Global */\n.highlight .vi { color: #19177C } /* Name.Variable.Instance */\n.highlight .vm { color: #19177C } /* Name.Variable.Magic */\n.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style>" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": "FUNC_PREFIX void vadd(double * RESTRICT _data_a, double * RESTRICT const _data_b, double * RESTRICT const _data_c)\n{\n for (int64_t ctr_0 = 0; ctr_0 < 4000000; ctr_0 += 1)\n {\n _data_a[ctr_0] = _data_b[ctr_0] + _data_c[ctr_0];\n }\n}", - "text/html": "<div class=\"highlight\"><pre><span></span><span class=\"n\">FUNC_PREFIX</span><span class=\"w\"> </span><span class=\"kt\">void</span><span class=\"w\"> </span><span class=\"n\">vadd</span><span class=\"p\">(</span><span class=\"kt\">double</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"n\">RESTRICT</span><span class=\"w\"> </span><span class=\"n\">_data_a</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">double</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"n\">RESTRICT</span><span class=\"w\"> </span><span class=\"k\">const</span><span class=\"w\"> </span><span class=\"n\">_data_b</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"kt\">double</span><span class=\"w\"> </span><span class=\"o\">*</span><span class=\"w\"> </span><span class=\"n\">RESTRICT</span><span class=\"w\"> </span><span class=\"k\">const</span><span class=\"w\"> </span><span class=\"n\">_data_c</span><span class=\"p\">)</span><span class=\"w\"></span>\n<span class=\"p\">{</span><span class=\"w\"></span>\n<span class=\"w\"> </span><span class=\"k\">for</span><span class=\"w\"> </span><span class=\"p\">(</span><span class=\"kt\">int64_t</span><span class=\"w\"> </span><span class=\"n\">ctr_0</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"mi\">0</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"n\">ctr_0</span><span class=\"w\"> </span><span class=\"o\"><</span><span class=\"w\"> </span><span class=\"mi\">4000000</span><span class=\"p\">;</span><span class=\"w\"> </span><span class=\"n\">ctr_0</span><span class=\"w\"> </span><span class=\"o\">+=</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"p\">)</span><span class=\"w\"></span>\n<span class=\"w\"> </span><span class=\"p\">{</span><span class=\"w\"></span>\n<span class=\"w\"> </span><span class=\"n\">_data_a</span><span class=\"p\">[</span><span class=\"n\">ctr_0</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"o\">=</span><span class=\"w\"> </span><span class=\"n\">_data_b</span><span class=\"p\">[</span><span class=\"n\">ctr_0</span><span class=\"p\">]</span><span class=\"w\"> </span><span class=\"o\">+</span><span class=\"w\"> </span><span class=\"n\">_data_c</span><span class=\"p\">[</span><span class=\"n\">ctr_0</span><span class=\"p\">];</span><span class=\"w\"></span>\n<span class=\"w\"> </span><span class=\"p\">}</span><span class=\"w\"></span>\n<span class=\"p\">}</span><span class=\"w\"></span>\n</pre></div>\n" - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "kernel_vadd = ps.create_kernel(vadd, config=config)\n", - "ps.show_code(kernel_vadd)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } - }, - { - "cell_type": "code", - "execution_count": 6, - "outputs": [], - "source": [ - "example_path = Path.cwd() / 'example'\n", - "generate_benchmark(kernel_vadd, example_path)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} \ No newline at end of file diff --git a/test.py b/test.py new file mode 100755 index 0000000..d516678 --- /dev/null +++ b/test.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# coding: utf-8 +import subprocess +import numpy as np +import sympy as sp +import pystencils as ps +from pystencils_benchmark import generate_benchmark +from pathlib import Path + + +def generate(path: Path): + a, b, c = ps.fields(a=np.ones(4000000), b=np.ones(4000000), c=np.ones(4000000)) + alpha = sp.symbols('alpha') + + @ps.kernel_config(ps.CreateKernelConfig()) + def vadd(): + a[0] @= b[0] + c[0] + kernel_vadd = ps.create_kernel(**vadd) + + @ps.kernel_config(ps.CreateKernelConfig()) + def daxpy(): + b[0] @= alpha * a[0] + b[0] + kernel_daxpy = ps.create_kernel(**daxpy) + + generate_benchmark([kernel_vadd, kernel_daxpy], path) + + +def make(path: Path): + subprocess.run(['make']) + + +def execute(path: Path): + subprocess.run(['./benchmark-GCC', '200']) + + +def main(): + path = Path.cwd() + generate(path) + make(path) + execute(path) + + +if __name__ == '__main__': + main() + -- GitLab