2021-12-15 16:04:18

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 01/12] perf test: Shell - Limit to only run executable scripts in tests

From: Carsten Haitzler <[email protected]>

Perf test's shell runner will just run everything in the tests
directory (as long as it's not another directory or does not begin
with a dot), but sometimes you find files in there that are not shell
scripts - perf.data output for example if you do some testing and then
the next time you run perf test it tries to run these. Check the files
are executable so they are actually intended to be test scripts and
not just some "random junk" files there.

Signed-off-by: Carsten Haitzler <[email protected]>
---
tools/perf/tests/builtin-test.c | 4 +++-
tools/perf/util/path.c | 12 ++++++++++++
tools/perf/util/path.h | 1 +
3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 8cb5a1c3489e..ece272b55587 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -295,7 +295,9 @@ static const char *shell_test__description(char *description, size_t size,

#define for_each_shell_test(entlist, nr, base, ent) \
for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
- if (!is_directory(base, ent) && ent->d_name[0] != '.')
+ if (!is_directory(base, ent) && \
+ is_executable_file(base, ent) && \
+ ent->d_name[0] != '.')

static const char *shell_tests__dir(char *path, size_t size)
{
diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
index caed0336429f..7dde8c230ae8 100644
--- a/tools/perf/util/path.c
+++ b/tools/perf/util/path.c
@@ -92,3 +92,15 @@ bool is_directory(const char *base_path, const struct dirent *dent)

return S_ISDIR(st.st_mode);
}
+
+bool is_executable_file(const char *base_path, const struct dirent *dent)
+{
+ char path[PATH_MAX];
+ struct stat st;
+
+ sprintf(path, "%s/%s", base_path, dent->d_name);
+ if (stat(path, &st))
+ return false;
+
+ return !S_ISDIR(st.st_mode) && (st.st_mode & S_IXUSR);
+}
diff --git a/tools/perf/util/path.h b/tools/perf/util/path.h
index 083429b7efa3..d94902c22222 100644
--- a/tools/perf/util/path.h
+++ b/tools/perf/util/path.h
@@ -12,5 +12,6 @@ int path__join3(char *bf, size_t size, const char *path1, const char *path2, con

bool is_regular_file(const char *file);
bool is_directory(const char *base_path, const struct dirent *dent);
+bool is_executable_file(const char *base_path, const struct dirent *dent);

#endif /* _PERF_PATH_H */
--
2.32.0



2021-12-15 16:04:20

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 02/12] perf test: Shell - only run .sh shell files to skip other files

From: Carsten Haitzler <[email protected]>

You edit your scripts in the tests and end up with your usual shell
backup files with ~ or .bak or something else at the end, but then your
next perf test run wants to run the backups too. You might also have perf
.data files in the directory or something else undesireable as well. You end
up chasing which test is the one you edited and the backup and have to keep
removing all the backup files, so automatically skip any files that are
not plain *.sh scripts to limit the time wasted in chasing ghosts.

Signed-off-by: Carsten Haitzler <[email protected]>
---
tools/perf/tests/builtin-test.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index ece272b55587..849737ead9fd 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -297,7 +297,20 @@ static const char *shell_test__description(char *description, size_t size,
for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
if (!is_directory(base, ent) && \
is_executable_file(base, ent) && \
- ent->d_name[0] != '.')
+ ent->d_name[0] != '.' && \
+ (shell_file_is_sh(ent->d_name) == 0))
+
+static int shell_file_is_sh(const char *file)
+{
+ const char *ext;
+
+ ext = strchr(file, '.');
+ if (!ext)
+ return -1;
+ if (!strcmp(ext, ".sh"))
+ return 0;
+ return -1;
+}

static const char *shell_tests__dir(char *path, size_t size)
{
--
2.32.0


2021-12-15 16:04:23

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 03/12] perf test: Use 3 digits for test numbering now we can have more tests

From: Carsten Haitzler <[email protected]>

This is in preparation for adding more tests that will need the test
number to be 3 digts so they align nicely in the output.

Signed-off-by: Carsten Haitzler <[email protected]>
---
tools/perf/tests/builtin-test.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 849737ead9fd..8652dcc4912c 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -435,7 +435,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width,
continue;

st.file = ent->d_name;
- pr_info("%2d: %-*s:", i, width, test_suite.desc);
+ pr_info("%3d: %-*s:", i, width, test_suite.desc);

if (intlist__find(skiplist, i)) {
color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
@@ -485,7 +485,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
continue;
}

- pr_info("%2d: %-*s:", i, width, test_description(t, -1));
+ pr_info("%3d: %-*s:", i, width, test_description(t, -1));

if (intlist__find(skiplist, i)) {
color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
@@ -525,7 +525,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
curr, argc, argv))
continue;

- pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
+ pr_info("%3d.%1d: %-*s:", i, subi + 1, subw,
test_description(t, subi));
test_and_print(t, subi);
}
@@ -560,7 +560,7 @@ static int perf_test__list_shell(int argc, const char **argv, int i)
if (!perf_test__matches(t.desc, curr, argc, argv))
continue;

- pr_info("%2d: %s\n", i, t.desc);
+ pr_info("%3d: %s\n", i, t.desc);

}

@@ -582,14 +582,14 @@ static int perf_test__list(int argc, const char **argv)
if (!perf_test__matches(test_description(t, -1), curr, argc, argv))
continue;

- pr_info("%2d: %s\n", i, test_description(t, -1));
+ pr_info("%3d: %s\n", i, test_description(t, -1));

if (has_subtests(t)) {
int subn = num_subtests(t);
int subi;

for (subi = 0; subi < subn; subi++)
- pr_info("%2d:%1d: %s\n", i, subi + 1,
+ pr_info("%3d:%1d: %s\n", i, subi + 1,
test_description(t, subi));
}
}
--
2.32.0


2021-12-15 16:04:25

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight

From: Carsten Haitzler <[email protected]>

This adds the initial test harness to run perf record and examine the
resuling output when coresight is enabled on arm64 and check the
resulting quality of the output as part of perf test.

Signed-off-by: Carsten Haitzler <[email protected]>
---
MAINTAINERS | 3 +
tools/perf/Makefile.perf | 14 +-
.../tests/shell/coresight_asm_pure_loop.sh | 18 +++
tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
tools/perf/tests/shell/tools/Makefile | 26 ++++
.../perf/tests/shell/tools/coresight/Makefile | 27 ++++
.../shell/tools/coresight/Makefile.miniconfig | 23 ++++
.../tools/coresight/asm_pure_loop/Makefile | 30 ++++
.../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
9 files changed, 297 insertions(+), 2 deletions(-)
create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
create mode 100644 tools/perf/tests/shell/lib/coresight.sh
create mode 100644 tools/perf/tests/shell/tools/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S

diff --git a/MAINTAINERS b/MAINTAINERS
index 13f9a84a617e..d46e8469c467 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
F: tools/perf/arch/arm/util/pmu.c
+F: tools/perf/tests/shell/coresight_*
+F: tools/perf/tests/shell/tools/Makefile
+F: tools/perf/tests/shell/tools/coresight/*
F: tools/perf/util/cs-etm-decoder/*
F: tools/perf/util/cs-etm.*

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 80522bcfafe0..26467a2c71f4 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
$(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
$(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@

-all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
+TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
+
+tests-tools-targets: FORCE
+ $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
+
+tests-tools-targets-clean:
+ $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
+
+all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets

# Create python binding output directory if not already present
_dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
@@ -1020,6 +1028,7 @@ install-tests: all install-gtk
$(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
$(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
+ $(Q)$(MAKE) -C tests/shell/tools install-tests

install-bin: install-tools install-tests install-traceevent-plugins

@@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
bpf-skel-clean:
$(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)

-clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
+clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
$(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
$(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
$(Q)$(RM) $(OUTPUT).config-detected
@@ -1155,5 +1164,6 @@ FORCE:
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
.PHONY: libtraceevent_plugins archheaders
+.PHONY: $(TESTS_TOOLS_TARGETS)

endif # force_fixdep
diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
new file mode 100755
index 000000000000..542d4a37e349
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / ASM Pure Loop
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="asm_pure_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS=""
+DATV="out"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 2601 334 334
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
new file mode 100644
index 000000000000..cd6c1283e6f5
--- /dev/null
+++ b/tools/perf/tests/shell/lib/coresight.sh
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+# This is sourced from a driver script so no need for #!/bin... etc. at the
+# top - the assumption below is that it runs as part of sourcing after the
+# test sets up some basic env vars to say what it is.
+
+# perf record options for the perf tests to use
+PERFRECMEM="-m ,128M"
+PERFRECOPT="$PERFRECMEM -e cs_etm//u"
+
+# These tests need to be run as root or coresight won't allow large buffers
+# and will not collect proper data
+UID=`id -u`
+if test "$UID" -ne 0; then
+ echo "Not running as root... skip"
+ exit 2
+fi
+
+TOOLS=$(dirname $0)/tools
+DIR="$TOOLS/coresight/$TEST"
+BIN="$DIR/$TEST"
+# If the test tool/binary does not exist and is executable then skip the test
+if ! test -x "$BIN"; then exit 2; fi
+DATD="."
+# If the data dir env is set then make the data dir use that instead of ./
+if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
+ DATD="$PERF_TEST_CORESIGHT_DATADIR";
+fi
+# If the stat dir env is set then make the data dir use that instead of ./
+STATD="."
+if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
+ STATD="$PERF_TEST_CORESIGHT_STATDIR";
+fi
+
+# Called if the test fails - error code 2
+err() {
+ echo "$1"
+ exit 1
+}
+
+# Check that some statistics from our perf
+check_val_min() {
+ STATF="$4"
+ if test "$2" -lt "$3"; then
+ echo ", FAILED" >> "$STATF"
+ err "Sanity check number of $1 is too low ($2 < $3)"
+ fi
+}
+
+perf_dump_aux_verify() {
+ # Some basic checking that the AUX chunk contains some sensible data
+ # to see that we are recording something and at least a minimum
+ # amount of it. We should almost always see F3 atoms in just about
+ # anything but certainly we will see some trace info and async atom
+ # chunks.
+ DUMP="$DATD/perf-tmp-aux-dump.txt"
+ perf report --stdio --dump -i "$1" | \
+ grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
+ # Simply count how many of these atoms we find to see that we are
+ # producing a reasonable amount of data - exact checks are not sane
+ # as this is a lossy process where we may lose some blocks and the
+ # compiler may produce different code depending on the compiler and
+ # optimization options, so this is rough just to see if we're
+ # either missing almost all the data or all of it
+ ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
+ ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
+ ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
+ rm -f "$DUMP"
+
+ # Arguments provide minimums for a pass
+ CHECK_F3_MIN="$2"
+ CHECK_ASYNC_MIN="$3"
+ CHECK_TRACE_INFO_MIN="$4"
+
+ # Write out statistics, so over time you can track results to see if
+ # there is a pattern - for example we have less "noisy" results that
+ # produce more consistent amounts of data each run, to see if over
+ # time any techinques to minimize data loss are having an effect or
+ # not
+ STATF="$STATD/stats-$TEST-$DATV.csv"
+ if ! test -f "$STATF"; then
+ echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
+ fi
+ echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
+
+ # Actually check to see if we passed or failed.
+ check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
+ check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
+ check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
+ echo ", Ok" >> "$STATF"
+}
+
+perf_dump_aux_tid_verify() {
+ # Specifically crafted test will produce a list of Tread ID's to
+ # stdout that need to be checked to see that they have had trace
+ # info collected in AUX blocks in the perf data. This will go
+ # through all the TID's that are listed as CID=0xabcdef and see
+ # that all the Thread IDs the test tool reports are in the perf
+ # data AUX chunks
+
+ # The TID test tools will print a TID per stdout line that are being
+ # tested
+ TIDS=`cat "$2"`
+ # Scan the perf report to find the TIDs that are actually CID in hex
+ # and build a list of the ones found
+ FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
+ grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
+ uniq | sort | uniq`
+
+ # Iterate over the list of TIDs that the test says it has and find
+ # them in the TIDs found in the perf report
+ MISSING=""
+ for TID2 in $TIDS; do
+ FOUND=""
+ for TIDHEX in $FOUND_TIDS; do
+ TID=`printf "%i" $TIDHEX`
+ if test "$TID" -eq "$TID2"; then
+ FOUND="y"
+ break
+ fi
+ done
+ if test -z "$FOUND"; then
+ MISSING="$MISSING $TID"
+ fi
+ done
+ if test -n "$MISSING"; then
+ err "Thread IDs $MISSING not found in perf AUX data"
+ fi
+}
diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
new file mode 100644
index 000000000000..c7ada20922fd
--- /dev/null
+++ b/tools/perf/tests/shell/tools/Makefile
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Carsten Haitzler <[email protected]>, 2021
+include ../../../../../tools/scripts/Makefile.include
+include ../../../../../tools/scripts/Makefile.arch
+include ../../../../../tools/scripts/utilities.mak
+
+SUBDIRS = \
+ coresight
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(Q)$(MAKE) -C $@
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+
+install-tests: all $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(Q)$(MAKE) -C $(@:install-%=%) install-tests
+
+CLEANDIRS = $(SUBDIRS:%=clean-%)
+
+clean: $(CLEANDIRS)
+$(CLEANDIRS):
+ $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
+
+.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
new file mode 100644
index 000000000000..723006ea827c
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Carsten Haitzler <[email protected]>, 2021
+include ../../../../../../tools/scripts/Makefile.include
+include ../../../../../../tools/scripts/Makefile.arch
+include ../../../../../../tools/scripts/utilities.mak
+
+SUBDIRS = \
+ asm_pure_loop
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(Q)$(MAKE) -C $@
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+
+install-tests: $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(Q)$(MAKE) -C $(@:install-%=%) install-tests
+
+CLEANDIRS = $(SUBDIRS:%=clean-%)
+
+clean: $(CLEANDIRS)
+$(CLEANDIRS):
+ $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
+
+.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
+
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
new file mode 100644
index 000000000000..cedd26c6a0eb
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Carsten Haitzler <[email protected]>, 2021
+
+ifndef DESTDIR
+prefix ?= $(HOME)
+endif
+
+DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
+perfexecdir = libexec/perf-core
+perfexec_instdir = $(perfexecdir)
+
+ifneq ($(filter /%,$(firstword $(perfexecdir))),)
+perfexec_instdir = $(perfexecdir)
+else
+perfexec_instdir = $(prefix)/$(perfexecdir)
+endif
+
+perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
+INSTALL = install
+
+include ../../../../../../scripts/Makefile.include
+include ../../../../../../scripts/Makefile.arch
+include ../../../../../../scripts/utilities.mak
diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
new file mode 100644
index 000000000000..10c5a60cb71c
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+include ../Makefile.miniconfig
+
+BIN=asm_pure_loop
+LIB=
+
+all: $(BIN)
+
+$(BIN): $(BIN).S
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
new file mode 100644
index 000000000000..262876451021
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Tamas Zsoldos <[email protected]>, 2021 */
+
+.globl _start
+_start:
+ mov x0, 0x000fffff
+ mov x1, xzr
+loop:
+ nop
+ nop
+ cbnz x1, noskip
+ nop
+ nop
+ adrp x2, skip
+ add x2, x2, :lo12:skip
+ br x2
+ nop
+ nop
+noskip:
+ nop
+ nop
+skip:
+ sub x0, x0, 1
+ cbnz x0, loop
+
+ mov x0, #0
+ mov x8, #93 // __NR_exit syscall
+ svc #0
--
2.32.0


2021-12-15 16:04:28

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 06/12] perf test: Add tests to re-use the thread loop test to check aux data

From: Carsten Haitzler <[email protected]>

This checks to see that the thread_loop tests produces sensible
amounts of aux coresight data.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../tests/shell/coresight_thread_loop_2.sh | 18 ++++++++++++++++++
.../tests/shell/coresight_thread_loop_25.sh | 18 ++++++++++++++++++
.../tests/shell/coresight_thread_loop_250.sh | 18 ++++++++++++++++++
3 files changed, 54 insertions(+)
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_2.sh
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_25.sh
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_250.sh

diff --git a/tools/perf/tests/shell/coresight_thread_loop_2.sh b/tools/perf/tests/shell/coresight_thread_loop_2.sh
new file mode 100755
index 000000000000..6d790b870a67
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_2.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 2 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="2 20"
+DATV="2th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 724 11 11
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_thread_loop_25.sh b/tools/perf/tests/shell/coresight_thread_loop_25.sh
new file mode 100755
index 000000000000..cce74202e4db
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_25.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 25 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="25 2"
+DATV="25th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 388121 1255 1255
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_thread_loop_250.sh b/tools/perf/tests/shell/coresight_thread_loop_250.sh
new file mode 100755
index 000000000000..55f271462a4d
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_250.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 250 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="250 1"
+DATV="250th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 724 11 11
+
+err=$?
+exit $err
--
2.32.0


2021-12-15 16:04:33

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 07/12] perf test: Add simple bubblesort test for coresight aux data

From: Carsten Haitzler <[email protected]>

This adds a simple bubblesort test that sorts small and large data
sets to see if a sufficient mount of aux data is produced.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../shell/coresight_bubble_sort_random.sh | 20 +
.../shell/coresight_bubble_sort_small.sh | 20 +
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../tools/coresight/bubble_sort/Makefile | 31 +
.../tools/coresight/bubble_sort/bubble_sort.c | 89 +
.../coresight/bubble_sort/random_array.txt | 1855 +++++++++++++++++
.../coresight/bubble_sort/small_array.txt | 10 +
7 files changed, 2027 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_random.sh
create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_small.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt

diff --git a/tools/perf/tests/shell/coresight_bubble_sort_random.sh b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
new file mode 100755
index 000000000000..63567f8c4f8b
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -e
+# Coresight / Bubblesort Random Array
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="bubble_sort"
+. $(dirname $0)/lib/coresight.sh
+ARGS="$DIR/random_array.txt"
+DATV="random"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+echo $ARGS
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 4188 1630 1630
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_bubble_sort_small.sh b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
new file mode 100755
index 000000000000..ac86d9973fba
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -e
+# Coresight / Bubblesort Small Array
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="bubble_sort"
+. $(dirname $0)/lib/coresight.sh
+ARGS="$DIR/small_array.txt"
+DATV="small"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+echo $ARGS
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 66 6 6
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index 1edab729db76..49fa80d28df4 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -6,7 +6,8 @@ include ../../../../../../tools/scripts/utilities.mak

SUBDIRS = \
asm_pure_loop \
- thread_loop
+ thread_loop \
+ bubble_sort

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
new file mode 100644
index 000000000000..6b82854f9f2b
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=bubble_sort
+LIB=
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'; \
+ $(INSTALL) random_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/random_array.txt'; \
+ $(INSTALL) small_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/small_array.txt'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
new file mode 100644
index 000000000000..07169e03a803
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+// Andrea Brunato <[email protected]>, 2021
+// Example taken from: https://gcc.gnu.org/wiki/AutoFDO/Tutorial
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+int count_lines(FILE *fp)
+{
+ int lines_n = 0;
+ char c;
+
+ for (c = getc(fp); !feof(fp); c = getc(fp)) {
+ if (c == '\n')
+ lines_n = lines_n + 1;
+ }
+ fseek(fp, 0, SEEK_SET);
+#ifdef DEBUG
+ printf("Number of lines: %d\n", lines_n);
+#endif
+ return lines_n;
+}
+
+#ifdef DEBUG
+void print_array(int *arr, int size)
+{
+ int i;
+
+ assert(arr != NULL);
+ for (i = 0; i < size; i++)
+ printf("%d\n", arr[i]);
+}
+#endif
+
+void bubble_sort(int *a, int n)
+{
+ int i, t, s = 1;
+
+ while (s) {
+ s = 0;
+ for (i = 1; i < n; i++) {
+ if (a[i] < a[i - 1]) {
+ t = a[i];
+ a[i] = a[i - 1];
+ a[i - 1] = t;
+ s = 1;
+ }
+ }
+ }
+}
+
+void init_array(int *arr, int size, FILE *fp)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ fscanf(fp, "%d", &arr[i]);
+}
+
+int main(int argc, char **argv)
+{
+ int lines_n = 0, *arr = NULL;
+ FILE *fp;
+
+ assert((argc == 2) && "Please specify an input file\n");
+
+ fp = fopen(argv[1], "r");
+ assert((fp != NULL) && "ERROR: Couldn't open the specified file\n");
+
+ // Input file expected formar: one number per line
+ lines_n = count_lines(fp);
+
+ arr = malloc(sizeof(int) * lines_n);
+ init_array(arr, lines_n, fp);
+
+ bubble_sort(arr, lines_n);
+
+#ifdef DEBUG
+ print_array(arr, lines_n);
+#endif
+
+ free(arr);
+ fclose(fp);
+
+ return 0;
+}
+
+
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
new file mode 100644
index 000000000000..d041cfb7a649
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
@@ -0,0 +1,1855 @@
+11637
+3799
+23116
+15091
+13022
+15840
+27029
+27563
+25641
+28703
+3017
+29923
+26998
+18230
+26864
+9139
+28431
+18283
+21315
+28167
+7700
+14798
+15512
+20470
+9237
+29921
+28395
+15057
+29819
+26831
+5926
+26653
+390
+2976
+21651
+410
+11429
+1828
+3534
+31091
+9141
+30892
+29619
+5033
+20585
+15413
+28673
+32517
+8875
+7509
+22159
+1482
+28926
+2748
+25246
+23677
+2712
+20332
+23615
+2481
+28581
+29728
+13726
+26364
+28074
+23534
+12120
+4130
+1307
+20009
+15225
+17469
+12076
+11899
+22886
+2854
+4667
+11494
+25057
+18590
+15010
+9295
+6603
+12891
+14441
+5499
+26880
+21390
+15932
+3975
+11242
+19063
+27555
+28538
+30148
+14592
+3360
+21049
+24923
+29681
+5157
+15595
+8863
+19992
+12588
+32711
+3077
+22132
+10031
+21685
+1634
+22046
+7323
+17925
+20453
+3694
+4502
+13543
+1959
+9365
+25814
+29540
+30414
+551
+32722
+23697
+32501
+9890
+13134
+2408
+21814
+1692
+8219
+27175
+19880
+1971
+17913
+10985
+75
+6275
+29139
+7104
+3241
+24809
+13310
+17897
+32684
+7199
+2015
+31825
+20985
+30466
+25403
+28839
+3939
+30171
+9223
+27181
+1302
+7945
+18902
+22094
+28959
+28100
+1874
+29613
+4804
+23941
+31981
+1874
+25476
+10176
+2004
+16080
+32404
+24472
+14217
+9647
+24917
+15001
+15559
+23867
+32520
+2545
+2233
+28869
+13685
+26640
+6548
+27395
+13590
+2851
+1008
+10772
+10417
+17257
+19706
+21757
+27627
+13514
+4631
+19162
+1138
+6325
+22136
+12944
+16124
+12359
+25197
+13024
+13459
+31896
+4661
+12648
+24619
+29975
+2417
+30526
+9880
+32733
+19252
+25646
+12851
+25535
+22792
+21622
+25256
+9785
+11252
+23999
+22965
+10221
+32537
+754
+6831
+11892
+4420
+12472
+20903
+18420
+14968
+17626
+25366
+27811
+6781
+15767
+19341
+28487
+28252
+1225
+31467
+10531
+29736
+12770
+11237
+26065
+9298
+9389
+4413
+25708
+4222
+206
+1952
+16927
+17411
+19671
+23966
+21346
+5232
+26240
+11465
+24782
+20600
+18201
+4713
+32313
+4899
+14371
+11307
+5277
+2022
+14443
+14631
+28140
+23499
+3955
+7565
+18082
+28583
+26049
+11652
+27835
+5415
+29742
+8307
+8380
+20582
+5376
+28696
+762
+6860
+8829
+3579
+2620
+14623
+26606
+31027
+8334
+5654
+15247
+25230
+8096
+1998
+11131
+25257
+31275
+18099
+22294
+9458
+17779
+22216
+4149
+22198
+172
+23793
+30710
+4351
+9939
+13985
+11652
+59
+26587
+9059
+26071
+20826
+3493
+32165
+10983
+29045
+28704
+29635
+19259
+15806
+15124
+18009
+20333
+17020
+1086
+13690
+32368
+14632
+15249
+31064
+18941
+9348
+9006
+31486
+4229
+26282
+24749
+11214
+12670
+5822
+23520
+7971
+28458
+28781
+15391
+28848
+1629
+30060
+19100
+27055
+6999
+7166
+31382
+12066
+15730
+23622
+17211
+30853
+15946
+7092
+5278
+14151
+29985
+2197
+3038
+17757
+14821
+11374
+16227
+7657
+29476
+7761
+6718
+5380
+3255
+28899
+507
+21354
+8942
+21928
+17282
+15106
+8035
+17251
+28354
+14675
+16033
+23012
+10270
+3609
+12387
+4083
+22608
+18438
+10363
+31842
+25456
+2993
+12567
+12285
+10847
+4036
+25889
+2263
+7521
+8246
+27332
+6281
+5934
+2057
+24322
+22014
+18625
+17420
+11120
+4933
+18486
+9201
+22355
+20027
+14665
+6106
+16764
+1955
+2674
+24517
+23913
+20392
+16961
+25273
+5622
+29187
+20339
+11895
+10335
+9094
+20758
+14115
+44
+29610
+29161
+14578
+30088
+22551
+9064
+19533
+428
+27047
+210
+7836
+24192
+18636
+32533
+4747
+1086
+23230
+6341
+31606
+8201
+29138
+28172
+11305
+1387
+25794
+23095
+2600
+1452
+8294
+15374
+31146
+18513
+11
+7897
+30819
+31
+11752
+32591
+27803
+26885
+7667
+31592
+10244
+24349
+17836
+25237
+21489
+9578
+6322
+5457
+15157
+15541
+19222
+12621
+21554
+22651
+12729
+10582
+10290
+10887
+23746
+26686
+1585
+10165
+31947
+19779
+15980
+20878
+28201
+26455
+10696
+19505
+29741
+1935
+2223
+28124
+17789
+24280
+25012
+11103
+6445
+10182
+22947
+31249
+12870
+25620
+9034
+28337
+17508
+12857
+32045
+23453
+18922
+29958
+13095
+27482
+1809
+13962
+15407
+23537
+28052
+24819
+7332
+29319
+11951
+7396
+0
+24126
+1573
+15203
+1194
+31509
+19366
+23180
+21698
+24946
+14946
+8384
+30229
+10099
+5060
+23938
+12575
+7220
+29396
+25422
+22865
+3935
+31126
+14275
+9741
+25019
+26108
+8997
+29459
+5595
+14307
+22680
+13453
+23456
+1218
+889
+11412
+22111
+15488
+16512
+24954
+25449
+14049
+10795
+6430
+7939
+23312
+8849
+4246
+3910
+3920
+8279
+29146
+23176
+29495
+22478
+22801
+15464
+1404
+24320
+9644
+24047
+6372
+25831
+10546
+25452
+162
+12526
+10816
+2805
+12098
+18199
+22284
+2588
+632
+23869
+9515
+18597
+5439
+11016
+19721
+14495
+5671
+3879
+9479
+13968
+25634
+12409
+8940
+1133
+25751
+6666
+19636
+3114
+18339
+27366
+24370
+31234
+24247
+27662
+16433
+9814
+13447
+20513
+18877
+26999
+18659
+27305
+15751
+17192
+11982
+31198
+11367
+20537
+6868
+9125
+26707
+28962
+4645
+22880
+29957
+21981
+29763
+10879
+15307
+21373
+652
+471
+6426
+15176
+11717
+8774
+21421
+22152
+11363
+21204
+8266
+30627
+3237
+17767
+9548
+31154
+26199
+11867
+2590
+508
+5685
+9562
+4680
+3527
+21332
+29853
+4331
+26626
+5804
+8806
+30680
+11836
+2053
+13250
+18750
+12811
+3459
+18921
+14531
+11448
+4381
+19024
+7032
+10599
+19932
+23346
+21110
+31736
+5792
+10309
+407
+6914
+19374
+11265
+15050
+30440
+14511
+16243
+19207
+25865
+3421
+8436
+17959
+30839
+28976
+22855
+1350
+5242
+4582
+19248
+4215
+10734
+29691
+1157
+5396
+5088
+30686
+24674
+29795
+20935
+12005
+1845
+20897
+25337
+27343
+27057
+11172
+23295
+28899
+2790
+15386
+30010
+3736
+22563
+13654
+32418
+3320
+9260
+4893
+1352
+897
+24116
+27410
+7866
+32310
+19354
+2760
+3243
+30622
+26854
+1810
+28332
+6230
+2049
+10362
+12110
+19718
+1304
+17994
+19655
+16923
+9017
+17840
+19894
+9328
+22423
+11185
+18453
+985
+14984
+31486
+2702
+7584
+20132
+5354
+22683
+27453
+15499
+8065
+9823
+29909
+31059
+23496
+32412
+31828
+3667
+13160
+5790
+11816
+31151
+6194
+16912
+20180
+32485
+10858
+28523
+9886
+10689
+1200
+26441
+2446
+10208
+4201
+649
+19694
+21476
+30880
+8900
+9817
+19507
+27582
+16013
+27193
+4177
+29851
+5791
+22262
+28816
+8540
+23328
+26992
+28046
+19652
+2195
+2694
+5634
+7430
+6356
+25759
+17606
+25591
+9758
+17330
+7393
+20057
+31341
+24765
+29760
+20556
+31406
+24439
+16953
+30044
+8448
+19044
+15593
+11764
+10639
+10535
+7469
+13865
+1039
+11436
+1319
+4999
+17500
+13796
+24842
+29723
+24282
+27361
+30792
+32410
+23984
+1667
+8323
+8491
+13317
+388
+9755
+28091
+19517
+29286
+23245
+4345
+9550
+18217
+31425
+17815
+6570
+7935
+6310
+550
+11700
+23011
+25532
+6854
+103
+6814
+15256
+6215
+122
+32352
+10646
+641
+4857
+16185
+26396
+6434
+14595
+6690
+29538
+25092
+16330
+15523
+5603
+8869
+19911
+4792
+12133
+27733
+23723
+32383
+1051
+10146
+8913
+6907
+4710
+6920
+27069
+15176
+17705
+13502
+17262
+7841
+12984
+29694
+21297
+2230
+10199
+24639
+9762
+9313
+5847
+18081
+9873
+14930
+5548
+953
+4307
+24255
+3720
+22293
+18312
+21097
+15784
+60
+4343
+2003
+26727
+26292
+24345
+6251
+28117
+25523
+15836
+31525
+32079
+8277
+31309
+8216
+15472
+9717
+10462
+10504
+27278
+12602
+13757
+11568
+26986
+22193
+18985
+334
+11
+675
+23098
+13090
+10232
+24131
+24210
+32671
+23747
+9766
+13959
+30837
+8515
+31295
+2313
+24877
+10020
+30433
+22083
+3478
+7941
+18436
+14792
+17040
+12004
+13669
+15490
+16678
+23356
+28066
+26871
+25077
+23461
+21786
+27509
+27367
+14961
+2380
+1662
+32487
+19835
+6455
+15376
+614
+9477
+10695
+28054
+28624
+31433
+17214
+30103
+22748
+32392
+26740
+20452
+19781
+17204
+18886
+2597
+16593
+833
+32064
+17379
+17717
+25184
+19581
+19423
+26962
+23824
+25178
+12322
+15802
+17619
+10654
+32343
+17037
+25858
+17284
+20361
+31406
+28206
+17839
+8121
+29850
+28389
+17970
+11480
+16044
+27103
+32676
+9884
+7189
+18612
+27375
+13011
+25248
+8624
+27167
+16913
+17033
+28474
+8431
+28770
+32216
+18027
+25686
+1292
+5509
+6894
+12620
+21287
+24917
+26323
+28448
+23047
+12968
+24616
+3809
+29518
+9663
+24553
+29202
+14835
+21220
+6785
+12761
+21624
+19053
+25295
+15607
+15236
+30405
+13704
+5130
+29608
+26410
+15114
+19041
+21133
+467
+24536
+10935
+2035
+14883
+8947
+22955
+13146
+9581
+29738
+19553
+7607
+125
+25092
+5985
+7843
+1713
+10628
+25470
+10901
+19348
+14538
+29719
+15625
+18293
+1742
+4258
+18738
+16429
+3453
+21625
+30091
+18119
+32643
+4672
+27135
+2571
+3211
+9096
+24942
+14666
+21660
+28962
+8376
+27399
+15822
+31049
+24155
+20515
+1979
+16109
+4627
+21804
+30092
+334
+18524
+11833
+20560
+28614
+29904
+21991
+23488
+20411
+11622
+15031
+2605
+21713
+7213
+7527
+11539
+27664
+26088
+569
+4311
+20104
+28409
+20140
+19522
+9077
+10930
+18157
+16787
+25216
+31867
+15602
+23801
+7375
+126
+9909
+32501
+19906
+19960
+7843
+8081
+9047
+22998
+5138
+21896
+32155
+32038
+291
+26500
+17796
+3376
+5274
+17693
+16263
+1929
+27670
+17073
+4405
+31778
+14877
+27450
+32036
+32068
+18642
+30320
+25415
+9179
+13420
+22419
+11277
+9943
+11543
+2342
+18245
+21913
+28469
+14693
+27338
+15644
+18322
+2936
+12075
+26487
+32264
+7399
+14240
+15771
+24509
+18825
+24192
+31505
+26939
+30511
+461
+1128
+112
+24820
+1294
+11189
+20272
+8069
+12934
+9509
+19741
+29200
+15054
+28557
+25545
+16865
+27595
+9225
+28484
+31668
+5411
+23119
+10962
+27218
+25619
+29940
+3622
+1066
+11964
+31472
+20788
+23492
+24322
+8570
+11716
+22958
+29473
+16120
+23711
+6619
+19457
+29281
+27719
+244
+23114
+28056
+26593
+9480
+27710
+31837
+32069
+4026
+9879
+9042
+32608
+6795
+27340
+6852
+883
+20682
+18656
+7122
+15695
+13991
+16284
+29566
+6121
+6020
+31946
+29874
+31744
+1946
+22451
+25898
+23162
+9393
+3941
+3448
+32753
+22040
+29576
+14181
+5697
+22569
+11246
+21344
+2891
+13406
+24146
+390
+10703
+8579
+25655
+2793
+4943
+30009
+9639
+18977
+24143
+18134
+19731
+14156
+1232
+8084
+383
+30027
+15069
+9746
+1381
+778
+25038
+28997
+11532
+13229
+23991
+28602
+28324
+28633
+21528
+13926
+7710
+4674
+28146
+31878
+30140
+24761
+26088
+10278
+9298
+19222
+26857
+23429
+19972
+14196
+27217
+12954
+30148
+17750
+19522
+21466
+21660
+11011
+32207
+22585
+14840
+3521
+10587
+22146
+4859
+17064
+31390
+28883
+23549
+28312
+116
+5260
+19196
+6555
+22381
+29286
+19461
+9586
+10974
+5676
+32061
+26244
+1874
+19439
+5705
+20417
+25687
+23385
+29016
+3201
+5790
+15781
+21509
+19756
+23127
+23924
+10464
+22550
+26144
+29604
+20089
+11870
+16496
+20640
+27227
+22890
+23413
+7918
+22186
+30532
+23574
+1646
+25828
+315
+31698
+13637
+31893
+25564
+13690
+14596
+32347
+23953
+1829
+19971
+23093
+5300
+29371
+10063
+1129
+21488
+22779
+8333
+24487
+27310
+30552
+21547
+723
+10370
+13546
+4082
+8682
+13208
+5546
+31993
+27919
+16801
+20501
+20527
+4578
+20495
+23257
+5340
+21509
+26646
+19661
+26958
+13559
+419
+11644
+26349
+32524
+11124
+31548
+26106
+15439
+13550
+17329
+17758
+19741
+1020
+17659
+29331
+18736
+6154
+26313
+28267
+2627
+29486
+29044
+5708
+5702
+31775
+7941
+9466
+30057
+7336
+2555
+28935
+12294
+4047
+13739
+15228
+30671
+25563
+4206
+21361
+22280
+475
+6302
+20412
+26433
+952
+26151
+20481
+19452
+18371
+8940
+20951
+17110
+13156
+4703
+31059
+25482
+7312
+3673
+17124
+18114
+4580
+17464
+1390
+20398
+31910
+10008
+26001
+27332
+16160
+4857
+24098
+13238
+13060
+3120
+24159
+29069
+10728
+28482
+5384
+3942
+7447
+6547
+19071
+3039
+13274
+20428
+9912
+18337
+19645
+22585
+24266
+16901
+2802
+14553
+30885
+30400
+32399
+6435
+29473
+20710
+28030
+8862
+1808
+27159
+18300
+31619
+11378
+7340
+338
+27066
+27540
+24851
+23453
+30335
+11332
+27409
+25216
+6464
+3600
+31313
+6494
+17896
+19375
+2169
+30255
+10571
+22434
+1402
+12939
+6410
+1089
+1078
+14455
+23491
+3051
+4024
+6072
+28925
+19218
+11802
+23003
+4122
+23330
+21650
+1085
+1812
+31021
+11195
+17798
+11999
+23012
+15104
+10956
+890
+24979
+9399
+16561
+432
+7010
+5096
+5997
+20666
+10967
+11989
+24193
+14253
+28125
+1741
+11372
+14820
+1120
+31350
+11628
+25363
+17657
+3996
+2792
+22729
+7050
+10487
+10522
+13410
+17034
+5294
+26133
+5995
+20262
+1747
+18778
+26293
+17222
+23151
+28805
+28665
+4636
+14509
+11355
+12011
+7781
+21985
+29915
+29324
+6290
+15154
+29132
+11290
+522
+5120
+20375
+25145
+11202
+29750
+15947
+26516
+22990
+7319
+20231
+10644
+27608
+21434
+32345
+18927
+6568
+9749
+31987
+23632
+21696
+9666
+2040
+2134
+2242
+5559
+27430
+20952
+192
+31554
+18837
+11816
+30277
+25451
+21547
+2541
+25816
+29475
+16232
+1700
+19817
+21906
+14691
+12591
+18044
+8909
+25202
+27953
+23172
+22914
+6804
+14234
+12636
+20760
+21866
+31846
+17844
+20014
+21902
+15389
+24169
+29553
+14032
+16076
+5035
+25992
+25029
+4317
+16615
+20427
+24495
+11357
+12509
+8751
+24526
+11103
+6514
+27064
+23387
+25860
+7862
+29519
+32038
+5185
+30944
+24886
+17154
+31396
+30740
+8150
+27337
+28106
+8701
+16534
+32519
+25090
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
new file mode 100644
index 000000000000..d351c8437d0a
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
@@ -0,0 +1,10 @@
+11637
+3799
+23116
+15091
+13022
+15840
+27029
+27563
+25641
+28703
--
2.32.0


2021-12-15 16:04:39

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 05/12] perf test: Add coresight test to check all threads get some data logged

From: Carsten Haitzler <[email protected]>

This adds a test and test scripts to check that all threads in the
target binary end up logging some kind of coresight aux data and that
they are not missing.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../coresight_thread_loop_check_tid_10.sh | 19 ++++
.../coresight_thread_loop_check_tid_2.sh | 19 ++++
.../coresight_thread_loop_check_tid_250.sh | 19 ++++
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../tools/coresight/thread_loop/Makefile | 29 +++++++
.../tools/coresight/thread_loop/thread_loop.c | 86 +++++++++++++++++++
6 files changed, 174 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c

diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
new file mode 100755
index 000000000000..283ad9facdee
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 10 Threads - Check TID
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="10 2000"
+DATV="check-tid-10th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+STDO="$DATD/perf-$TEST-$DATV.stdout"
+
+SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
+
+perf_dump_aux_tid_verify "$DATA" "$STDO"
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
new file mode 100755
index 000000000000..ce8ba534bba2
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 2 Threads - Check TID
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="2 4000"
+DATV="check-tid-2th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+STDO="$DATD/perf-$TEST-$DATV.stdout"
+
+SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
+
+perf_dump_aux_tid_verify "$DATA" "$STDO"
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
new file mode 100755
index 000000000000..cb14581c1e68
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
@@ -0,0 +1,19 @@
+#!/bin/sh -e
+# Coresight / Thread Loop 250 Threads - Check TID
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="thread_loop"
+. $(dirname $0)/lib/coresight.sh
+ARGS="250 100"
+DATV="check-tid-250th"
+DATA="$DATD/perf-$TEST-$DATV.data"
+STDO="$DATD/perf-$TEST-$DATV.stdout"
+
+SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
+
+perf_dump_aux_tid_verify "$DATA" "$STDO"
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index 723006ea827c..1edab729db76 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -5,7 +5,8 @@ include ../../../../../../tools/scripts/Makefile.arch
include ../../../../../../tools/scripts/utilities.mak

SUBDIRS = \
- asm_pure_loop
+ asm_pure_loop \
+ thread_loop

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
new file mode 100644
index 000000000000..424df4e8b0e6
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=thread_loop
+LIB=-pthread
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
new file mode 100644
index 000000000000..c0158fac7d0b
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+// Carsten Haitzler <[email protected]>, 2021
+
+// define this for gettid()
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/syscall.h>
+#ifndef SYS_gettid
+// gettid is 178 on arm64
+# define SYS_gettid 178
+#endif
+#define gettid() syscall(SYS_gettid)
+
+struct args {
+ unsigned int loops;
+ pthread_t th;
+ void *ret;
+};
+
+static void *thrfn(void *arg)
+{
+ struct args *a = arg;
+ int i = 0, len = a->loops;
+
+ if (getenv("SHOW_TID")) {
+ unsigned long long tid = gettid();
+
+ printf("%llu\n", tid);
+ }
+ asm volatile(
+ "loop:\n"
+ "add %[i], %[i], #1\n"
+ "cmp %[i], %[len]\n"
+ "blt loop\n"
+ : /* out */
+ : /* in */ [i] "r" (i), [len] "r" (len)
+ : /* clobber */
+ );
+ return (void *)(long)i;
+}
+
+static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
+{
+ pthread_t t;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_create(&t, &attr, fn, arg);
+ return t;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int i, len, thr;
+ pthread_t threads[256];
+ struct args args[256];
+
+ if (argc < 3) {
+ printf("ERR: %s [numthreads] [numloops (millions)]\n", argv[0]);
+ exit(1);
+ }
+
+ thr = atoi(argv[1]);
+ if ((thr < 1) || (thr > 256)) {
+ printf("ERR: threads 1-256\n");
+ exit(1);
+ }
+ len = atoi(argv[2]);
+ if ((len < 1) || (len > 4000)) {
+ printf("ERR: max loops 4000 (millions)\n");
+ exit(1);
+ }
+ len *= 1000000;
+ for (i = 0; i < thr; i++) {
+ args[i].loops = len;
+ args[i].th = new_thr(thrfn, &(args[i]));
+ }
+ for (i = 0; i < thr; i++)
+ pthread_join(args[i].th, &(args[i].ret));
+ return 0;
+}
--
2.32.0


2021-12-15 16:04:46

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 09/12] perf test: Add add memcpy test for coresight quality checking

From: Carsten Haitzler <[email protected]>

This adds memory bound tests for quality checking perf's aux data
recording.

Signed-off-by: Carsten Haitzler <[email protected]>
---
tools/perf/tests/shell/coresight_memcpy_1m.sh | 18 +++++++++
.../perf/tests/shell/coresight_memcpy_32m.sh | 18 +++++++++
.../perf/tests/shell/coresight_memcpy_64k.sh | 18 +++++++++
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../shell/tools/coresight/memcpy/Makefile | 29 ++++++++++++++
.../shell/tools/coresight/memcpy/memcpy.c | 40 +++++++++++++++++++
6 files changed, 125 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_memcpy_1m.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_32m.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_64k.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c

diff --git a/tools/perf/tests/shell/coresight_memcpy_1m.sh b/tools/perf/tests/shell/coresight_memcpy_1m.sh
new file mode 100755
index 000000000000..fa1c28d73b66
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_1m.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 1M
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy"
+. $(dirname $0)/lib/coresight.sh
+ARGS="1024 2"
+DATV="1m"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 39 766 766
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_32m.sh b/tools/perf/tests/shell/coresight_memcpy_32m.sh
new file mode 100755
index 000000000000..4ab5459e3824
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_32m.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 32M
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy"
+. $(dirname $0)/lib/coresight.sh
+ARGS="32768 1"
+DATV="32m"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 39 7804 7804
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_64k.sh b/tools/perf/tests/shell/coresight_memcpy_64k.sh
new file mode 100755
index 000000000000..5b6ba2a6d394
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_64k.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 64K
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy"
+. $(dirname $0)/lib/coresight.sh
+ARGS="64 40"
+DATV="64k"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 40 934 934
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index a1a752f45c46..99030c889b04 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -8,7 +8,8 @@ SUBDIRS = \
asm_pure_loop \
thread_loop \
bubble_sort \
- bubble_sort_thread
+ bubble_sort_thread \
+ memcpy

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/memcpy/Makefile b/tools/perf/tests/shell/tools/coresight/memcpy/Makefile
new file mode 100644
index 000000000000..7c31fe4ec399
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/memcpy/Makefile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=memcpy
+LIB=
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c b/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c
new file mode 100644
index 000000000000..1aa0617448ad
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+// Carsten Haitzler <[email protected]>, 2021
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ unsigned long i, len, size;
+ unsigned char *src, *dst;
+ long long v;
+
+ if (argc < 3) {
+ printf("ERR: %s [copysize Kb] [numloops (hundreds)]\n", argv[0]);
+ exit(1);
+ }
+
+ v = atoll(argv[1]);
+ if ((v < 1) || (v > (1024 * 1024))) {
+ printf("ERR: max memory 1GB (1048576 KB)\n");
+ exit(1);
+ }
+ size = v;
+ v = atoll(argv[2]);
+ if ((v < 1) || (v > 40000000000ll)) {
+ printf("ERR: loops 1-40000000000 (hundreds)\n");
+ exit(1);
+ }
+ len = v * 100;
+ src = malloc(size * 1024);
+ dst = malloc(size * 1024);
+ if ((!src) || (!dst)) {
+ printf("ERR: Can't allocate memory\n");
+ exit(1);
+ }
+ for (i = 0; i < len; i++)
+ memcpy(dst, src, size * 1024);
+ return 0;
+}
--
2.32.0


2021-12-15 16:04:51

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 11/12] perf test: Add unrolled loop tests for coresight aux data

From: Carsten Haitzler <[email protected]>

These tests have large batches of code manually unrolled with macros
to ensure that the processor has to walk through a lot of instructions
and memory for those instructions to generate the coresight aux data.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../shell/coresight_unroll_loop_thread_1.sh | 18 +++++
.../shell/coresight_unroll_loop_thread_10.sh | 18 +++++
.../shell/coresight_unroll_loop_thread_2.sh | 18 +++++
.../shell/coresight_unroll_loop_thread_25.sh | 18 +++++
.../shell/coresight_unroll_loop_thread_250.sh | 18 +++++
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../coresight/unroll_loop_thread/Makefile | 29 ++++++++
.../unroll_loop_thread/unroll_loop_thread.c | 74 +++++++++++++++++++
8 files changed, 195 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c

diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
new file mode 100755
index 000000000000..9175ec532bd8
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Unroll Loop Thread 1
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="unroll_loop_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="1"
+DATV="1"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 118 14 14
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
new file mode 100755
index 000000000000..66cf0245294e
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Unroll Loop Thread 10
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="unroll_loop_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="10"
+DATV="10"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 127 17 17
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
new file mode 100755
index 000000000000..ff2e293699b0
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Unroll Loop Thread 2
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="unroll_loop_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="2"
+DATV="2"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 65 6 6
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
new file mode 100755
index 000000000000..7d7669a797ab
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Unroll Loop Thread 25
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="unroll_loop_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="25"
+DATV="25"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 72 26 25
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
new file mode 100755
index 000000000000..7a0e23aff0dc
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Unroll Loop Thread 250
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="unroll_loop_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="250"
+DATV="250"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 544 2417 2417
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index be671aac06b8..b9cdeff1149b 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -10,7 +10,8 @@ SUBDIRS = \
bubble_sort \
bubble_sort_thread \
memcpy \
- memcpy_thread
+ memcpy_thread \
+ unroll_loop_thread

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
new file mode 100644
index 000000000000..45ab2be8be92
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=unroll_loop_thread
+LIB=-pthread
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c
new file mode 100644
index 000000000000..cb9d22c7dfb9
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+// Carsten Haitzler <[email protected]>, 2021
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+
+struct args {
+ pthread_t th;
+ unsigned int in, out;
+ void *ret;
+};
+
+static void *thrfn(void *arg)
+{
+ struct args *a = arg;
+ unsigned int i, in = a->in;
+
+ for (i = 0; i < 10000; i++) {
+ asm volatile (
+// force an unroll of thia add instruction so we can test long runs of code
+#define SNIP1 "add %[in], %[in], #1\n"
+// 10
+#define SNIP2 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1
+// 100
+#define SNIP3 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2
+// 1000
+#define SNIP4 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3
+// 10000
+#define SNIP5 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4
+// 100000
+ SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5
+ : /* out */
+ : /* in */ [in] "r" (in)
+ : /* clobber */
+ );
+ }
+}
+
+static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
+{
+ pthread_t t;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_create(&t, &attr, fn, arg);
+ return t;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int i, thr;
+ pthread_t threads[256];
+ struct args args[256];
+
+ if (argc < 2) {
+ printf("ERR: %s [numthreads]\n", argv[0]);
+ exit(1);
+ }
+
+ thr = atoi(argv[1]);
+ if ((thr > 256) || (thr < 1)) {
+ printf("ERR: threads 1-256\n");
+ exit(1);
+ }
+ for (i = 0; i < thr; i++) {
+ args[i].in = rand();
+ args[i].th = new_thr(thrfn, &(args[i]));
+ }
+ for (i = 0; i < thr; i++)
+ pthread_join(args[i].th, &(args[i].ret));
+ return 0;
+}
--
2.32.0


2021-12-15 16:04:52

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 10/12] perf test: Add threaded memcpy tests to check coresight aux data

From: Carsten Haitzler <[email protected]>

This adds threaded memcpy test looking at coresight aux data quality.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../shell/coresight_memcpy_thread_1m_2.sh | 18 +++++
.../shell/coresight_memcpy_thread_1m_25.sh | 18 +++++
.../shell/coresight_memcpy_thread_32m_10.sh | 18 +++++
.../shell/coresight_memcpy_thread_32m_2.sh | 18 +++++
.../shell/coresight_memcpy_thread_64k_2.sh | 18 +++++
.../shell/coresight_memcpy_thread_64k_25.sh | 18 +++++
.../shell/coresight_memcpy_thread_64k_250.sh | 18 +++++
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../tools/coresight/memcpy_thread/Makefile | 29 +++++++
.../coresight/memcpy_thread/memcpy_thread.c | 79 +++++++++++++++++++
10 files changed, 236 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_1m_2.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_1m_25.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_32m_10.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_32m_2.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_64k_2.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_64k_25.sh
create mode 100755 tools/perf/tests/shell/coresight_memcpy_thread_64k_250.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy_thread/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy_thread/memcpy_thread.c

diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_1m_2.sh b/tools/perf/tests/shell/coresight_memcpy_thread_1m_2.sh
new file mode 100755
index 000000000000..32d5ee94343a
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_1m_2.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 1M 2 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="1024 2 400"
+DATV="1m_2"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 125 26 26
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_1m_25.sh b/tools/perf/tests/shell/coresight_memcpy_thread_1m_25.sh
new file mode 100755
index 000000000000..6510f8c7df99
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_1m_25.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 1M 25 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="1024 25 1"
+DATV="1m_25"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 1 44 43
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_32m_10.sh b/tools/perf/tests/shell/coresight_memcpy_thread_32m_10.sh
new file mode 100755
index 000000000000..3715ed4b612e
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_32m_10.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 32M 10 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="32768 10 1"
+DATV="32m_10"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 6 36 36
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_32m_2.sh b/tools/perf/tests/shell/coresight_memcpy_thread_32m_2.sh
new file mode 100755
index 000000000000..ad57bf4d9c0c
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_32m_2.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 32M 2 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="32768 2 1"
+DATV="32m_2"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 3 12 12
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_64k_2.sh b/tools/perf/tests/shell/coresight_memcpy_thread_64k_2.sh
new file mode 100755
index 000000000000..282cc8922641
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_64k_2.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 64k 2 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="64 2 100"
+DATV="64k_2"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 66 11 11
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_64k_25.sh b/tools/perf/tests/shell/coresight_memcpy_thread_64k_25.sh
new file mode 100755
index 000000000000..05bc6c23f4a1
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_64k_25.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 64k 25 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="64 25 2"
+DATV="64k_25"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 118 31 31
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_memcpy_thread_64k_250.sh b/tools/perf/tests/shell/coresight_memcpy_thread_64k_250.sh
new file mode 100755
index 000000000000..aaf35e32f610
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_memcpy_thread_64k_250.sh
@@ -0,0 +1,18 @@
+#!/bin/sh -e
+# Coresight / Memcpy 64k 250 Threads
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="memcpy_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="64 250 1"
+DATV="64k_250"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 340 1878 1878
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index 99030c889b04..be671aac06b8 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -9,7 +9,8 @@ SUBDIRS = \
thread_loop \
bubble_sort \
bubble_sort_thread \
- memcpy
+ memcpy \
+ memcpy_thread

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/memcpy_thread/Makefile b/tools/perf/tests/shell/tools/coresight/memcpy_thread/Makefile
new file mode 100644
index 000000000000..e2604cfae74b
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/memcpy_thread/Makefile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=memcpy_thread
+LIB=-pthread
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/memcpy_thread/memcpy_thread.c b/tools/perf/tests/shell/tools/coresight/memcpy_thread/memcpy_thread.c
new file mode 100644
index 000000000000..a7e169d1bf64
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/memcpy_thread/memcpy_thread.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+// Carsten Haitzler <[email protected]>, 2021
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+
+struct args {
+ unsigned long loops;
+ unsigned long size;
+ pthread_t th;
+ void *ret;
+};
+
+static void *thrfn(void *arg)
+{
+ struct args *a = arg;
+ unsigned long i, len = a->loops;
+ unsigned char *src, *dst;
+
+ src = malloc(a->size * 1024);
+ dst = malloc(a->size * 1024);
+ if ((!src) || (!dst)) {
+ printf("ERR: Can't allocate memory\n");
+ exit(1);
+ }
+ for (i = 0; i < len; i++)
+ memcpy(dst, src, a->size * 1024);
+}
+
+static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
+{
+ pthread_t t;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_create(&t, &attr, fn, arg);
+ return t;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned long i, len, size, thr;
+ pthread_t threads[256];
+ struct args args[256];
+ long long v;
+
+ if (argc < 4) {
+ printf("ERR: %s [copysize Kb] [numthreads] [numloops (hundreds)]\n", argv[0]);
+ exit(1);
+ }
+
+ v = atoll(argv[1]);
+ if ((v < 1) || (v > (1024 * 1024))) {
+ printf("ERR: max memory 1GB (1048576 KB)\n");
+ exit(1);
+ }
+ size = v;
+ thr = atol(argv[2]);
+ if ((thr < 1) || (thr > 256)) {
+ printf("ERR: threads 1-256\n");
+ exit(1);
+ }
+ v = atoll(argv[3]);
+ if ((v < 1) || (v > 40000000000ll)) {
+ printf("ERR: loops 1-40000000000 (hundreds)\n");
+ exit(1);
+ }
+ len = v * 100;
+ for (i = 0; i < thr; i++) {
+ args[i].loops = len;
+ args[i].size = size;
+ args[i].th = new_thr(thrfn, &(args[i]));
+ }
+ for (i = 0; i < thr; i++)
+ pthread_join(args[i].th, &(args[i].ret));
+ return 0;
+}
--
2.32.0


2021-12-15 16:04:43

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 08/12] perf test: Add threaded bubblesort tests for coresight

From: Carsten Haitzler <[email protected]>

This adds threaded versions of the bubblesort test to check perf
produces sane/sufficient coresight aux data.

Signed-off-by: Carsten Haitzler <[email protected]>
---
.../coresight_bubble_sort_thread_random.sh | 20 +
.../coresight_bubble_sort_thread_small.sh | 20 +
.../perf/tests/shell/tools/coresight/Makefile | 3 +-
.../coresight/bubble_sort_thread/Makefile | 31 +
.../bubble_sort_thread/bubble_sort_thread.c | 136 +
.../bubble_sort_thread/random_array.txt | 30000 ++++++++++++++++
.../bubble_sort_thread/small_array.txt | 10 +
7 files changed, 30219 insertions(+), 1 deletion(-)
create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_thread_random.sh
create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_thread_small.sh
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort_thread/Makefile
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort_thread/bubble_sort_thread.c
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort_thread/random_array.txt
create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort_thread/small_array.txt

diff --git a/tools/perf/tests/shell/coresight_bubble_sort_thread_random.sh b/tools/perf/tests/shell/coresight_bubble_sort_thread_random.sh
new file mode 100755
index 000000000000..09f2e62aece1
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_bubble_sort_thread_random.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -e
+# Coresight / Bubblesort Thread Random Array
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="bubble_sort_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="$DIR/random_array.txt"
+DATV="random"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+echo $ARGS
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 2 7392 7392
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/coresight_bubble_sort_thread_small.sh b/tools/perf/tests/shell/coresight_bubble_sort_thread_small.sh
new file mode 100755
index 000000000000..6d4f0413be94
--- /dev/null
+++ b/tools/perf/tests/shell/coresight_bubble_sort_thread_small.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -e
+# Coresight / Bubblesort Thread Small Array
+
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+
+TEST="bubble_sort_thread"
+. $(dirname $0)/lib/coresight.sh
+ARGS="$DIR/small_array.txt"
+DATV="small"
+DATA="$DATD/perf-$TEST-$DATV.data"
+
+echo $ARGS
+
+perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
+
+perf_dump_aux_verify "$DATA" 90 7 7
+
+err=$?
+exit $err
diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
index 49fa80d28df4..a1a752f45c46 100644
--- a/tools/perf/tests/shell/tools/coresight/Makefile
+++ b/tools/perf/tests/shell/tools/coresight/Makefile
@@ -7,7 +7,8 @@ include ../../../../../../tools/scripts/utilities.mak
SUBDIRS = \
asm_pure_loop \
thread_loop \
- bubble_sort
+ bubble_sort \
+ bubble_sort_thread

all: $(SUBDIRS)
$(SUBDIRS):
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/Makefile b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/Makefile
new file mode 100644
index 000000000000..a7468e201ca2
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/Makefile
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0
+# Carsten Haitzler <[email protected]>, 2021
+include ../Makefile.miniconfig
+
+BIN=bubble_sort_thread
+LIB=-pthread
+
+all: $(BIN)
+
+$(BIN): $(BIN).c
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
+endif
+endif
+
+install-tests: all
+ifdef CORESIGHT
+ifeq ($(ARCH),arm64)
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
+ $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'; \
+ $(INSTALL) random_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/random_array.txt'; \
+ $(INSTALL) small_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/small_array.txt'
+endif
+endif
+
+clean:
+ $(Q)$(RM) -f $(BIN)
+
+.PHONY: all clean install-tests
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/bubble_sort_thread.c b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/bubble_sort_thread.c
new file mode 100644
index 000000000000..094bd8a82378
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/bubble_sort_thread.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+// Andrea Brunato <[email protected]>, 2021
+// Example taken from: https://gcc.gnu.org/wiki/AutoFDO/Tutorial
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <string.h> // memcpy
+#define _GNU_SOURCE /* See feature_test_macros(7) */
+#include <unistd.h>
+#include <sys/syscall.h>
+#define gettid() syscall(SYS_gettid)
+
+typedef struct payload_t {
+ int *array;
+ int size;
+} payload_t;
+
+
+int count_lines(FILE *fp)
+{
+ int lines_n = 0;
+ char c;
+
+ for (c = getc(fp); !feof(fp); c = getc(fp)) {
+ if (c == '\n')
+ lines_n = lines_n + 1;
+ }
+ fseek(fp, 0, SEEK_SET);
+#ifdef DEBUG
+ printf("Number of lines: %d\n", lines_n);
+#endif
+ return lines_n;
+}
+
+#ifdef DEBUG
+void print_array(int *arr, int size)
+{
+ int i;
+
+ assert(arr != NULL);
+ for (i = 0; i < size; i++)
+ printf("%d\n", arr[i]);
+}
+#endif
+
+void *bubble_sort(void *payload)
+{
+ payload_t *p = payload;
+ int *a = p->array;
+ int n = p->size;
+ int i, t, s = 1;
+
+ printf("Sorting from thread %ld\n", gettid());
+ while (s) {
+ s = 0;
+ for (i = 1; i < n; i++) {
+ if (a[i] < a[i - 1]) {
+ t = a[i];
+ a[i] = a[i - 1];
+ a[i - 1] = t;
+ s = 1;
+ }
+ }
+ }
+ return NULL;
+}
+
+void init_array(int *arr, int size, FILE *fp)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ fscanf(fp, "%d", &arr[i]);
+}
+
+int main(int argc, char **argv)
+{
+ int lines_n = 0, *arr = NULL, *arr2 = NULL;
+ pthread_t thread1, thread2;
+ FILE *fp;
+ payload_t *p1, *p2;
+
+ p1 = malloc(sizeof(payload_t));
+ p2 = malloc(sizeof(payload_t));
+ assert((p1 != NULL) && "Couldn't allocate payload\n");
+ assert((p2 != NULL) && "Couldn't allocate payload\n");
+
+ assert((argc == 2) && "Please specify an input file\n");
+
+ fp = fopen(argv[1], "r");
+ assert((fp != NULL) && "ERROR: Couldn't open the specified file\n");
+
+ // Input file expected formar: one number per line
+ lines_n = count_lines(fp);
+
+ // Allocate memory for the arrays
+ arr = malloc(sizeof(int) * lines_n);
+ arr2 = malloc(sizeof(int) * lines_n);
+ assert((arr2 != NULL) && "Couldn't allocate array\n");
+ assert((arr != NULL) && "Couldn't allocate array\n");
+
+ init_array(arr, lines_n, fp);
+ memcpy(arr2, arr, sizeof(int) * lines_n);
+
+ // Init the payload
+ p1->array = arr;
+ p1->size = lines_n;
+ p2->array = arr2;
+ p2->size = lines_n;
+
+ printf("Main thread tid is: %ld\n", gettid());
+
+ /* Create independent threads each of which will sort its own array */
+ pthread_create(&thread1, NULL, bubble_sort, p1);
+ pthread_create(&thread2, NULL, bubble_sort, p2);
+
+ // Let's wait for the threads to finish
+ pthread_join(thread1, NULL);
+ pthread_join(thread2, NULL);
+
+#ifdef DEBUG
+ print_array(p1->array, lines_n);
+ print_array(p2->array, lines_n);
+#endif
+
+ free(arr);
+ free(arr2);
+ free(p1);
+ free(p2);
+ fclose(fp);
+
+ return 0;
+}
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/random_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/random_array.txt
new file mode 100644
index 000000000000..682c82ffbe7f
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/random_array.txt
@@ -0,0 +1,30000 @@
+11637
+3799
+23116
+15091
+13022
+15840
+27029
+27563
+25641
+28703
+3017
+29923
+26998
+18230
+26864
+9139
+28431
+18283
+21315
+28167
+7700
+14798
+15512
+20470
+9237
+29921
+28395
+15057
+29819
+26831
+5926
+26653
+390
+2976
+21651
+410
+11429
+1828
+3534
+31091
+9141
+30892
+29619
+5033
+20585
+15413
+28673
+32517
+8875
+7509
+22159
+1482
+28926
+2748
+25246
+23677
+2712
+20332
+23615
+2481
+28581
+29728
+13726
+26364
+28074
+23534
+12120
+4130
+1307
+20009
+15225
+17469
+12076
+11899
+22886
+2854
+4667
+11494
+25057
+18590
+15010
+9295
+6603
+12891
+14441
+5499
+26880
+21390
+15932
+3975
+11242
+19063
+27555
+28538
+30148
+14592
+3360
+21049
+24923
+29681
+5157
+15595
+8863
+19992
+12588
+32711
+3077
+22132
+10031
+21685
+1634
+22046
+7323
+17925
+20453
+3694
+4502
+13543
+1959
+9365
+25814
+29540
+30414
+551
+32722
+23697
+32501
+9890
+13134
+2408
+21814
+1692
+8219
+27175
+19880
+1971
+17913
+10985
+75
+6275
+29139
+7104
+3241
+24809
+13310
+17897
+32684
+7199
+2015
+31825
+20985
+30466
+25403
+28839
+3939
+30171
+9223
+27181
+1302
+7945
+18902
+22094
+28959
+28100
+1874
+29613
+4804
+23941
+31981
+1874
+25476
+10176
+2004
+16080
+32404
+24472
+14217
+9647
+24917
+15001
+15559
+23867
+32520
+2545
+2233
+28869
+13685
+26640
+6548
+27395
+13590
+2851
+1008
+10772
+10417
+17257
+19706
+21757
+27627
+13514
+4631
+19162
+1138
+6325
+22136
+12944
+16124
+12359
+25197
+13024
+13459
+31896
+4661
+12648
+24619
+29975
+2417
+30526
+9880
+32733
+19252
+25646
+12851
+25535
+22792
+21622
+25256
+9785
+11252
+23999
+22965
+10221
+32537
+754
+6831
+11892
+4420
+12472
+20903
+18420
+14968
+17626
+25366
+27811
+6781
+15767
+19341
+28487
+28252
+1225
+31467
+10531
+29736
+12770
+11237
+26065
+9298
+9389
+4413
+25708
+4222
+206
+1952
+16927
+17411
+19671
+23966
+21346
+5232
+26240
+11465
+24782
+20600
+18201
+4713
+32313
+4899
+14371
+11307
+5277
+2022
+14443
+14631
+28140
+23499
+3955
+7565
+18082
+28583
+26049
+11652
+27835
+5415
+29742
+8307
+8380
+20582
+5376
+28696
+762
+6860
+8829
+3579
+2620
+14623
+26606
+31027
+8334
+5654
+15247
+25230
+8096
+1998
+11131
+25257
+31275
+18099
+22294
+9458
+17779
+22216
+4149
+22198
+172
+23793
+30710
+4351
+9939
+13985
+11652
+59
+26587
+9059
+26071
+20826
+3493
+32165
+10983
+29045
+28704
+29635
+19259
+15806
+15124
+18009
+20333
+17020
+1086
+13690
+32368
+14632
+15249
+31064
+18941
+9348
+9006
+31486
+4229
+26282
+24749
+11214
+12670
+5822
+23520
+7971
+28458
+28781
+15391
+28848
+1629
+30060
+19100
+27055
+6999
+7166
+31382
+12066
+15730
+23622
+17211
+30853
+15946
+7092
+5278
+14151
+29985
+2197
+3038
+17757
+14821
+11374
+16227
+7657
+29476
+7761
+6718
+5380
+3255
+28899
+507
+21354
+8942
+21928
+17282
+15106
+8035
+17251
+28354
+14675
+16033
+23012
+10270
+3609
+12387
+4083
+22608
+18438
+10363
+31842
+25456
+2993
+12567
+12285
+10847
+4036
+25889
+2263
+7521
+8246
+27332
+6281
+5934
+2057
+24322
+22014
+18625
+17420
+11120
+4933
+18486
+9201
+22355
+20027
+14665
+6106
+16764
+1955
+2674
+24517
+23913
+20392
+16961
+25273
+5622
+29187
+20339
+11895
+10335
+9094
+20758
+14115
+44
+29610
+29161
+14578
+30088
+22551
+9064
+19533
+428
+27047
+210
+7836
+24192
+18636
+32533
+4747
+1086
+23230
+6341
+31606
+8201
+29138
+28172
+11305
+1387
+25794
+23095
+2600
+1452
+8294
+15374
+31146
+18513
+11
+7897
+30819
+31
+11752
+32591
+27803
+26885
+7667
+31592
+10244
+24349
+17836
+25237
+21489
+9578
+6322
+5457
+15157
+15541
+19222
+12621
+21554
+22651
+12729
+10582
+10290
+10887
+23746
+26686
+1585
+10165
+31947
+19779
+15980
+20878
+28201
+26455
+10696
+19505
+29741
+1935
+2223
+28124
+17789
+24280
+25012
+11103
+6445
+10182
+22947
+31249
+12870
+25620
+9034
+28337
+17508
+12857
+32045
+23453
+18922
+29958
+13095
+27482
+1809
+13962
+15407
+23537
+28052
+24819
+7332
+29319
+11951
+7396
+0
+24126
+1573
+15203
+1194
+31509
+19366
+23180
+21698
+24946
+14946
+8384
+30229
+10099
+5060
+23938
+12575
+7220
+29396
+25422
+22865
+3935
+31126
+14275
+9741
+25019
+26108
+8997
+29459
+5595
+14307
+22680
+13453
+23456
+1218
+889
+11412
+22111
+15488
+16512
+24954
+25449
+14049
+10795
+6430
+7939
+23312
+8849
+4246
+3910
+3920
+8279
+29146
+23176
+29495
+22478
+22801
+15464
+1404
+24320
+9644
+24047
+6372
+25831
+10546
+25452
+162
+12526
+10816
+2805
+12098
+18199
+22284
+2588
+632
+23869
+9515
+18597
+5439
+11016
+19721
+14495
+5671
+3879
+9479
+13968
+25634
+12409
+8940
+1133
+25751
+6666
+19636
+3114
+18339
+27366
+24370
+31234
+24247
+27662
+16433
+9814
+13447
+20513
+18877
+26999
+18659
+27305
+15751
+17192
+11982
+31198
+11367
+20537
+6868
+9125
+26707
+28962
+4645
+22880
+29957
+21981
+29763
+10879
+15307
+21373
+652
+471
+6426
+15176
+11717
+8774
+21421
+22152
+11363
+21204
+8266
+30627
+3237
+17767
+9548
+31154
+26199
+11867
+2590
+508
+5685
+9562
+4680
+3527
+21332
+29853
+4331
+26626
+5804
+8806
+30680
+11836
+2053
+13250
+18750
+12811
+3459
+18921
+14531
+11448
+4381
+19024
+7032
+10599
+19932
+23346
+21110
+31736
+5792
+10309
+407
+6914
+19374
+11265
+15050
+30440
+14511
+16243
+19207
+25865
+3421
+8436
+17959
+30839
+28976
+22855
+1350
+5242
+4582
+19248
+4215
+10734
+29691
+1157
+5396
+5088
+30686
+24674
+29795
+20935
+12005
+1845
+20897
+25337
+27343
+27057
+11172
+23295
+28899
+2790
+15386
+30010
+3736
+22563
+13654
+32418
+3320
+9260
+4893
+1352
+897
+24116
+27410
+7866
+32310
+19354
+2760
+3243
+30622
+26854
+1810
+28332
+6230
+2049
+10362
+12110
+19718
+1304
+17994
+19655
+16923
+9017
+17840
+19894
+9328
+22423
+11185
+18453
+985
+14984
+31486
+2702
+7584
+20132
+5354
+22683
+27453
+15499
+8065
+9823
+29909
+31059
+23496
+32412
+31828
+3667
+13160
+5790
+11816
+31151
+6194
+16912
+20180
+32485
+10858
+28523
+9886
+10689
+1200
+26441
+2446
+10208
+4201
+649
+19694
+21476
+30880
+8900
+9817
+19507
+27582
+16013
+27193
+4177
+29851
+5791
+22262
+28816
+8540
+23328
+26992
+28046
+19652
+2195
+2694
+5634
+7430
+6356
+25759
+17606
+25591
+9758
+17330
+7393
+20057
+31341
+24765
+29760
+20556
+31406
+24439
+16953
+30044
+8448
+19044
+15593
+11764
+10639
+10535
+7469
+13865
+1039
+11436
+1319
+4999
+17500
+13796
+24842
+29723
+24282
+27361
+30792
+32410
+23984
+1667
+8323
+8491
+13317
+388
+9755
+28091
+19517
+29286
+23245
+4345
+9550
+18217
+31425
+17815
+6570
+7935
+6310
+550
+11700
+23011
+25532
+6854
+103
+6814
+15256
+6215
+122
+32352
+10646
+641
+4857
+16185
+26396
+6434
+14595
+6690
+29538
+25092
+16330
+15523
+5603
+8869
+19911
+4792
+12133
+27733
+23723
+32383
+1051
+10146
+8913
+6907
+4710
+6920
+27069
+15176
+17705
+13502
+17262
+7841
+12984
+29694
+21297
+2230
+10199
+24639
+9762
+9313
+5847
+18081
+9873
+14930
+5548
+953
+4307
+24255
+3720
+22293
+18312
+21097
+15784
+60
+4343
+2003
+26727
+26292
+24345
+6251
+28117
+25523
+15836
+31525
+32079
+8277
+31309
+8216
+15472
+9717
+10462
+10504
+27278
+12602
+13757
+11568
+26986
+22193
+18985
+334
+11
+675
+23098
+13090
+10232
+24131
+24210
+32671
+23747
+9766
+13959
+30837
+8515
+31295
+2313
+24877
+10020
+30433
+22083
+3478
+7941
+18436
+14792
+17040
+12004
+13669
+15490
+16678
+23356
+28066
+26871
+25077
+23461
+21786
+27509
+27367
+14961
+2380
+1662
+32487
+19835
+6455
+15376
+614
+9477
+10695
+28054
+28624
+31433
+17214
+30103
+22748
+32392
+26740
+20452
+19781
+17204
+18886
+2597
+16593
+833
+32064
+17379
+17717
+25184
+19581
+19423
+26962
+23824
+25178
+12322
+15802
+17619
+10654
+32343
+17037
+25858
+17284
+20361
+31406
+28206
+17839
+8121
+29850
+28389
+17970
+11480
+16044
+27103
+32676
+9884
+7189
+18612
+27375
+13011
+25248
+8624
+27167
+16913
+17033
+28474
+8431
+28770
+32216
+18027
+25686
+1292
+5509
+6894
+12620
+21287
+24917
+26323
+28448
+23047
+12968
+24616
+3809
+29518
+9663
+24553
+29202
+14835
+21220
+6785
+12761
+21624
+19053
+25295
+15607
+15236
+30405
+13704
+5130
+29608
+26410
+15114
+19041
+21133
+467
+24536
+10935
+2035
+14883
+8947
+22955
+13146
+9581
+29738
+19553
+7607
+125
+25092
+5985
+7843
+1713
+10628
+25470
+10901
+19348
+14538
+29719
+15625
+18293
+1742
+4258
+18738
+16429
+3453
+21625
+30091
+18119
+32643
+4672
+27135
+2571
+3211
+9096
+24942
+14666
+21660
+28962
+8376
+27399
+15822
+31049
+24155
+20515
+1979
+16109
+4627
+21804
+30092
+334
+18524
+11833
+20560
+28614
+29904
+21991
+23488
+20411
+11622
+15031
+2605
+21713
+7213
+7527
+11539
+27664
+26088
+569
+4311
+20104
+28409
+20140
+19522
+9077
+10930
+18157
+16787
+25216
+31867
+15602
+23801
+7375
+126
+9909
+32501
+19906
+19960
+7843
+8081
+9047
+22998
+5138
+21896
+32155
+32038
+291
+26500
+17796
+3376
+5274
+17693
+16263
+1929
+27670
+17073
+4405
+31778
+14877
+27450
+32036
+32068
+18642
+30320
+25415
+9179
+13420
+22419
+11277
+9943
+11543
+2342
+18245
+21913
+28469
+14693
+27338
+15644
+18322
+2936
+12075
+26487
+32264
+7399
+14240
+15771
+24509
+18825
+24192
+31505
+26939
+30511
+461
+1128
+112
+24820
+1294
+11189
+20272
+8069
+12934
+9509
+19741
+29200
+15054
+28557
+25545
+16865
+27595
+9225
+28484
+31668
+5411
+23119
+10962
+27218
+25619
+29940
+3622
+1066
+11964
+31472
+20788
+23492
+24322
+8570
+11716
+22958
+29473
+16120
+23711
+6619
+19457
+29281
+27719
+244
+23114
+28056
+26593
+9480
+27710
+31837
+32069
+4026
+9879
+9042
+32608
+6795
+27340
+6852
+883
+20682
+18656
+7122
+15695
+13991
+16284
+29566
+6121
+6020
+31946
+29874
+31744
+1946
+22451
+25898
+23162
+9393
+3941
+3448
+32753
+22040
+29576
+14181
+5697
+22569
+11246
+21344
+2891
+13406
+24146
+390
+10703
+8579
+25655
+2793
+4943
+30009
+9639
+18977
+24143
+18134
+19731
+14156
+1232
+8084
+383
+30027
+15069
+9746
+1381
+778
+25038
+28997
+11532
+13229
+23991
+28602
+28324
+28633
+21528
+13926
+7710
+4674
+28146
+31878
+30140
+24761
+26088
+10278
+9298
+19222
+26857
+23429
+19972
+14196
+27217
+12954
+30148
+17750
+19522
+21466
+21660
+11011
+32207
+22585
+14840
+3521
+10587
+22146
+4859
+17064
+31390
+28883
+23549
+28312
+116
+5260
+19196
+6555
+22381
+29286
+19461
+9586
+10974
+5676
+32061
+26244
+1874
+19439
+5705
+20417
+25687
+23385
+29016
+3201
+5790
+15781
+21509
+19756
+23127
+23924
+10464
+22550
+26144
+29604
+20089
+11870
+16496
+20640
+27227
+22890
+23413
+7918
+22186
+30532
+23574
+1646
+25828
+315
+31698
+13637
+31893
+25564
+13690
+14596
+32347
+23953
+1829
+19971
+23093
+5300
+29371
+10063
+1129
+21488
+22779
+8333
+24487
+27310
+30552
+21547
+723
+10370
+13546
+4082
+8682
+13208
+5546
+31993
+27919
+16801
+20501
+20527
+4578
+20495
+23257
+5340
+21509
+26646
+19661
+26958
+13559
+419
+11644
+26349
+32524
+11124
+31548
+26106
+15439
+13550
+17329
+17758
+19741
+1020
+17659
+29331
+18736
+6154
+26313
+28267
+2627
+29486
+29044
+5708
+5702
+31775
+7941
+9466
+30057
+7336
+2555
+28935
+12294
+4047
+13739
+15228
+30671
+25563
+4206
+21361
+22280
+475
+6302
+20412
+26433
+952
+26151
+20481
+19452
+18371
+8940
+20951
+17110
+13156
+4703
+31059
+25482
+7312
+3673
+17124
+18114
+4580
+17464
+1390
+20398
+31910
+10008
+26001
+27332
+16160
+4857
+24098
+13238
+13060
+3120
+24159
+29069
+10728
+28482
+5384
+3942
+7447
+6547
+19071
+3039
+13274
+20428
+9912
+18337
+19645
+22585
+24266
+16901
+2802
+14553
+30885
+30400
+32399
+6435
+29473
+20710
+28030
+8862
+1808
+27159
+18300
+31619
+11378
+7340
+338
+27066
+27540
+24851
+23453
+30335
+11332
+27409
+25216
+6464
+3600
+31313
+6494
+17896
+19375
+2169
+30255
+10571
+22434
+1402
+12939
+6410
+1089
+1078
+14455
+23491
+3051
+4024
+6072
+28925
+19218
+11802
+23003
+4122
+23330
+21650
+1085
+1812
+31021
+11195
+17798
+11999
+23012
+15104
+10956
+890
+24979
+9399
+16561
+432
+7010
+5096
+5997
+20666
+10967
+11989
+24193
+14253
+28125
+1741
+11372
+14820
+1120
+31350
+11628
+25363
+17657
+3996
+2792
+22729
+7050
+10487
+10522
+13410
+17034
+5294
+26133
+5995
+20262
+1747
+18778
+26293
+17222
+23151
+28805
+28665
+4636
+14509
+11355
+12011
+7781
+21985
+29915
+29324
+6290
+15154
+29132
+11290
+522
+5120
+20375
+25145
+11202
+29750
+15947
+26516
+22990
+7319
+20231
+10644
+27608
+21434
+32345
+18927
+6568
+9749
+31987
+23632
+21696
+9666
+2040
+2134
+2242
+5559
+27430
+20952
+192
+31554
+18837
+11816
+30277
+25451
+21547
+2541
+25816
+29475
+16232
+1700
+19817
+21906
+14691
+12591
+18044
+8909
+25202
+27953
+23172
+22914
+6804
+14234
+12636
+20760
+21866
+31846
+17844
+20014
+21902
+15389
+24169
+29553
+14032
+16076
+5035
+25992
+25029
+4317
+16615
+20427
+24495
+11357
+12509
+8751
+24526
+11103
+6514
+27064
+23387
+25860
+7862
+29519
+32038
+5185
+30944
+24886
+17154
+31396
+30740
+8150
+27337
+28106
+8701
+16534
+32519
+25090
+18917
+6096
+8108
+3689
+27190
+16269
+27215
+9647
+12053
+25736
+26970
+24741
+14855
+17132
+13248
+12600
+8799
+15948
+16470
+31117
+28014
+626
+16452
+20527
+26447
+13140
+7837
+32474
+19058
+8740
+8220
+24612
+32632
+16364
+29509
+4185
+26093
+1945
+29385
+2234
+9617
+8136
+24481
+26662
+28378
+28758
+20335
+8995
+10653
+7919
+12685
+31479
+17154
+25
+5288
+17030
+6037
+25406
+16329
+21709
+13461
+17519
+32117
+11628
+15387
+23557
+2455
+19500
+1576
+23029
+9321
+15847
+25528
+31660
+30499
+16405
+20677
+25010
+12967
+7718
+2994
+2167
+27450
+23463
+21967
+22380
+8237
+12022
+15549
+23201
+7756
+15246
+17037
+28764
+32183
+12625
+30247
+21179
+18709
+10171
+4163
+31914
+18140
+26620
+32655
+16235
+24044
+2472
+8266
+11851
+2083
+28829
+5239
+26108
+21321
+6898
+9690
+25756
+29074
+30546
+17660
+7827
+31932
+28992
+20779
+2138
+6736
+6339
+32192
+7567
+24752
+4848
+1580
+31091
+12895
+11987
+18673
+3482
+16217
+16572
+8652
+9296
+12028
+26615
+24906
+32573
+14605
+9713
+20348
+4806
+16382
+4606
+1978
+2799
+10813
+24549
+31998
+12798
+19121
+24429
+17978
+12772
+11512
+29926
+232
+17086
+2036
+26210
+20954
+314
+22422
+31374
+7865
+10557
+9580
+4246
+15646
+18085
+8631
+20867
+6606
+29832
+17751
+29590
+14223
+15046
+18489
+27077
+12125
+9286
+9818
+15142
+29978
+9481
+8168
+5392
+2581
+15141
+9978
+10319
+12066
+10945
+7398
+30471
+17371
+1638
+14353
+10110
+26747
+8000
+22859
+30931
+7616
+20937
+7587
+29527
+920
+8259
+19290
+21921
+29099
+26576
+23040
+23309
+23157
+26172
+5839
+15156
+10917
+22846
+10157
+9129
+27277
+3815
+473
+834
+8502
+11218
+16546
+30551
+11242
+18699
+19117
+30598
+15448
+1537
+1845
+891
+15996
+724
+20717
+14319
+25458
+31561
+14092
+9718
+1259
+10744
+13287
+24419
+13149
+16799
+24685
+18223
+4132
+30815
+204
+6260
+3622
+7560
+29554
+29072
+21487
+12562
+25849
+14131
+6953
+15913
+10603
+25053
+11343
+8014
+31444
+17766
+28011
+16707
+20429
+30818
+8422
+1120
+30497
+28187
+20668
+2245
+4526
+27098
+7315
+10194
+32119
+17450
+28879
+30834
+12151
+26564
+12110
+27378
+26557
+31748
+18414
+6825
+4855
+22054
+30752
+16702
+3005
+25605
+16100
+9929
+1870
+24674
+5499
+3974
+17819
+723
+4462
+10122
+12
+26231
+18907
+7387
+8407
+17184
+7887
+1314
+8932
+28317
+16638
+10047
+20341
+15819
+7077
+8670
+15065
+20841
+26407
+28152
+4527
+14990
+1277
+20691
+9616
+26016
+14822
+29566
+12821
+19937
+5373
+4796
+16804
+12063
+23781
+4295
+10664
+4540
+3672
+28113
+31759
+28475
+19261
+27864
+31180
+26341
+2526
+29649
+29796
+11346
+24630
+21801
+14308
+9048
+11983
+23532
+4393
+17042
+13955
+95
+10526
+18476
+24293
+18060
+23599
+15423
+28291
+12751
+11493
+13882
+17863
+14580
+22508
+26333
+26507
+12368
+9176
+3960
+17709
+20191
+16845
+11999
+1078
+4694
+4115
+7973
+32161
+32726
+28121
+31926
+13478
+10558
+27682
+28046
+20800
+27201
+5624
+2947
+29258
+8366
+11725
+4449
+10213
+32217
+2758
+4368
+425
+22978
+1640
+27730
+22674
+13615
+29959
+23043
+19139
+8273
+27546
+3592
+26280
+28111
+31338
+5545
+14295
+18376
+30967
+20928
+29234
+32284
+4048
+30622
+19573
+14233
+23538
+6409
+24088
+20546
+22243
+9002
+14951
+24524
+6843
+8087
+16616
+31885
+23736
+1205
+13467
+25377
+20512
+8036
+6406
+3606
+28102
+9126
+7996
+19711
+20482
+25252
+13738
+1402
+15426
+19202
+12532
+3427
+4990
+24417
+7789
+12946
+21078
+21792
+741
+20359
+24314
+11042
+2490
+20768
+16304
+22837
+17853
+14548
+15964
+10302
+13756
+31889
+25183
+4213
+14872
+22450
+1153
+24812
+22437
+14015
+30384
+27742
+12603
+30308
+26276
+19367
+31352
+12349
+20843
+8515
+31111
+16217
+15695
+17575
+28478
+7939
+9210
+4542
+4866
+13344
+25625
+29687
+31230
+20165
+2295
+28126
+9834
+9340
+2931
+21509
+16137
+1636
+11829
+15490
+22237
+6191
+28465
+14339
+3063
+10263
+16320
+8809
+20404
+23893
+20665
+31419
+21568
+1951
+4533
+10159
+6392
+5587
+356
+28252
+4407
+26808
+11829
+30180
+29493
+24595
+14121
+9156
+20897
+30629
+16754
+274
+31535
+31495
+24957
+32504
+28821
+7703
+10027
+13253
+4318
+14816
+19678
+20441
+3339
+7283
+29575
+21894
+10701
+10341
+19702
+29182
+14176
+9544
+22630
+25917
+20801
+8498
+11850
+8645
+18330
+28654
+5714
+9756
+21204
+32590
+10356
+9986
+13235
+32625
+5160
+31118
+3246
+19775
+3975
+4410
+17911
+8872
+29165
+17485
+19384
+28868
+11966
+32232
+20373
+1492
+24353
+6050
+21091
+7198
+10315
+11320
+19774
+16273
+1685
+21004
+24069
+15555
+21275
+19149
+8422
+9328
+21826
+8288
+8832
+24615
+23197
+14512
+19976
+16819
+29217
+4359
+9270
+5109
+26760
+26111
+29313
+9843
+6004
+26325
+25589
+14071
+20383
+9224
+20580
+7696
+30157
+844
+16836
+31012
+31485
+21655
+18150
+21852
+19598
+19225
+30945
+8966
+5294
+31490
+28699
+15005
+26081
+17953
+20999
+7883
+16764
+22993
+22108
+3814
+17412
+12505
+17805
+32688
+18949
+18101
+23014
+11845
+23919
+24692
+11132
+4883
+1448
+6618
+25644
+12991
+20352
+9740
+32097
+12892
+25501
+32702
+26577
+28082
+4550
+5706
+7741
+32125
+28083
+12171
+7017
+10329
+4752
+20768
+13125
+9373
+26767
+15584
+27435
+10331
+9889
+14582
+29150
+19993
+30986
+17012
+7200
+7730
+909
+26012
+1004
+14011
+31052
+13612
+2072
+1418
+19376
+20202
+13025
+32036
+1462
+5550
+5470
+9140
+14496
+26135
+5774
+26738
+13551
+30933
+7437
+6488
+1464
+7948
+756
+4834
+30292
+14400
+16931
+23425
+12456
+3442
+3963
+5025
+31977
+23059
+21449
+31697
+133
+14957
+3771
+26842
+32383
+1125
+14928
+13027
+7187
+21176
+23244
+15369
+10942
+17572
+15498
+24327
+28510
+12327
+30543
+5040
+22319
+30952
+32257
+16005
+21904
+8171
+23458
+3425
+9247
+18275
+27473
+26256
+12344
+24686
+838
+18084
+22324
+19433
+25118
+19539
+8161
+9202
+5289
+4712
+4554
+16362
+23543
+1796
+14263
+30126
+10863
+4245
+26732
+18287
+28044
+19751
+28271
+25789
+3525
+19879
+20975
+29936
+32690
+8183
+18804
+11460
+10887
+14075
+30114
+14368
+32430
+30171
+10144
+18885
+22455
+20678
+11217
+20106
+31526
+22850
+14696
+6225
+14847
+16812
+15252
+10137
+30100
+1738
+5638
+5177
+32268
+32042
+28785
+18204
+17775
+14632
+19616
+16724
+16851
+8599
+5565
+31457
+3628
+5005
+14938
+13877
+29263
+24931
+24044
+28443
+3482
+18147
+15045
+31120
+2771
+31893
+22907
+26799
+4257
+27212
+26056
+28102
+8988
+11310
+10822
+13521
+19959
+13116
+22470
+18438
+14590
+19103
+13008
+6123
+28011
+19770
+18981
+4419
+30000
+28616
+31466
+23398
+10225
+29671
+5747
+32515
+20086
+17374
+28669
+814
+2973
+15665
+10166
+30926
+21837
+28524
+30703
+3832
+25068
+32095
+8472
+318
+22697
+25887
+13467
+24349
+13845
+25530
+30335
+25525
+8821
+23714
+11607
+32163
+12318
+22751
+19610
+17487
+29679
+10216
+11274
+4517
+9763
+499
+10945
+3647
+1908
+1529
+27301
+6043
+26590
+24304
+5531
+10104
+4117
+4293
+21466
+17445
+8172
+3218
+28083
+11724
+2467
+1662
+5783
+18129
+31904
+10955
+7685
+4629
+19734
+8345
+15678
+29602
+21789
+15727
+6812
+12352
+26525
+10677
+19286
+17473
+22039
+14099
+4170
+12867
+5023
+27539
+15220
+30987
+30260
+6513
+9687
+31990
+15852
+796
+21574
+24287
+16683
+14052
+32558
+19735
+20459
+10603
+22898
+9738
+13247
+27520
+25055
+12409
+9438
+15760
+5616
+29556
+7642
+10281
+30157
+6240
+30714
+4155
+16416
+18048
+7740
+14370
+7631
+9954
+31070
+25357
+5329
+21001
+7814
+7775
+5187
+28173
+19759
+30226
+26392
+6196
+22472
+19529
+32270
+29060
+19593
+27751
+12430
+24998
+1679
+19707
+20136
+16452
+30986
+18867
+25037
+9332
+29583
+27263
+32158
+24522
+28017
+14601
+20697
+9742
+1617
+26864
+16126
+23564
+29354
+8651
+28037
+29745
+32084
+29200
+9503
+15499
+6264
+3778
+975
+15467
+16202
+19068
+14281
+13383
+21792
+800
+28672
+17407
+27083
+20069
+32584
+10414
+27388
+25657
+13872
+22697
+25564
+17755
+30303
+2120
+31445
+26812
+14932
+7235
+4290
+23150
+12630
+12841
+27754
+99
+3885
+31254
+32519
+20862
+21323
+324
+18527
+10277
+13492
+25487
+990
+12319
+7100
+7198
+5456
+31701
+12904
+32569
+5826
+26291
+10916
+11339
+11173
+767
+21616
+12558
+17521
+5917
+9125
+32503
+25211
+18928
+21295
+32327
+12039
+5363
+11582
+8035
+21181
+18034
+11266
+27653
+27112
+21102
+715
+9862
+21716
+30274
+11420
+27943
+22437
+18346
+11057
+16688
+2230
+9766
+19157
+2638
+20452
+10963
+23911
+27622
+27955
+27449
+10904
+12991
+14613
+20089
+9438
+8589
+32120
+29831
+32754
+17810
+5393
+22342
+27632
+31503
+22398
+22354
+26090
+5065
+16153
+11668
+30857
+13880
+29434
+6195
+4226
+2522
+30570
+10024
+26453
+18274
+9700
+18837
+4910
+195
+19405
+19184
+8328
+28634
+4231
+23106
+20892
+4232
+3542
+4052
+32125
+20560
+23279
+17433
+26660
+13700
+15271
+11361
+25872
+21522
+8503
+26339
+7733
+30584
+8918
+19415
+28015
+25508
+22704
+23645
+13725
+2513
+10364
+13134
+2393
+21034
+31448
+8951
+10830
+8198
+6240
+4454
+29431
+32310
+26144
+6713
+17298
+32440
+16252
+3096
+19859
+17296
+27242
+32247
+16534
+24487
+71
+610
+8648
+32033
+10187
+12858
+14862
+8752
+23360
+2712
+21779
+32389
+31344
+1144
+10248
+183
+9088
+22621
+32369
+27587
+7480
+3488
+24513
+18188
+7114
+15294
+21598
+4565
+22990
+10918
+7344
+7311
+5325
+29859
+6666
+21647
+11511
+16561
+21371
+20934
+19438
+18669
+4704
+6073
+9562
+2184
+27864
+11285
+28485
+23221
+22374
+9564
+28785
+11284
+32612
+14317
+30304
+25771
+29511
+25017
+179
+4800
+13858
+11442
+166
+26988
+31609
+3231
+25364
+29553
+12148
+2703
+23637
+2971
+17136
+14372
+28517
+141
+31354
+5173
+25951
+3767
+21171
+11060
+13637
+3886
+25532
+7557
+9343
+26572
+23209
+14389
+24017
+27608
+24096
+20067
+8915
+29691
+15957
+6895
+4535
+20827
+24584
+1439
+19127
+21272
+8253
+25059
+22220
+11576
+27389
+16300
+32174
+28839
+3804
+23982
+27297
+18990
+26351
+2292
+27243
+19380
+18804
+6851
+10981
+22633
+1928
+17881
+28022
+14251
+24671
+8563
+12600
+10869
+12821
+16528
+20714
+28994
+22171
+9609
+3319
+25133
+5792
+8239
+7844
+31616
+12038
+27743
+680
+6056
+21196
+7049
+24415
+5262
+12303
+23107
+15794
+13068
+4729
+5887
+29539
+7499
+19310
+20992
+16361
+3542
+13851
+25434
+26070
+26695
+16469
+26417
+29452
+17339
+29616
+17555
+16521
+3940
+10740
+5479
+19513
+1872
+28449
+32350
+10604
+19697
+843
+20665
+22815
+14217
+24424
+31711
+14302
+29341
+25447
+13787
+25836
+8295
+30799
+13838
+6642
+31824
+1942
+15065
+17905
+11662
+31334
+29078
+30685
+1674
+6744
+22505
+8080
+29234
+23626
+21984
+6882
+15930
+9108
+3084
+2079
+20316
+30767
+10356
+379
+32714
+664
+4048
+16021
+29096
+10229
+27820
+22650
+31153
+9271
+18113
+18734
+17049
+6821
+26081
+23846
+8116
+9675
+27295
+5244
+4517
+5067
+5364
+30597
+27900
+16115
+8097
+9997
+4419
+28062
+23288
+3121
+7744
+21537
+392
+20059
+4350
+16080
+3975
+12000
+9041
+21452
+5966
+8101
+15392
+3911
+22531
+2670
+30255
+13304
+11511
+25333
+25254
+11904
+8596
+11152
+13879
+9810
+5918
+23623
+2823
+21282
+32338
+1551
+6136
+29283
+24374
+11072
+9961
+25751
+6446
+15622
+8993
+3950
+21474
+14379
+16214
+30025
+21275
+21811
+15982
+23340
+32630
+27659
+27753
+893
+21129
+28189
+25795
+28879
+29955
+23670
+3501
+1121
+18840
+21505
+26019
+25278
+30763
+29173
+26047
+13697
+20396
+21222
+20376
+24198
+30973
+22383
+5603
+5450
+26683
+21643
+6163
+15098
+11178
+24326
+23881
+8213
+381
+32034
+25076
+31137
+28709
+21599
+1561
+32024
+29061
+5191
+6183
+18536
+29798
+7946
+26263
+26502
+24789
+3812
+15628
+1060
+10719
+4849
+25652
+24357
+9407
+18364
+25120
+23275
+11070
+4665
+13801
+7614
+25873
+27197
+10561
+3447
+20384
+19827
+1898
+24147
+26542
+9411
+12496
+199
+20401
+5595
+14145
+18359
+28442
+27818
+10757
+21133
+20187
+20718
+5155
+25494
+12722
+16564
+8475
+15724
+13384
+15459
+17859
+13264
+26571
+28673
+8798
+6957
+21503
+22001
+4019
+21856
+18810
+6394
+4301
+19324
+31835
+809
+10622
+25910
+3870
+10902
+5812
+10841
+32586
+6277
+7885
+19123
+31414
+31395
+8505
+25918
+3186
+14177
+26650
+17176
+5804
+16904
+29479
+12362
+7662
+6348
+9939
+1964
+21408
+24836
+1478
+11304
+9920
+15277
+61
+21033
+17707
+19988
+24673
+7693
+1790
+17094
+9656
+3060
+25419
+9640
+28511
+5905
+6674
+24752
+6066
+23632
+10437
+17138
+15644
+13338
+17077
+13876
+15872
+3952
+17533
+2471
+2185
+30901
+28946
+32503
+19165
+5887
+32361
+30597
+25607
+17825
+4440
+31880
+6414
+11838
+4320
+1464
+10698
+16475
+16495
+976
+9914
+13633
+5711
+27737
+6567
+27291
+14619
+22204
+4755
+12167
+7747
+32087
+6269
+21717
+6068
+24169
+24131
+23572
+32575
+9498
+3074
+31674
+19941
+10058
+9744
+11132
+3692
+30134
+21615
+29297
+5238
+11034
+23853
+31918
+12528
+6391
+8105
+19746
+6292
+16935
+25932
+8164
+26881
+2990
+731
+21794
+22130
+13074
+8136
+19418
+32593
+23126
+6774
+23913
+19080
+18687
+3095
+23511
+8307
+13942
+22372
+7979
+32673
+24400
+14225
+21862
+22444
+623
+30644
+31851
+2882
+29252
+1364
+1578
+31692
+15637
+1135
+20485
+18970
+7380
+21380
+19128
+14949
+29571
+25007
+27692
+5889
+1026
+18025
+26084
+6825
+29778
+30542
+31840
+13178
+24311
+26866
+12993
+27241
+12453
+16296
+27501
+5716
+10284
+15112
+24405
+25558
+17718
+10256
+29237
+17085
+11816
+4821
+14588
+32365
+898
+3698
+9888
+30328
+6568
+2047
+16442
+20531
+743
+22824
+2000
+5707
+23736
+28203
+6729
+30196
+12254
+19028
+8870
+24488
+14355
+4825
+15006
+31303
+10320
+17801
+21315
+10367
+26395
+24193
+6434
+13195
+13188
+18454
+29884
+6146
+20101
+14697
+23131
+22517
+17272
+19643
+12818
+4786
+10756
+9566
+24106
+26536
+6612
+27673
+14847
+19829
+24394
+16213
+658
+32574
+25853
+17820
+15414
+17742
+21987
+22626
+14327
+3012
+8859
+12439
+12374
+32527
+23711
+2566
+12319
+1319
+31565
+18210
+20235
+7273
+32669
+21333
+5080
+31269
+18484
+1757
+26874
+6811
+791
+11438
+4886
+18282
+14802
+14102
+24676
+8636
+2271
+2193
+10937
+6988
+22602
+15790
+8362
+15411
+29633
+15235
+13552
+17825
+10106
+5531
+17686
+25470
+2987
+23886
+23928
+11135
+28776
+4412
+13024
+13153
+17126
+22370
+12510
+948
+26890
+24948
+10830
+6020
+5621
+17548
+1352
+23811
+12991
+23002
+19947
+13269
+2749
+12938
+23666
+31789
+8028
+32372
+9520
+11361
+20617
+1734
+20959
+22501
+7766
+26304
+6122
+20246
+1105
+3831
+19163
+10548
+14615
+19347
+23822
+8348
+6838
+28933
+20407
+15571
+25901
+7110
+9571
+22965
+13110
+20794
+5287
+14535
+14847
+16094
+9541
+12126
+5140
+27445
+10004
+15733
+27604
+20552
+22054
+4366
+22807
+18827
+27240
+28550
+28947
+23439
+20402
+25546
+632
+19972
+5867
+28766
+19703
+11131
+28184
+15017
+25791
+5624
+27088
+31513
+22684
+12038
+27718
+17192
+13183
+2461
+19733
+30932
+22654
+28944
+5637
+22484
+31657
+26207
+7797
+20221
+4915
+8774
+28883
+25165
+22401
+2382
+3769
+18094
+28242
+3642
+13773
+27544
+25968
+25608
+517
+29198
+20964
+30112
+7673
+2830
+4239
+22477
+29052
+15225
+14829
+10438
+5307
+11599
+25597
+5786
+2408
+17409
+29167
+23901
+16819
+10793
+14291
+18199
+27320
+2836
+27558
+7900
+7884
+8817
+32149
+6640
+30977
+221
+110
+29416
+31319
+10447
+19937
+3323
+20752
+6680
+30113
+25705
+25275
+8217
+9634
+26758
+30243
+8310
+21447
+27880
+15757
+18980
+12469
+29783
+11978
+28987
+308
+12084
+19800
+5157
+12019
+3525
+14729
+31677
+3011
+30376
+22456
+7095
+18111
+22680
+3927
+15781
+18555
+18044
+21092
+32699
+29698
+23471
+30735
+24236
+15633
+18660
+10699
+32509
+25299
+16284
+30913
+5073
+12401
+8653
+17628
+5287
+6054
+24953
+4403
+21254
+26970
+20136
+5446
+19885
+16599
+13688
+32129
+20068
+25270
+15253
+23108
+23111
+9943
+10478
+30362
+9290
+11580
+26845
+10809
+16549
+27234
+3948
+8018
+2224
+6277
+26756
+22361
+15135
+5443
+4447
+20041
+26100
+14172
+13774
+14773
+19105
+28249
+23543
+31102
+6595
+8845
+12757
+29587
+24334
+21100
+29413
+26819
+8108
+1409
+2104
+29437
+1799
+12955
+5367
+13685
+22254
+25300
+7517
+1273
+7684
+19979
+26828
+1716
+28796
+13702
+12942
+9952
+2426
+30266
+11055
+20700
+28423
+946
+19791
+13859
+31114
+8808
+10089
+533
+22066
+4366
+22754
+2725
+29811
+439
+17532
+31223
+25896
+29388
+1518
+8476
+889
+10480
+30459
+3740
+22500
+24607
+16937
+18438
+22701
+32495
+14342
+27259
+24569
+2078
+18135
+31031
+12503
+9008
+24493
+10960
+29982
+12674
+3717
+28826
+13003
+529
+30426
+5832
+24727
+13506
+1720
+23582
+2588
+3303
+22757
+30140
+13391
+30696
+26087
+18727
+26817
+1479
+30963
+15185
+4843
+9384
+14655
+2483
+28249
+26433
+12453
+28615
+8419
+22154
+18774
+30653
+14722
+18616
+26457
+10350
+28361
+1431
+17237
+18597
+3818
+569
+5774
+25347
+2756
+9710
+31697
+41
+20611
+3919
+17685
+10588
+2781
+23190
+23649
+12773
+29346
+5984
+18245
+16720
+7491
+14439
+5542
+30830
+20828
+14291
+11730
+1838
+14860
+10116
+8292
+14190
+21716
+31994
+10138
+6109
+30601
+25041
+15033
+30915
+28049
+32127
+22953
+15137
+10188
+31366
+17554
+9936
+16152
+29304
+31100
+6500
+20420
+28067
+3246
+11486
+18249
+15053
+1869
+5508
+22650
+31376
+10688
+21711
+7255
+14074
+1499
+19124
+9943
+6477
+22085
+10789
+16188
+19163
+4215
+16874
+6023
+24181
+5444
+21904
+8432
+3119
+9448
+11582
+25680
+28280
+16532
+24429
+18347
+26352
+13860
+12107
+6288
+26957
+26424
+11962
+27076
+31699
+30384
+30049
+27201
+3474
+9080
+29421
+30559
+20883
+12516
+29151
+12498
+28282
+21891
+23972
+29962
+7753
+32561
+15389
+13405
+32697
+5296
+894
+27760
+20914
+6789
+26930
+2566
+22713
+13053
+13193
+3415
+6764
+28074
+24980
+23490
+23516
+32506
+9397
+16994
+22170
+14748
+28760
+20565
+16541
+18780
+22002
+20090
+28741
+27799
+28888
+19284
+10617
+5359
+3892
+15445
+4100
+13969
+3864
+3725
+29356
+10754
+14526
+27205
+443
+27875
+27114
+8867
+15181
+2801
+881
+13107
+3172
+14185
+10139
+24488
+19315
+7196
+20332
+23184
+18549
+14184
+17708
+7827
+2533
+20762
+16712
+14245
+3382
+7287
+29932
+3899
+10278
+11113
+11404
+15823
+4042
+15417
+25835
+23537
+1379
+20362
+14045
+8404
+1486
+18737
+31728
+9090
+27781
+16578
+18999
+12197
+21348
+9143
+4079
+18241
+21301
+6408
+13502
+24482
+9539
+6464
+27024
+3710
+6785
+23308
+4963
+27863
+24858
+17332
+5292
+20897
+23910
+7250
+4880
+10778
+15058
+1014
+13860
+20446
+21930
+11538
+21300
+13856
+5245
+26583
+30441
+31354
+3552
+6884
+5836
+1965
+5998
+5118
+23021
+32651
+23551
+5133
+10184
+31391
+2497
+5507
+28117
+31809
+19858
+19796
+31207
+29831
+28315
+11840
+4104
+17391
+18902
+11140
+8098
+5774
+26766
+24614
+9993
+7204
+8835
+29859
+12138
+633
+6253
+26410
+7903
+4361
+9506
+4865
+30552
+28124
+10114
+26705
+16253
+30814
+15508
+28255
+21460
+17455
+1682
+13877
+1917
+24011
+24297
+21270
+28548
+25852
+2503
+16631
+25205
+8209
+22937
+10446
+13083
+24707
+2656
+25529
+23415
+3283
+16514
+19373
+3197
+4881
+27195
+27887
+3461
+29858
+23550
+11192
+29925
+5730
+19080
+17230
+22830
+12060
+6667
+7931
+18240
+30671
+22537
+32193
+16682
+19935
+11832
+15529
+16267
+6652
+10861
+13825
+9848
+15743
+5556
+10548
+25955
+1962
+27484
+9992
+21075
+1286
+29120
+6360
+19602
+13178
+12139
+25342
+28073
+12411
+5944
+8402
+252
+29401
+17952
+2194
+31758
+7868
+8633
+14794
+16257
+29190
+8799
+25422
+25283
+17087
+10095
+16593
+9579
+17978
+14007
+31747
+21762
+10642
+28220
+25839
+13558
+23947
+5911
+3275
+9403
+8804
+2695
+27073
+21440
+1419
+15679
+11324
+18022
+5920
+30813
+23785
+115
+11359
+14584
+25565
+26909
+9754
+4990
+30629
+15648
+13854
+17216
+29027
+28541
+5998
+28903
+30599
+4653
+6705
+10496
+5587
+32279
+14587
+13597
+18544
+29260
+14762
+29100
+29207
+4892
+15281
+32715
+15001
+15745
+3056
+26420
+19629
+10630
+20526
+17203
+32437
+22601
+16003
+14868
+21754
+15749
+12894
+2543
+18326
+6051
+8033
+26852
+28608
+26825
+16220
+1402
+24887
+4802
+13709
+5459
+15349
+12075
+24924
+12889
+18578
+13785
+26141
+13457
+28986
+24140
+10786
+26333
+28491
+22633
+4312
+10517
+31531
+1524
+11702
+23131
+23307
+1904
+4281
+13420
+21871
+12433
+10829
+22138
+2643
+28180
+5945
+26666
+15443
+10822
+10387
+2811
+4837
+17120
+20128
+17859
+21323
+32481
+16563
+31882
+27015
+25945
+29732
+13427
+16995
+16194
+19576
+7619
+5991
+9712
+29366
+18469
+21190
+344
+632
+16192
+18846
+25121
+513
+13637
+27513
+3759
+22246
+22976
+10576
+29756
+17491
+19664
+10556
+19893
+22310
+22134
+4796
+5377
+18692
+31949
+16901
+11417
+6326
+32510
+11850
+7817
+22686
+8823
+24067
+15059
+13399
+1326
+19104
+5812
+11333
+9304
+14502
+30526
+14128
+30225
+6215
+10554
+22330
+27466
+32428
+1766
+10345
+15940
+1812
+28331
+21030
+32733
+19167
+16604
+26150
+28947
+13603
+20391
+9603
+31199
+28012
+7157
+17323
+13892
+19836
+21259
+20303
+3000
+10706
+27785
+16192
+18712
+3404
+19322
+26
+24089
+26805
+3985
+10938
+23921
+32715
+11328
+15229
+18292
+18364
+25359
+5635
+26423
+4773
+14008
+2732
+19271
+27953
+24485
+9971
+21709
+5955
+22500
+30263
+19097
+14355
+7256
+5672
+19089
+13136
+3641
+30987
+6726
+2795
+3593
+7065
+7713
+14117
+14835
+19217
+29390
+3666
+19739
+21932
+22960
+1895
+17417
+20413
+15292
+175
+8576
+31674
+14846
+1498
+22493
+11061
+20511
+28098
+794
+29122
+18945
+25984
+22681
+23887
+19457
+11498
+4097
+1601
+15309
+18906
+15488
+9647
+20529
+32039
+26980
+22389
+28762
+29654
+5958
+6048
+10992
+4988
+28271
+4630
+14046
+19424
+11654
+22548
+20418
+26816
+24347
+1970
+2476
+13700
+11139
+24471
+31634
+31738
+8134
+16236
+5212
+23177
+2945
+31169
+3358
+29590
+16951
+20533
+30738
+15983
+13603
+11542
+23371
+17894
+19357
+20240
+18379
+6439
+1873
+6737
+31979
+24113
+12590
+7196
+20252
+30500
+10762
+8235
+12536
+11846
+16170
+6080
+30413
+22280
+7129
+6662
+10296
+13161
+24267
+4328
+9558
+3160
+8667
+24556
+12052
+26829
+15051
+6098
+3830
+29771
+17571
+28080
+278
+29764
+21245
+7358
+7189
+21569
+15274
+17250
+214
+2275
+14040
+30821
+27197
+5129
+8729
+21527
+27982
+19025
+13117
+14814
+20033
+18441
+4759
+14158
+14792
+13651
+11716
+19793
+10765
+1817
+19826
+8388
+32130
+7271
+20274
+14808
+25918
+9505
+21472
+22415
+4000
+3101
+29137
+4129
+9265
+25446
+31502
+5832
+32727
+15414
+21277
+12886
+22526
+3103
+5152
+24475
+22985
+26617
+12334
+23803
+3946
+14843
+18799
+13158
+10175
+13628
+10867
+2808
+16453
+10089
+10763
+32074
+24273
+5422
+7661
+20632
+23502
+26422
+14584
+18327
+18407
+19800
+4203
+5825
+373
+23909
+19836
+25647
+31722
+32356
+29923
+14084
+14677
+13446
+3980
+32525
+23817
+22566
+32549
+9068
+26000
+11524
+3581
+12103
+5417
+1087
+3193
+4061
+15713
+615
+1743
+21320
+25588
+30260
+3233
+21766
+8945
+14132
+28370
+24001
+31013
+15456
+28482
+13175
+27646
+8197
+20148
+14823
+13630
+15708
+16283
+9484
+23780
+7934
+13
+31944
+23356
+2936
+4814
+14660
+25413
+195
+21726
+28538
+23813
+6517
+4583
+2189
+11282
+5766
+2008
+5233
+9525
+27072
+3796
+12289
+19265
+22123
+22834
+249
+10413
+16784
+2952
+13438
+29021
+14850
+7745
+25265
+1483
+2986
+2329
+26060
+29886
+6775
+8304
+29727
+28770
+27309
+23138
+1037
+7465
+6547
+21146
+7650
+8262
+3375
+12761
+30783
+6241
+23095
+8141
+5941
+20228
+17124
+14818
+20189
+16167
+15432
+16318
+29830
+22545
+792
+16932
+26872
+12436
+6429
+27439
+2549
+206
+996
+9019
+12789
+6923
+3535
+19351
+27013
+22020
+20059
+5108
+10369
+22631
+4456
+4452
+29426
+8059
+31828
+15398
+2345
+10477
+15607
+8417
+19699
+12579
+18575
+22553
+3904
+20938
+30343
+16781
+13091
+6408
+2989
+11649
+8222
+27365
+1042
+28881
+20088
+21372
+12953
+3770
+2980
+1794
+24154
+11602
+2292
+5303
+12449
+24306
+10975
+27309
+19184
+12342
+18736
+3540
+1257
+32034
+1946
+13218
+1158
+21247
+16579
+29538
+30069
+8265
+16587
+6360
+22428
+31083
+4624
+3206
+31185
+10125
+20089
+11324
+27987
+6978
+24272
+1160
+6792
+7366
+13457
+24498
+18427
+23751
+16679
+12363
+15303
+24797
+27220
+30034
+1686
+9954
+28854
+5105
+32015
+14586
+19555
+6912
+21160
+25879
+26304
+7901
+31587
+29892
+10297
+28127
+747
+24493
+6426
+10711
+9329
+5869
+18184
+6502
+8760
+19672
+7128
+12590
+3128
+25265
+8269
+27659
+29462
+19500
+32725
+9986
+4852
+830
+13746
+22178
+30739
+27121
+7628
+1540
+11374
+5242
+6787
+26620
+10958
+23550
+23079
+2763
+24523
+12839
+29018
+3666
+889
+20306
+21900
+12335
+13362
+6386
+23565
+987
+23447
+18159
+8563
+10829
+21911
+21945
+4891
+9046
+10314
+22689
+22799
+17095
+29768
+30946
+4035
+30500
+4610
+1782
+22207
+23619
+188
+378
+15366
+24641
+30628
+23750
+8188
+5279
+12282
+27881
+29736
+5829
+13245
+3047
+12339
+15532
+7315
+18646
+10949
+17313
+17401
+13643
+1528
+11606
+2352
+25092
+11587
+26669
+202
+32608
+20000
+23431
+10720
+30220
+26746
+25488
+17847
+7315
+13071
+27334
+13902
+30665
+19313
+3044
+21341
+7592
+17733
+2122
+28252
+13554
+20954
+1548
+16796
+5723
+26404
+15249
+23102
+15114
+16241
+21198
+2324
+21800
+3728
+22436
+28447
+3504
+26925
+11759
+19668
+14386
+31065
+26490
+11900
+941
+8022
+6496
+9949
+19911
+2717
+27360
+24001
+28457
+9929
+32616
+18925
+7204
+21790
+22090
+17330
+6206
+15093
+24518
+24478
+21729
+20557
+3107
+30255
+22797
+11602
+8510
+5373
+9023
+8374
+24374
+9172
+4428
+25324
+14216
+26299
+21716
+23204
+32218
+18665
+5218
+22935
+27906
+17572
+14637
+25409
+1185
+10215
+27334
+14777
+20028
+31429
+17973
+30157
+3325
+340
+22030
+30875
+21336
+25069
+25444
+30650
+3281
+5355
+8936
+32622
+23585
+10696
+21161
+3788
+8094
+3706
+13224
+4699
+15106
+16840
+28719
+18810
+6558
+1716
+21821
+19343
+30480
+660
+26384
+7661
+23718
+16758
+169
+12520
+11386
+9753
+22679
+29734
+4961
+5603
+13440
+24332
+25844
+31925
+9544
+26071
+12136
+2627
+1667
+14225
+19704
+21722
+27676
+30660
+6650
+10730
+31628
+23467
+2936
+19390
+30269
+20527
+7235
+20317
+9571
+22795
+6243
+21898
+2501
+7172
+9278
+9849
+6681
+32655
+14925
+18864
+30547
+18026
+30182
+5968
+15788
+5282
+19403
+12123
+16872
+2558
+18124
+7333
+24354
+25262
+21807
+20866
+20670
+2303
+23328
+26116
+17132
+14809
+10424
+4893
+6795
+17116
+6295
+10144
+20525
+24179
+31833
+31171
+4171
+32347
+16404
+3588
+20028
+28818
+20491
+20111
+16442
+31872
+29057
+2460
+15963
+6781
+17613
+8772
+31486
+25139
+11901
+26528
+29540
+22834
+9370
+10738
+28177
+17150
+24383
+31134
+17954
+12489
+8795
+15185
+31425
+19494
+8089
+14240
+16919
+16748
+21755
+21505
+20566
+28949
+16477
+20072
+18518
+22571
+10248
+31037
+24326
+11909
+17712
+10904
+11627
+1951
+1952
+21144
+17653
+25370
+25367
+15594
+23741
+13188
+19703
+3486
+23549
+28299
+13981
+12461
+21407
+18405
+24086
+17744
+21321
+10739
+19669
+32707
+249
+8278
+10767
+30152
+22580
+2150
+13075
+17789
+17806
+7320
+27462
+1074
+4410
+9653
+11775
+4321
+20427
+29105
+24193
+12694
+16488
+7851
+4267
+27059
+13737
+2182
+29294
+22602
+13439
+19000
+19396
+30055
+3946
+14211
+10913
+27343
+24181
+4740
+19570
+3955
+3296
+27599
+10174
+21175
+12432
+27390
+443
+27745
+205
+13864
+15369
+14409
+26071
+16427
+7652
+11480
+15906
+30417
+23787
+2924
+1895
+17990
+15675
+16023
+20635
+15195
+3979
+18046
+20627
+7687
+14466
+12111
+7656
+13134
+4025
+376
+4692
+1307
+30367
+4730
+22166
+25844
+9800
+7897
+5639
+26525
+14854
+2492
+27287
+5437
+4687
+17514
+21476
+16443
+7218
+24326
+14008
+5811
+31534
+13309
+24883
+7881
+23116
+1521
+26716
+7717
+14431
+4834
+27978
+18809
+22606
+10313
+7253
+14297
+20885
+24806
+22426
+31775
+10333
+8958
+6676
+16787
+23945
+10955
+6795
+18796
+29365
+9177
+7975
+29362
+12226
+4605
+12126
+1897
+22078
+14143
+10088
+17480
+3514
+27555
+18604
+22029
+10406
+27231
+12146
+5163
+19187
+21421
+8203
+212
+8966
+8899
+23744
+29774
+25740
+27507
+630
+27949
+22418
+740
+26553
+26096
+16826
+24554
+9589
+31020
+30598
+19099
+24589
+19965
+27169
+16231
+11273
+13318
+14220
+30141
+6092
+11440
+7454
+16124
+17401
+17655
+2847
+18188
+3661
+14482
+6195
+28637
+17155
+8739
+26719
+32393
+3792
+6752
+23969
+7818
+7663
+868
+27680
+24754
+7796
+30191
+27369
+7256
+8541
+11759
+28470
+31046
+2565
+4574
+15319
+30375
+28282
+16849
+14273
+6636
+8444
+23733
+9637
+13692
+5236
+27384
+3131
+14068
+28624
+25119
+2130
+30004
+23854
+8492
+1339
+12639
+31272
+8111
+14328
+8458
+15574
+21581
+26646
+9992
+10549
+2317
+2235
+29472
+5470
+7286
+13900
+25267
+4448
+29781
+11096
+26589
+1149
+28999
+7046
+17122
+21060
+8784
+31722
+29879
+25700
+9989
+23666
+324
+27904
+23913
+19961
+13192
+19619
+5921
+10125
+18032
+9208
+4712
+12460
+13590
+25027
+28260
+1668
+25369
+18871
+16128
+15928
+11009
+2437
+21340
+1031
+17743
+5551
+22103
+5314
+7391
+18084
+26063
+13566
+16126
+23436
+32616
+23126
+2356
+32485
+9194
+10543
+5858
+4768
+29819
+32137
+26285
+5189
+5696
+26136
+1836
+5327
+26485
+30578
+12682
+12149
+24687
+17536
+27712
+12720
+27672
+23219
+26540
+9076
+15849
+15437
+2082
+18866
+5895
+1350
+339
+8810
+5546
+6447
+11494
+20493
+19310
+31135
+22521
+17793
+18899
+6149
+13515
+12524
+30255
+9822
+2233
+21391
+9892
+12590
+26102
+15547
+14441
+14883
+1673
+24993
+13495
+4590
+16306
+1256
+28136
+22446
+6635
+18132
+19216
+10693
+26977
+5700
+31026
+5708
+31540
+18206
+9021
+21136
+15761
+16670
+27471
+19682
+14015
+27921
+13964
+26067
+19347
+18762
+15992
+3056
+28877
+32575
+17518
+13500
+16406
+1862
+15441
+12127
+15464
+29203
+6473
+14457
+12699
+27172
+14879
+27276
+25324
+20876
+23181
+32025
+12891
+13619
+23617
+28209
+4514
+16383
+18877
+20058
+16357
+12296
+3764
+5878
+7709
+22595
+28617
+15385
+24457
+26042
+26573
+26435
+14666
+24874
+18956
+417
+18248
+6141
+12517
+12922
+16923
+11847
+30552
+31334
+990
+7798
+11043
+21411
+20425
+26667
+11872
+21115
+15457
+15925
+20711
+19265
+18014
+30648
+6158
+29756
+14745
+15993
+18585
+24819
+13356
+23507
+17489
+30058
+23017
+2869
+4130
+32642
+23233
+29416
+1796
+26148
+1250
+28186
+8845
+29931
+7260
+4541
+19269
+28006
+4237
+16756
+31406
+23891
+5179
+22187
+6723
+32508
+4003
+23939
+7637
+10044
+30141
+3676
+3
+29954
+2966
+26153
+16559
+27279
+9558
+25592
+25083
+27279
+30568
+5506
+17310
+3273
+5024
+17898
+22077
+6200
+14779
+22315
+8323
+16607
+5990
+21413
+6502
+11208
+32669
+23420
+24284
+27065
+16958
+8067
+30439
+3408
+9964
+4670
+20139
+28879
+32164
+21539
+4439
+12708
+9803
+18080
+32418
+27304
+23552
+13114
+29435
+4955
+23821
+13672
+2848
+1515
+18182
+32361
+17366
+28787
+20349
+27324
+1439
+10167
+12339
+5896
+26948
+14898
+462
+10885
+11749
+24967
+12575
+15434
+30176
+1923
+26308
+3996
+32561
+7460
+21473
+31067
+2474
+15158
+9371
+5237
+24469
+487
+5834
+31439
+19738
+14647
+7808
+10914
+3797
+27421
+23332
+21495
+14109
+28604
+18568
+9362
+4750
+30668
+18697
+7414
+11814
+7187
+29606
+15990
+31836
+20395
+4198
+28849
+4783
+27268
+17313
+7283
+8212
+13654
+19873
+13247
+27061
+14533
+19686
+25000
+11809
+14857
+24221
+24388
+1720
+24731
+3447
+22985
+17360
+21348
+29750
+19745
+24652
+15100
+12228
+12040
+29210
+17244
+31513
+22530
+14572
+15817
+10963
+24313
+22924
+12303
+20484
+3719
+2214
+2319
+1191
+12678
+1852
+5274
+26116
+15085
+21262
+27264
+21713
+6293
+297
+23889
+9512
+5300
+31257
+7910
+16030
+6320
+2200
+26978
+18751
+5504
+14426
+19170
+4779
+17899
+27513
+8656
+8566
+7511
+25833
+18537
+11157
+28508
+18515
+3036
+23167
+8655
+28920
+20199
+22621
+25280
+20030
+9003
+5971
+30493
+21211
+23453
+30490
+6202
+16020
+5576
+19234
+593
+16767
+8817
+28805
+31125
+27917
+6850
+23546
+21951
+16187
+30241
+19113
+23135
+25107
+471
+4288
+31593
+20697
+31466
+16582
+14164
+5992
+20671
+20886
+10966
+7388
+22522
+11936
+24826
+4697
+25603
+12379
+27638
+676
+3111
+32105
+5581
+30858
+25966
+15891
+10953
+18278
+6562
+5427
+7746
+20585
+23642
+25036
+23814
+4160
+13662
+25177
+29870
+27723
+3848
+29441
+25699
+16750
+24190
+19182
+1933
+28500
+12975
+23008
+9356
+2974
+31844
+12177
+10012
+19988
+16111
+32022
+30361
+30988
+12885
+11793
+7808
+2440
+7828
+12864
+12135
+18324
+7799
+18541
+18195
+385
+27079
+13461
+18778
+31529
+4345
+29504
+4548
+12566
+20683
+31218
+23837
+18392
+28257
+20737
+27426
+23409
+1662
+32396
+25489
+6603
+6219
+11587
+11133
+18956
+5909
+1442
+6835
+32722
+211
+28526
+22311
+25680
+1667
+22102
+25706
+2634
+9287
+28880
+17510
+9923
+9666
+10003
+5961
+28117
+26136
+23824
+3381
+22746
+1099
+1605
+20982
+9174
+4445
+9850
+16614
+23533
+18377
+413
+2388
+9087
+1742
+31796
+32447
+22493
+12930
+13267
+15226
+4098
+7508
+18733
+22976
+30706
+3948
+18688
+22857
+4947
+31302
+15182
+8481
+14987
+9905
+24202
+22756
+1194
+24200
+25037
+31317
+4372
+29328
+3909
+15870
+9112
+11817
+13333
+30190
+562
+23199
+19397
+3907
+7939
+11883
+18075
+2936
+9618
+13541
+25377
+14426
+15038
+13578
+31669
+22700
+23597
+24056
+3448
+28949
+23073
+25050
+24052
+5577
+2821
+18922
+23917
+25033
+1445
+20777
+926
+14700
+16000
+27524
+18742
+21731
+24127
+15507
+5736
+19163
+11159
+29510
+6485
+22619
+27495
+32389
+32450
+11711
+7816
+5361
+3356
+2009
+29205
+25737
+1103
+14317
+25970
+26144
+5592
+18882
+7836
+24125
+12088
+17546
+29354
+16832
+25543
+31520
+15063
+20749
+28478
+4889
+9724
+32484
+26163
+26371
+11708
+17874
+8244
+25595
+18728
+610
+14399
+3509
+886
+32688
+11703
+2744
+27183
+21648
+30292
+9198
+4625
+16558
+6670
+12743
+10318
+26420
+17243
+16280
+15548
+8001
+4048
+16169
+25731
+9713
+16061
+3209
+9508
+14014
+8444
+17228
+27463
+16018
+16357
+6381
+6416
+4673
+15400
+13541
+18995
+12630
+23976
+26973
+3909
+10857
+3570
+17806
+5661
+30151
+719
+4157
+26978
+29897
+26222
+1558
+17032
+6880
+16792
+13063
+23749
+15834
+32193
+25843
+13148
+3094
+12253
+252
+28281
+28156
+27109
+4153
+19008
+20669
+29935
+17570
+1468
+19506
+8364
+14466
+1109
+8603
+30556
+1054
+9731
+26021
+27062
+20656
+10766
+11509
+18009
+11034
+27121
+935
+10005
+10322
+25149
+19023
+20791
+20023
+12655
+3474
+13232
+16209
+5989
+5994
+28951
+27487
+1106
+22376
+15626
+13420
+26640
+19257
+10572
+6294
+31227
+27655
+2299
+21657
+11355
+26675
+9998
+22022
+19994
+15074
+27535
+12436
+518
+5060
+29043
+1246
+26578
+23066
+3473
+24159
+22424
+25844
+28459
+5356
+17133
+11071
+4347
+5262
+15892
+23202
+30608
+21825
+24726
+24000
+11072
+20297
+714
+19739
+32584
+28169
+20109
+21215
+1462
+16337
+29799
+18022
+6037
+1740
+1229
+19877
+26911
+16693
+9161
+2044
+24121
+10058
+6396
+27880
+5701
+10645
+10414
+30932
+29436
+13111
+5071
+22574
+32627
+5749
+10906
+6375
+4700
+7255
+19460
+24049
+18422
+10884
+29752
+15525
+13348
+22599
+27761
+15844
+6851
+15921
+16486
+9312
+17144
+18038
+8051
+31894
+7614
+21994
+10517
+25945
+720
+16961
+27767
+16649
+29756
+14807
+1873
+29899
+27310
+8904
+8768
+27015
+27684
+24037
+13561
+5457
+21498
+4610
+6390
+29020
+30344
+3736
+23191
+9492
+31311
+13703
+31589
+30882
+5225
+6860
+31925
+983
+21943
+32699
+31550
+22354
+30133
+3633
+4000
+29252
+2711
+24677
+21322
+27822
+19510
+12447
+19995
+30928
+20903
+21500
+7393
+11725
+5315
+12559
+29713
+15959
+24756
+7183
+17166
+29404
+4946
+7051
+3884
+15203
+1384
+9815
+24214
+3555
+29817
+25922
+8819
+20177
+19722
+32143
+30997
+3232
+9768
+26336
+15030
+24706
+11414
+26763
+22200
+29455
+7763
+31959
+20954
+26134
+2048
+3213
+16077
+19405
+8195
+19557
+22104
+1759
+18464
+26166
+5677
+13017
+29953
+17052
+26097
+22284
+163
+10797
+15732
+24686
+8301
+29717
+17345
+30669
+22768
+21356
+3482
+6799
+21264
+29589
+29456
+31376
+10393
+32751
+277
+19854
+25072
+4053
+1998
+15291
+14590
+20590
+10359
+22863
+839
+21407
+17778
+32559
+10843
+25967
+5868
+855
+30376
+16532
+22728
+2286
+28642
+6444
+17183
+27382
+25419
+29384
+19398
+272
+6491
+20921
+4059
+16820
+16220
+25419
+5374
+28525
+14460
+570
+23107
+590
+5932
+2713
+3492
+26076
+7651
+17997
+4780
+13496
+27518
+16451
+5786
+493
+6786
+969
+17374
+26462
+4659
+3504
+26007
+27793
+26214
+27771
+7851
+19379
+2771
+23909
+13159
+26272
+16931
+21472
+23588
+5588
+16390
+4288
+19715
+15039
+3269
+4102
+10408
+2888
+24885
+591
+23646
+30277
+25841
+19497
+19583
+30673
+23125
+10267
+18340
+15700
+6523
+5948
+10073
+2082
+11115
+10444
+3760
+27900
+27733
+29783
+7412
+32303
+6955
+18410
+7090
+26477
+25705
+19666
+8398
+22754
+7239
+7796
+5842
+22763
+23650
+29815
+31988
+13864
+7668
+16105
+23704
+22823
+25105
+7370
+25646
+9820
+4396
+6431
+28638
+32596
+13762
+10586
+7546
+3166
+5786
+12514
+1340
+952
+24745
+8907
+27985
+10595
+18916
+28416
+17350
+16626
+28903
+3015
+21373
+24372
+3216
+30446
+12097
+8648
+31121
+27053
+31820
+13467
+26619
+17431
+29039
+32094
+25199
+1900
+2246
+10059
+24731
+13371
+22534
+14200
+18907
+28473
+14655
+6251
+26539
+13988
+7987
+29092
+28252
+32661
+16055
+6427
+24949
+4297
+20676
+11521
+29579
+21706
+15413
+3530
+7909
+10169
+13857
+23918
+6853
+10096
+23973
+13884
+27767
+17815
+28798
+14210
+2643
+28584
+7272
+4474
+12668
+29685
+31416
+4391
+22305
+24085
+26899
+5809
+6949
+30498
+30211
+3983
+18761
+5928
+796
+29688
+23866
+20222
+18929
+9232
+22606
+5344
+9243
+10367
+29986
+26001
+22717
+11113
+9006
+28430
+23750
+296
+15738
+29092
+8815
+19465
+11987
+24487
+2226
+2214
+3415
+3189
+2898
+28460
+22130
+13421
+15794
+14346
+15256
+19837
+29374
+15572
+14547
+554
+19769
+11888
+2055
+12568
+17300
+22414
+24277
+4982
+28350
+6402
+8394
+23347
+16784
+1159
+27178
+14707
+987
+21646
+896
+5123
+4846
+3601
+11706
+27821
+31683
+31939
+6999
+4184
+22917
+22963
+7000
+25198
+29679
+28
+178
+23476
+13810
+27418
+5909
+8648
+5156
+32668
+5173
+18494
+32640
+21080
+25942
+17856
+25738
+23650
+27677
+11326
+30851
+15331
+26575
+8541
+15910
+2327
+30500
+8125
+1404
+24899
+14358
+21177
+9342
+10141
+31151
+1655
+18361
+29912
+26258
+13658
+23946
+23137
+25508
+27814
+20055
+28013
+22301
+23052
+5328
+14319
+701
+30821
+954
+19969
+20362
+5733
+32284
+3973
+8598
+14724
+19373
+2777
+26922
+29622
+1336
+31643
+15565
+23155
+1311
+29656
+2707
+25866
+7904
+13319
+25346
+22504
+4025
+29003
+10946
+1191
+18406
+2770
+11844
+6761
+11448
+10527
+20336
+25721
+31344
+10144
+20691
+31928
+19783
+5129
+11812
+28597
+32293
+453
+26059
+18365
+4413
+6408
+31697
+12301
+17363
+10512
+12844
+6402
+32468
+19054
+16115
+26080
+658
+24000
+7131
+4807
+28809
+2201
+14007
+29323
+20710
+27999
+20233
+4527
+8174
+5216
+29780
+24540
+14388
+5703
+19580
+6675
+31059
+27226
+26596
+32240
+26284
+29582
+9214
+15840
+45
+16953
+26876
+16484
+11280
+7518
+20254
+24275
+7419
+29195
+24705
+23103
+10857
+6856
+2248
+16363
+2062
+29534
+28504
+21398
+28995
+9974
+6629
+23442
+372
+16463
+13293
+25629
+2015
+2971
+14196
+16036
+20016
+1285
+10264
+320
+15483
+19983
+6295
+596
+31076
+17344
+19414
+29358
+13138
+10745
+21356
+6131
+8386
+18452
+22156
+14747
+7990
+12522
+975
+16349
+27948
+3559
+24040
+19495
+21813
+26570
+16081
+20695
+7713
+15601
+8759
+250
+23897
+20892
+2042
+25408
+8330
+3547
+26058
+26181
+25263
+10122
+7432
+6184
+7831
+31908
+6971
+448
+7912
+19541
+10407
+17355
+7303
+729
+14687
+21428
+28216
+16095
+26589
+11290
+677
+19827
+242
+25953
+4367
+5218
+29544
+27639
+32657
+25489
+8279
+1714
+24431
+17552
+9107
+16925
+18831
+31039
+18324
+3077
+26988
+3463
+26351
+1598
+5020
+14242
+12579
+19873
+8830
+15796
+13391
+23862
+14601
+14591
+8225
+10847
+29542
+25279
+2685
+23477
+26747
+4224
+30645
+13473
+2224
+5706
+9060
+7083
+13893
+9561
+5587
+32256
+45
+22193
+21737
+17767
+13141
+26056
+27201
+1655
+4851
+20765
+8800
+6111
+2801
+5083
+16879
+30618
+31348
+5499
+5722
+12073
+24220
+6972
+23459
+28315
+18045
+2512
+21900
+32530
+7916
+20366
+18410
+32284
+11980
+120
+6655
+3506
+20010
+31010
+22412
+28708
+9134
+17102
+819
+24201
+15535
+15023
+29985
+359
+11842
+3885
+10053
+142
+7036
+2127
+15602
+23577
+8553
+19818
+14490
+11577
+7771
+16127
+29871
+17746
+11616
+17073
+6124
+13254
+25076
+8266
+1668
+7345
+26702
+32694
+24276
+21536
+8420
+9610
+21067
+31823
+19618
+19414
+30436
+8332
+4492
+11739
+13363
+17740
+9556
+30951
+17460
+24840
+7909
+4481
+1516
+5226
+26472
+2082
+14280
+694
+10054
+14047
+10653
+24284
+30963
+29225
+14650
+13466
+5440
+15850
+7231
+11740
+6118
+10276
+29128
+8662
+2001
+26059
+5525
+14164
+9957
+23959
+10424
+29501
+30737
+22026
+28253
+23646
+25656
+28583
+27981
+3218
+2252
+23529
+23281
+14880
+19523
+27432
+20467
+32199
+18379
+14860
+3291
+16592
+24674
+4854
+29790
+30461
+4621
+20587
+31774
+17761
+13735
+3560
+21913
+19606
+20774
+28507
+32359
+21502
+2591
+18141
+30231
+5903
+5702
+32319
+31814
+13650
+26113
+5166
+1720
+18696
+29148
+18108
+1099
+3461
+18982
+19520
+12670
+30706
+3756
+5900
+16540
+2644
+14594
+22342
+2276
+21842
+6179
+19277
+27358
+16809
+5782
+29626
+31667
+30070
+28681
+11831
+22590
+9178
+2658
+22967
+12019
+1660
+25400
+14720
+10797
+3634
+6394
+2000
+5558
+5550
+3224
+8879
+27885
+30792
+6578
+5617
+13002
+14641
+31098
+5164
+10927
+6356
+14043
+11960
+23181
+10655
+19346
+9639
+13954
+22962
+25519
+13040
+23541
+30831
+30309
+4098
+18859
+14227
+25976
+25950
+13055
+23065
+29238
+23047
+20125
+31814
+1991
+27066
+27148
+29497
+29701
+18579
+26551
+15918
+30553
+18706
+27009
+22267
+19350
+13020
+23173
+8997
+9417
+15415
+27509
+9426
+30120
+4178
+17438
+10845
+2418
+30814
+32645
+16467
+24737
+11419
+11648
+21041
+21040
+8172
+31007
+5977
+1182
+27579
+29740
+9923
+7506
+16188
+15528
+3494
+27261
+21391
+29276
+9683
+32742
+2143
+25750
+24750
+24429
+4400
+8294
+19108
+4610
+5848
+31007
+10878
+32319
+31803
+20608
+18031
+32016
+20012
+30683
+26855
+22366
+4735
+32084
+23108
+24293
+27007
+13629
+24980
+28614
+31922
+24312
+18844
+24274
+22940
+14698
+8965
+21269
+19777
+10752
+4259
+4315
+21707
+2139
+26908
+27012
+4636
+6280
+22725
+8473
+17390
+25185
+5554
+12265
+15066
+28792
+13044
+29929
+16476
+31824
+10042
+11268
+27910
+24170
+15564
+4955
+30629
+11498
+4633
+27240
+30366
+22842
+13874
+22943
+29580
+4134
+28625
+8412
+445
+31646
+2242
+13294
+550
+22804
+29289
+7301
+12581
+7413
+15854
+11676
+32614
+16391
+12636
+26684
+6233
+14903
+11881
+17497
+20500
+6563
+16795
+21262
+27332
+12734
+22015
+3037
+12438
+3129
+19055
+5707
+18863
+8130
+14333
+6326
+6493
+22914
+9235
+9211
+25181
+5838
+25164
+15925
+15744
+18659
+23562
+13881
+31253
+14735
+4874
+6542
+30031
+26913
+19295
+3370
+29623
+7240
+3181
+8687
+9546
+28658
+18496
+3169
+30606
+10609
+31838
+12282
+5606
+25430
+25220
+2437
+8667
+3004
+9977
+31888
+32161
+9633
+16904
+14807
+11911
+18499
+24149
+24746
+27617
+10647
+8690
+28059
+14214
+30012
+22754
+4467
+27544
+3511
+17083
+20938
+27424
+20056
+20020
+24807
+6555
+19659
+28941
+11620
+20929
+2497
+11776
+22738
+316
+22427
+22857
+2181
+1872
+24533
+26209
+16291
+12764
+8792
+25583
+15273
+6758
+30381
+370
+16719
+31643
+14046
+19934
+19323
+10495
+16458
+29298
+19528
+16080
+9859
+16409
+20972
+12515
+17246
+8708
+29768
+21964
+4707
+19988
+12402
+13588
+27891
+988
+14677
+10952
+25721
+31956
+29349
+32588
+12985
+23620
+5087
+16870
+9378
+14029
+10541
+2104
+27823
+5114
+20167
+13758
+5919
+18023
+22062
+14905
+17933
+9090
+27775
+20057
+31342
+9238
+30495
+15136
+2933
+20371
+23119
+20720
+31949
+10484
+324
+14309
+21251
+15067
+14476
+17758
+23472
+12445
+18806
+13760
+6685
+5509
+3736
+20605
+4119
+30890
+10078
+19816
+12974
+28037
+29336
+10089
+14949
+6609
+7931
+5577
+4134
+30127
+22070
+19463
+9161
+15929
+27841
+18255
+26430
+17462
+23564
+18206
+14677
+14676
+27694
+3935
+31268
+10079
+29577
+28039
+31123
+18938
+31514
+8579
+25127
+16778
+28531
+15482
+12844
+5901
+31654
+4217
+9484
+25189
+5696
+26452
+23461
+26264
+16033
+23072
+15987
+6180
+2560
+12794
+19113
+23339
+6790
+31621
+9800
+32156
+15899
+10279
+17191
+26004
+10781
+4308
+1770
+3970
+22142
+4452
+31006
+21307
+8379
+6991
+14763
+10725
+10425
+24326
+24456
+879
+10589
+26625
+22827
+20898
+9933
+32604
+11497
+20450
+10323
+5588
+12518
+1369
+23491
+9850
+27762
+1980
+32472
+29812
+2064
+2949
+7332
+8394
+1404
+19356
+12465
+32533
+693
+2569
+12019
+7477
+18951
+19672
+11439
+13202
+2140
+7245
+17592
+10782
+22022
+20713
+9567
+18272
+14237
+29332
+3801
+26196
+18832
+18292
+19097
+14608
+5924
+23303
+23884
+25392
+14509
+13951
+30264
+7542
+19209
+3790
+13722
+13913
+19988
+13322
+7888
+6798
+6822
+15859
+24275
+17497
+2063
+17429
+24181
+597
+28421
+27130
+17203
+1739
+15163
+24069
+22204
+5277
+30120
+4510
+28626
+27521
+843
+28637
+17970
+13937
+28991
+1223
+25649
+9087
+9382
+11453
+23499
+13606
+32697
+32116
+28729
+27070
+25879
+4534
+27674
+27243
+24484
+14382
+8723
+12781
+27009
+25709
+27120
+20341
+25951
+357
+23582
+26515
+6685
+14595
+16313
+23770
+3272
+29030
+1033
+12960
+18771
+10724
+2116
+25772
+12396
+9958
+4322
+10353
+13239
+24316
+13772
+343
+16386
+465
+6778
+32754
+5622
+7400
+26401
+28563
+26108
+9997
+915
+25792
+20669
+562
+18689
+7761
+9451
+31536
+19177
+23474
+23460
+3268
+20557
+10829
+25860
+15833
+7433
+31023
+15171
+28929
+7534
+23502
+24655
+4905
+14373
+15150
+27459
+16367
+1322
+20758
+12367
+18721
+14856
+6202
+20846
+23309
+2594
+26659
+6262
+2653
+8479
+6024
+6891
+4238
+7461
+2819
+8579
+18678
+23962
+21747
+26136
+29303
+440
+30639
+23516
+744
+1522
+8096
+1433
+14104
+13653
+2934
+10923
+3090
+19736
+10641
+16669
+2080
+14380
+6933
+9125
+24257
+9940
+27659
+6997
+12740
+31251
+16092
+4501
+4868
+17401
+13912
+976
+32249
+6415
+20925
+1370
+5363
+4432
+18909
+3382
+286
+6387
+19821
+2699
+28151
+6558
+8485
+15542
+1219
+17752
+28790
+457
+30454
+22254
+28205
+9485
+17561
+26974
+26115
+6174
+31909
+1911
+15986
+19532
+20161
+744
+3247
+31793
+8032
+10197
+26512
+26510
+24754
+4535
+18020
+2266
+30922
+21561
+16770
+24366
+28227
+16508
+14880
+20385
+2202
+31775
+31601
+23735
+19473
+8665
+27837
+17941
+19190
+7966
+6797
+27739
+28171
+23189
+12913
+26980
+32439
+23335
+10549
+7269
+26209
+4161
+25680
+29234
+2889
+3557
+21486
+25030
+12749
+15386
+30356
+5370
+24030
+24896
+3081
+26882
+19813
+29531
+12263
+4064
+30466
+31815
+23573
+17042
+18022
+1989
+15271
+9708
+29392
+816
+26239
+19209
+27036
+22405
+10164
+27783
+27019
+23726
+17529
+10452
+18580
+15171
+28470
+5633
+14762
+4739
+3101
+5196
+12897
+23158
+19556
+24384
+10331
+5910
+20848
+22053
+21408
+2029
+12039
+10568
+21293
+24380
+1099
+32634
+22367
+17049
+954
+19856
+24404
+23220
+5871
+23058
+30158
+24567
+29188
+6368
+18242
+5344
+16305
+11171
+8627
+6014
+31848
+19637
+22787
+2834
+27218
+23351
+19448
+17598
+23946
+18732
+15906
+18737
+27439
+1469
+27446
+21796
+32186
+27588
+24124
+29783
+17482
+31084
+26569
+30078
+28007
+15054
+1256
+29561
+16677
+11326
+26656
+21010
+28297
+6657
+31009
+3856
+10745
+22940
+14187
+3892
+23844
+16837
+17138
+24390
+12182
+22448
+7456
+32054
+16538
+30954
+2547
+25929
+23250
+27466
+5501
+27100
+7436
+7969
+27169
+21629
+2717
+4681
+18369
+4503
+1895
+19374
+21328
+69
+28895
+28640
+9243
+17846
+26873
+24769
+27801
+29403
+18437
+25648
+25482
+21326
+32589
+18855
+16032
+6732
+18275
+26066
+6061
+4126
+19619
+8668
+11199
+19481
+11181
+4799
+28543
+11687
+24989
+15909
+15768
+27802
+18483
+25984
+26953
+557
+7303
+113
+16202
+22608
+6011
+25699
+28556
+11251
+12701
+30642
+28674
+20317
+16225
+5914
+28161
+14046
+21521
+22186
+24957
+2881
+6243
+24063
+21295
+26038
+21830
+14888
+28714
+6365
+3613
+28680
+17837
+15012
+11584
+739
+12260
+17622
+27881
+28974
+16734
+8402
+29560
+1896
+5414
+16408
+11168
+26995
+16071
+17362
+24567
+2607
+22119
+9526
+18225
+1309
+31138
+8575
+15522
+22184
+3
+2180
+17232
+22956
+26194
+13399
+2750
+28862
+9768
+25277
+6804
+3407
+4040
+15993
+12322
+19813
+17223
+15767
+11724
+30605
+28603
+6920
+23194
+26071
+19277
+24572
+28871
+17925
+16549
+19053
+26278
+30268
+6926
+27890
+19024
+28346
+10475
+8263
+18447
+4205
+12301
+31982
+16413
+30073
+2867
+27998
+4291
+7310
+26221
+20722
+31662
+12126
+31377
+7464
+26731
+31277
+30300
+27247
+22344
+27630
+13535
+20314
+31158
+30584
+11497
+11027
+7277
+31594
+6561
+18847
+16368
+24257
+10517
+22039
+18675
+29260
+4824
+30484
+30825
+29993
+8803
+17986
+17234
+4967
+1207
+12821
+9078
+15053
+18029
+29173
+13271
+11040
+3961
+5136
+22637
+13460
+7520
+10543
+9940
+22968
+4074
+28057
+10666
+3695
+30668
+19938
+24170
+24075
+20556
+31593
+1032
+20331
+21259
+7977
+28158
+29902
+9437
+18666
+16932
+31177
+20838
+9776
+21489
+5707
+29265
+26719
+1838
+13709
+27381
+11166
+18108
+2313
+2247
+4132
+24993
+18753
+30402
+30079
+9285
+21383
+25763
+23305
+20899
+17083
+13109
+12546
+8140
+13054
+31837
+1080
+15367
+5898
+15507
+8804
+29763
+4450
+26699
+20540
+21663
+17686
+29141
+1789
+7180
+10055
+29584
+9140
+18950
+11333
+17348
+21347
+16873
+27104
+9760
+23606
+2118
+32400
+22516
+12159
+4278
+29094
+1258
+17951
+29577
+26449
+9305
+2272
+28582
+18749
+30
+25833
+7556
+5094
+11840
+2742
+2133
+10242
+29746
+8294
+16480
+325
+32097
+7899
+18
+28626
+26551
+30947
+14464
+10143
+3209
+14351
+8379
+11567
+7084
+2682
+3118
+27613
+6461
+11463
+31083
+4578
+18107
+22883
+6901
+8118
+4977
+14192
+22812
+4806
+23769
+18363
+8168
+21885
+18324
+32529
+29769
+12231
+32745
+27382
+25951
+3300
+32252
+20468
+24761
+13654
+27379
+16886
+12898
+4354
+22866
+22883
+11675
+26990
+24411
+6728
+5187
+2357
+15102
+20549
+11529
+31986
+14758
+30424
+10761
+30576
+6149
+6708
+7791
+13187
+8735
+29258
+8423
+22634
+20832
+19355
+25896
+29887
+20456
+13101
+6040
+15944
+12033
+17099
+23619
+20442
+20486
+23175
+30107
+18263
+20031
+23194
+31367
+3496
+16745
+30264
+8389
+14751
+4812
+23465
+24677
+16025
+30672
+18595
+31502
+9925
+11202
+30519
+23115
+11742
+9045
+30369
+27463
+10405
+13110
+16562
+8576
+30583
+29206
+22959
+19293
+30989
+5688
+23910
+4382
+5303
+12930
+12292
+3110
+26293
+17172
+30314
+25573
+32092
+23564
+17262
+4121
+10128
+3125
+15438
+24462
+2926
+10575
+22489
+13453
+17147
+15422
+21214
+15477
+21832
+16862
+9845
+1548
+14537
+27947
+30976
+19408
+5135
+10048
+7233
+18488
+6121
+24892
+32587
+23072
+12691
+21789
+1262
+26835
+15032
+21259
+19326
+6411
+32167
+10100
+23478
+25378
+31392
+15493
+7867
+13913
+14487
+6031
+582
+2603
+13647
+8105
+23852
+7980
+16831
+7820
+12628
+18870
+10571
+10660
+28831
+1420
+21324
+20442
+5857
+17325
+22282
+7750
+16468
+27457
+14361
+10011
+2799
+5617
+17384
+29539
+7261
+21422
+6373
+10834
+7631
+14665
+5434
+15990
+3503
+1386
+9822
+13101
+7349
+28031
+32008
+15470
+31613
+6276
+24278
+20734
+1561
+7533
+194
+26509
+6697
+18440
+12425
+16822
+26296
+24304
+3288
+28799
+19710
+25460
+2386
+16887
+26122
+24490
+23942
+17489
+31658
+7705
+18139
+6081
+13047
+18888
+11862
+26638
+8158
+21379
+4788
+12755
+15573
+28914
+20718
+28110
+15877
+4934
+8460
+30156
+216
+8068
+23376
+8783
+12489
+3404
+13355
+12437
+10174
+31023
+22726
+19381
+3142
+5707
+15628
+998
+7598
+25569
+28581
+24514
+28215
+2672
+4050
+31522
+8937
+18608
+22400
+15624
+11599
+25735
+2472
+11297
+24370
+1693
+24524
+28519
+7781
+18904
+11628
+17739
+1703
+23964
+28687
+1849
+25477
+23942
+11532
+19870
+1138
+927
+2234
+13572
+27003
+22688
+3801
+6631
+21830
+4674
+23796
+14230
+2475
+24778
+13106
+21990
+5631
+21191
+18222
+21300
+16278
+17514
+16499
+28819
+30913
+5830
+17907
+1814
+475
+11713
+10922
+19339
+15209
+8268
+3336
+10785
+31585
+25742
+17330
+5996
+4121
+5711
+16008
+30312
+31347
+23147
+31775
+12775
+21124
+10551
+10493
+6803
+1465
+3904
+1460
+15638
+16093
+18568
+8498
+32577
+9883
+12396
+10926
+22513
+23790
+26485
+30749
+32480
+19789
+7024
+11735
+22038
+23590
+31732
+3932
+10336
+22589
+13598
+29295
+2902
+5938
+31465
+875
+4500
+20437
+22485
+7943
+24294
+28962
+8520
+16296
+20377
+25939
+2844
+7970
+13283
+21491
+17930
+3061
+22266
+28946
+29684
+23642
+18545
+16559
+24781
+32181
+14076
+1787
+4811
+1685
+29702
+23169
+2411
+10153
+27934
+1274
+24765
+22416
+29859
+14563
+27546
+6382
+26267
+2890
+20026
+4718
+16162
+11770
+10299
+23078
+13637
+3418
+27992
+213
+23177
+1425
+10706
+20635
+15849
+26407
+28033
+3428
+28069
+7383
+14007
+22820
+31629
+15044
+23225
+22733
+21740
+5071
+18955
+15445
+18414
+30961
+23519
+24690
+7658
+3187
+4733
+10049
+19131
+28353
+7500
+14961
+4331
+21584
+28873
+18248
+31371
+3007
+29069
+13537
+24056
+2130
+5696
+5229
+22241
+29777
+12349
+13694
+8172
+6038
+8078
+32569
+12850
+11773
+27908
+28045
+25233
+28757
+3854
+4263
+3430
+18009
+20755
+25150
+8136
+14372
+28087
+13613
+26435
+52
+11184
+30160
+24650
+28882
+7737
+20926
+21175
+5549
+24781
+27312
+1740
+4322
+7059
+30561
+24488
+16973
+4852
+6169
+25335
+28457
+3818
+31982
+17208
+13822
+31220
+24660
+21097
+18306
+17840
+24749
+13976
+1594
+1540
+12442
+4797
+1930
+17984
+27614
+29579
+22682
+7692
+22846
+10565
+18193
+16
+27157
+21204
+12764
+3521
+13636
+8700
+942
+16216
+31526
+21276
+30737
+17331
+26212
+28016
+9011
+16465
+12061
+27932
+3027
+27484
+9425
+22334
+20980
+11618
+23362
+8535
+11123
+23649
+5562
+10356
+2364
+7615
+5278
+17504
+20975
+27886
+15877
+30827
+4086
+13383
+31867
+11629
+2440
+4686
+1791
+6722
+3116
+27504
+10348
+8478
+30112
+14595
+13855
+22040
+3658
+26447
+12846
+7660
+18223
+1679
+21297
+29023
+24375
+21599
+21860
+28610
+28420
+16591
+3641
+6814
+22748
+6477
+25192
+29805
+21381
+4297
+19783
+6733
+4238
+6029
+27594
+15496
+12615
+27018
+14205
+6375
+15447
+5927
+15706
+297
+20988
+19592
+8702
+20345
+21100
+1992
+3875
+3512
+32144
+6409
+24886
+27560
+12025
+4432
+29332
+30489
+18502
+6388
+26155
+26302
+26193
+30838
+17831
+10757
+30970
+4671
+4628
+1936
+21748
+7363
+1405
+4963
+30520
+11749
+27671
+10427
+18794
+30405
+18233
+16663
+5255
+30909
+23886
+1874
+19464
+26271
+5282
+26684
+28158
+29674
+20118
+11394
+22743
+12679
+13734
+18670
+16475
+20915
+26886
+21269
+10937
+11538
+5575
+30156
+23217
+24940
+7874
+1193
+15521
+8593
+24917
+16242
+32315
+3359
+13121
+4533
+20043
+17364
+14549
+30418
+5857
+19745
+28527
+4205
+10656
+969
+17601
+7160
+27948
+403
+9591
+20547
+14237
+21062
+13662
+26038
+15856
+13537
+26408
+13044
+27206
+14416
+22514
+32225
+26969
+9379
+2515
+8284
+11275
+18398
+5746
+13766
+4861
+24128
+28871
+15652
+13846
+4596
+28460
+30872
+4528
+26235
+14576
+29570
+8754
+16589
+30698
+20334
+29283
+1266
+23222
+5848
+27626
+28662
+18825
+6879
+18354
+11614
+21192
+3295
+24050
+31425
+27006
+3939
+28511
+27438
+26092
+6469
+20976
+8324
+5062
+19413
+25294
+25890
+16212
+31603
+29227
+6250
+1
+921
+31477
+7563
+21011
+10456
+11800
+31264
+27807
+1473
+7193
+21785
+14405
+5734
+10284
+8567
+12264
+23257
+31285
+31524
+5832
+24727
+576
+25745
+11263
+15751
+14547
+18133
+28941
+12150
+4348
+21155
+434
+10666
+30848
+25707
+28650
+4402
+8627
+9732
+28680
+19977
+24457
+20091
+2685
+23541
+3123
+9734
+31906
+6596
+15222
+2504
+958
+2561
+29533
+10413
+19098
+7164
+24515
+6655
+22201
+11240
+11426
+26192
+24287
+22100
+29542
+21129
+21922
+8740
+13057
+13836
+31346
+5972
+11727
+15696
+351
+25200
+24499
+14467
+24877
+30201
+30230
+26513
+3244
+16173
+27092
+14897
+5271
+26851
+24744
+26452
+1114
+3362
+746
+28493
+18026
+1083
+27204
+13629
+4959
+27114
+19042
+15995
+7794
+29104
+186
+24263
+726
+20473
+6252
+13090
+14141
+16511
+30132
+9296
+20649
+14909
+14188
+16981
+13644
+19971
+844
+6033
+1594
+27599
+15817
+8742
+7540
+29186
+2928
+8603
+8850
+17041
+2154
+9555
+4664
+25494
+14973
+4725
+31528
+16735
+1287
+16237
+16471
+15705
+22109
+19965
+21291
+21274
+28509
+4765
+13398
+12297
+30255
+25225
+24702
+10842
+21739
+16894
+11834
+5317
+25266
+23380
+14587
+14139
+20867
+7950
+1208
+5177
+25266
+19713
+19213
+1016
+13060
+6681
+4570
+15303
+22429
+11216
+13521
+10970
+8646
+7550
+25980
+626
+16430
+18915
+11018
+28652
+15948
+19610
+20639
+7933
+6225
+7762
+25613
+28457
+3259
+7328
+10012
+18498
+17046
+13813
+2837
+20760
+22225
+4088
+12845
+23624
+17778
+410
+19662
+10240
+14522
+1988
+1853
+31985
+3779
+17455
+11579
+6673
+11688
+4064
+5362
+27728
+7499
+26890
+25104
+14320
+11382
+16039
+32466
+12694
+12348
+27036
+12894
+27417
+31382
+13384
+14836
+25449
+17310
+27276
+23524
+32071
+27749
+11013
+9891
+28974
+12237
+28601
+3879
+2833
+20463
+8859
+15091
+19984
+23176
+20467
+13903
+20739
+17322
+3386
+5238
+9069
+555
+9230
+21747
+21798
+26248
+6350
+13416
+13994
+3575
+7855
+18728
+2154
+5419
+3130
+21043
+23709
+8929
+8037
+30025
+11328
+27557
+18996
+16655
+2809
+9603
+5717
+19017
+14890
+28233
+9031
+26146
+3023
+26492
+17821
+2704
+12286
+2439
+20795
+7484
+10741
+23720
+24472
+16650
+6338
+6163
+22007
+27446
+32577
+9984
+15311
+18126
+10240
+22998
+16912
+18614
+26923
+19834
+11559
+7371
+11843
+25631
+21592
+9529
+2513
+15221
+15186
+23809
+18288
+16569
+30219
+8567
+19339
+23127
+11468
+21644
+22718
+20303
+30523
+32255
+14820
+23691
+28926
+23975
+12653
+5922
+2810
+17833
+11587
+23290
+32630
+29328
+29323
+16603
+17691
+3586
+25349
+1563
+31645
+19116
+2890
+28368
+30694
+18965
+25865
+22929
+7460
+23937
+29317
+22513
+20700
+21180
+4543
+26164
+7403
+17603
+13876
+22080
+17004
+32253
+17579
+27155
+23788
+25771
+20573
+22005
+5242
+6206
+15882
+20366
+16391
+12722
+15889
+1677
+23811
+7907
+7484
+8009
+19116
+1276
+31683
+5138
+27356
+18099
+18699
+4222
+31325
+13209
+23919
+28496
+14409
+1401
+6606
+24196
+19798
+6856
+7256
+9857
+9151
+28827
+9217
+23166
+20289
+27965
+5958
+10910
+13875
+6053
+10746
+30831
+3728
+19849
+10143
+27108
+10980
+13148
+13003
+32573
+19574
+3413
+32286
+13444
+30497
+29908
+21099
+14649
+1850
+9615
+3154
+3985
+6522
+21277
+15556
+12793
+6977
+2655
+14816
+23706
+22540
+12934
+7860
+2541
+28184
+8401
+7985
+10155
+3667
+3268
+25042
+21735
+26708
+11688
+8529
+3441
+5873
+28475
+25083
+20532
+14311
+23043
+11816
+1946
+25397
+29375
+3302
+8499
+18032
+16658
+14683
+15416
+21617
+6054
+27713
+24381
+15502
+26731
+8372
+19823
+29524
+14701
+185
+4766
+28239
+23926
+10306
+25240
+1947
+30701
+7518
+25377
+19751
+23250
+26322
+12380
+2349
+6183
+18630
+1710
+26019
+21870
+26267
+29346
+10966
+30848
+21458
+13917
+16704
+29138
+28725
+30818
+4175
+20869
+11500
+5091
+15483
+29014
+1056
+4862
+12958
+28247
+26289
+15663
+8658
+12853
+32528
+14607
+15225
+11333
+2093
+32591
+18898
+18527
+3473
+23404
+18632
+1383
+2004
+7519
+4128
+29018
+7661
+32482
+22407
+2014
+9559
+4425
+290
+12938
+14098
+13985
+11994
+6886
+9099
+6502
+14470
+9476
+25232
+7517
+5177
+29403
+22962
+25133
+14207
+17446
+22034
+3613
+19382
+25342
+24340
+14799
+2593
+7464
+32187
+9484
+22031
+5060
+25300
+32144
+7871
+25819
+9916
+19334
+31918
+13121
+5861
+14786
+17794
+13667
+17416
+16761
+3457
+22097
+5457
+9687
+1190
+1189
+9671
+26153
+23912
+684
+16262
+9184
+6625
+12857
+23004
+7191
+31334
+24419
+5174
+6999
+14753
+12177
+6426
+6080
+3501
+7006
+23249
+669
+17082
+3791
+31370
+10781
+11332
+28640
+4946
+3369
+20660
+7810
+6629
+11806
+4650
+22575
+14719
+4345
+28941
+22165
+11174
+26590
+19469
+18021
+12859
+3670
+30665
+1818
+22752
+31805
+22336
+31498
+31462
+18261
+17137
+14995
+24509
+19506
+16295
+3802
+12217
+18324
+7424
+4131
+3430
+216
+12711
+2408
+24471
+25661
+10550
+14571
+2466
+15641
+30438
+12246
+16812
+19985
+31810
+12137
+29488
+30284
+8806
+7870
+3442
+31880
+8114
+14968
+26054
+29329
+18784
+6625
+13409
+29585
+1236
+14089
+25987
+18908
+16406
+1506
+29386
+19330
+28362
+13444
+9247
+4694
+4041
+31648
+3287
+17417
+26965
+8427
+23636
+25316
+5555
+28189
+1168
+22281
+11820
+965
+10995
+3688
+1748
+29347
+24174
+17436
+19522
+9255
+20342
+30940
+26722
+16711
+30480
+4099
+28130
+21521
+22306
+14839
+15297
+9747
+19732
+11198
+28133
+1762
+1454
+8102
+1858
+23480
+19595
+24860
+17421
+25654
+25939
+32263
+11787
+6549
+22451
+19892
+15940
+9071
+29824
+9661
+20718
+945
+30393
+11431
+15412
+7229
+5571
+30666
+16814
+16319
+24492
+23159
+1907
+26789
+17637
+26745
+32580
+27845
+8611
+29132
+21155
+379
+25618
+31951
+8436
+8645
+20322
+1789
+32222
+15333
+25601
+17249
+29483
+24984
+7087
+16192
+11538
+10953
+17393
+8629
+18732
+14247
+1588
+3059
+13536
+31609
+28674
+25944
+9918
+13292
+6050
+26511
+13184
+25850
+12276
+5629
+13696
+12662
+4117
+11251
+4710
+11442
+31746
+17714
+26
+20683
+32644
+22378
+15075
+19042
+7222
+19437
+4631
+16448
+27485
+28387
+10569
+19221
+918
+14974
+21784
+23734
+20354
+32355
+20951
+14705
+27528
+2518
+23819
+15941
+26998
+30398
+4236
+3640
+19326
+1654
+31316
+27181
+24791
+30874
+8686
+26057
+9817
+15606
+29127
+7226
+27658
+22029
+3402
+17499
+25864
+13843
+23340
+28781
+15135
+6916
+22570
+26496
+9269
+21217
+3995
+22122
+32178
+24270
+19480
+25726
+23885
+10974
+31835
+32327
+11158
+23789
+3801
+5176
+6201
+2701
+29055
+32119
+15799
+25493
+27613
+21757
+25876
+8926
+28448
+30202
+9831
+4578
+14906
+3497
+8395
+9637
+7103
+26950
+18985
+29983
+3480
+19434
+4696
+11520
+3660
+17458
+23176
+23424
+1802
+24978
+25056
+29805
+24880
+22976
+10719
+18653
+22045
+14555
+22013
+7347
+847
+27516
+18099
+19403
+10866
+27793
+28062
+23226
+4311
+20455
+6726
+18007
+13274
+22967
+17256
+1713
+7728
+2782
+14302
+8437
+27728
+15681
+13180
+19605
+6908
+24684
+5353
+29564
+29076
+21278
+8756
+21095
+9720
+2493
+13011
+3039
+10866
+28777
+14265
+6908
+16825
+10465
+4349
+415
+17372
+15791
+280
+5448
+23496
+21888
+1805
+11020
+25432
+248
+30555
+12476
+20239
+7520
+20430
+7098
+1367
+17877
+18547
+13798
+23913
+27841
+5380
+2735
+4040
+21230
+16686
+26900
+20315
+3962
+23702
+20712
+31761
+4033
+2341
+9554
+19334
+29269
+28775
+9407
+16800
+4031
+217
+21454
+6445
+10886
+5443
+11700
+25013
+27074
+31966
+4698
+1787
+3240
+16843
+18987
+30594
+13337
+13231
+24617
+21999
+24398
+20473
+11289
+17647
+290
+15570
+13191
+6691
+16133
+10
+14935
+568
+20650
+29760
+17145
+3645
+30416
+3102
+16853
+14541
+24466
+17647
+22247
+3443
+19444
+14154
+2986
+3897
+4878
+14372
+27928
+4099
+27611
+18213
+2987
+19780
+22240
+11240
+14120
+32716
+21034
+5572
+7198
+15333
+453
+25466
+14585
+5740
+26098
+6864
+4645
+24993
+25742
+28137
+6075
+10946
+22637
+9827
+28350
+13657
+2149
+17048
+11419
+13835
+17299
+6550
+2502
+30082
+22456
+9162
+28797
+20533
+9783
+3876
+19538
+25471
+31856
+26418
+15261
+4146
+31239
+4957
+5336
+17160
+7856
+4171
+27104
+6898
+24860
+16687
+14854
+157
+25774
+3691
+24826
+2965
+12292
+637
+3947
+23288
+8015
+7878
+3867
+31909
+28724
+10222
+6426
+7138
+22945
+2810
+21014
+22455
+23854
+5726
+8988
+13982
+31262
+26873
+24362
+27357
+7879
+25152
+7064
+27902
+29391
+9126
+5683
+8593
+26891
+6720
+12830
+8188
+5746
+29659
+26482
+3583
+11372
+4224
+24944
+19308
+15492
+9798
+30354
+6271
+23470
+15953
+25231
+20667
+16948
+2955
+31642
+2403
+1829
+20292
+17092
+30645
+19168
+28326
+12790
+19748
+10245
+13524
+30064
+11847
+24939
+28087
+11171
+9958
+4185
+2450
+29844
+26965
+30231
+2827
+12394
+16399
+15157
+28625
+12500
+28098
+2300
+13441
+8134
+14588
+20780
+22161
+29059
+10597
+20737
+16391
+25392
+3582
+23990
+11024
+19880
+29721
+15850
+29317
+22213
+15382
+2521
+19684
+12952
+19849
+13137
+26018
+17644
+1928
+17035
+25575
+30714
+6798
+4241
+26844
+2768
+4512
+27074
+4771
+10747
+19745
+3526
+436
+11259
+5443
+15023
+27374
+22714
+25821
+4683
+21981
+18412
+6764
+28324
+28840
+22166
+14512
+29731
+18122
+11143
+29190
+2778
+8800
+5198
+13643
+30584
+11295
+22437
+26381
+17952
+12440
+1158
+14036
+26047
+1159
+4410
+12133
+19426
+11355
+22527
+26638
+16763
+13203
+15817
+12924
+15725
+1897
+7024
+5355
+9026
+25254
+21968
+30693
+1598
+10269
+20268
+11732
+26172
+13649
+30137
+8874
+1716
+19829
+26371
+12715
+7402
+8824
+11758
+9215
+2959
+7559
+22534
+9939
+15442
+24684
+11510
+28227
+15070
+30203
+30902
+13629
+24372
+8527
+30972
+6547
+14729
+867
+8237
+7145
+668
+11849
+2855
+27221
+18779
+7548
+387
+6735
+28452
+19246
+27191
+27604
+21929
+9635
+8029
+18499
+19665
+2623
+19495
+24401
+29347
+25980
+31220
+10618
+18197
+29505
+2417
+4939
+24713
+7038
+5477
+28298
+29697
+5559
+30940
+32673
+31978
+16623
+18352
+8355
+26989
+13045
+6143
+7183
+25585
+4961
+30083
+7876
+10950
+22121
+15399
+24554
+11818
+4639
+29479
+23303
+998
+19123
+22737
+16665
+3574
+26948
+14762
+5490
+3465
+26717
+28264
+3815
+16067
+14540
+11544
+15759
+15805
+6016
+32278
+9748
+18349
+26368
+2696
+6496
+18551
+8307
+10807
+16441
+6974
+17714
+4338
+14389
+16374
+28996
+30840
+12446
+9031
+23049
+16724
+11895
+13966
+27938
+159
+30036
+32290
+11984
+1366
+5547
+24750
+30789
+21825
+17430
+15806
+12009
+759
+26014
+6998
+18843
+5192
+20675
+20793
+13452
+3368
+30975
+31898
+6577
+2707
+27444
+19438
+21168
+27779
+26332
+12409
+11489
+12736
+24482
+23825
+25324
+10826
+4460
+2345
+8870
+28373
+12029
+10600
+15273
+29875
+25086
+10362
+4254
+11017
+11062
+5842
+28633
+11752
+6701
+18364
+13095
+25293
+8148
+18974
+14177
+562
+26885
+6048
+14238
+13783
+27071
+21364
+8581
+20188
+30818
+3782
+16895
+997
+28813
+28554
+3173
+3310
+5382
+24617
+23482
+14012
+9515
+23534
+17416
+8187
+17504
+9084
+18852
+26914
+25979
+7886
+16054
+18373
+2518
+25540
+12063
+14642
+12693
+2063
+25072
+11575
+19348
+12883
+15998
+26952
+8680
+23085
+27630
+4393
+26999
+21088
+29188
+10811
+10399
+8837
+4996
+18
+16784
+6044
+20456
+23928
+10326
+28720
+6549
+11675
+17064
+23148
+8419
+18468
+27813
+28329
+26617
+18738
+15992
+3163
+28314
+27431
+8203
+3561
+839
+23641
+7755
+10354
+5687
+6393
+10275
+25713
+27482
+5774
+28467
+12218
+32463
+29649
+21216
+15940
+15217
+19918
+21076
+18305
+12910
+30845
+29957
+16379
+19558
+29142
+23385
+28991
+2472
+12183
+2465
+29899
+30342
+1585
+17121
+2261
+5033
+27235
+15769
+11387
+30789
+6905
+6211
+12685
+30684
+24784
+20456
+11336
+30844
+13459
+30704
+580
+27645
+28272
+22223
+25866
+11871
+9701
+32369
+141
+1048
+6020
+3745
+2409
+9080
+25678
+4541
+18927
+12559
+4974
+22023
+8091
+20890
+13124
+2345
+779
+3662
+17380
+27169
+23766
+6138
+19727
+16126
+22505
+21127
+20121
+20663
+18975
+22207
+19557
+18963
+32075
+29802
+8248
+27529
+19173
+23319
+25734
+25363
+18398
+28559
+16967
+26757
+10294
+14916
+4552
+9558
+21252
+20314
+31720
+24184
+20162
+28279
+30042
+1536
+4386
+30513
+26216
+27798
+13877
+5099
+23661
+17587
+3974
+29960
+13617
+24869
+5967
+26204
+32285
+26551
+23518
+6105
+22616
+12437
+25211
+21790
+20041
+17758
+29585
+27723
+30736
+8622
+25449
+16327
+16926
+23825
+16847
+7119
+27741
+30566
+3830
+31163
+8528
+25278
+21106
+23047
+23622
+16011
+24227
+17057
+3597
+13392
+11788
+29078
+549
+767
+32219
+26643
+1204
+2303
+17692
+28164
+27166
+7843
+5236
+28322
+8545
+14207
+20175
+20615
+580
+159
+495
+4109
+4833
+7743
+32094
+30106
+29558
+26895
+3886
+23693
+31887
+27505
+27225
+7681
+9267
+12320
+23057
+16411
+30463
+5854
+5613
+20791
+9628
+25068
+5095
+30737
+27532
+3607
+10600
+15072
+30069
+4148
+6330
+31886
+29202
+16438
+20552
+32267
+16191
+30224
+28095
+24699
+23000
+12720
+26994
+30234
+32423
+19858
+27757
+17793
+22203
+21543
+3939
+23370
+1011
+30539
+3175
+25824
+32709
+3214
+2305
+19535
+30681
+26611
+24374
+11816
+5184
+10096
+21563
+3278
+29916
+22645
+13094
+14296
+29763
+7302
+16875
+31392
+27871
+29865
+23444
+6250
+6382
+2716
+22539
+26937
+16003
+22299
+31828
+4746
+25594
+272
+29547
+9910
+11480
+14182
+19651
+25931
+19149
+8641
+15938
+6469
+15777
+23593
+17150
+27426
+16858
+1621
+26421
+619
+6396
+3157
+21165
+13743
+20680
+12615
+28408
+7758
+26863
+29375
+8079
+627
+30927
+13383
+23105
+12005
+26825
+11838
+2032
+15222
+26732
+13969
+5050
+15596
+18694
+19171
+16114
+16923
+19493
+19661
+18786
+7381
+5256
+12655
+7917
+9699
+11694
+9709
+12298
+11516
+29060
+11959
+16158
+1026
+19105
+22992
+2041
+9321
+13596
+289
+16615
+14458
+11045
+12724
+24857
+21049
+22688
+13842
+9876
+28881
+21995
+5303
+11249
+438
+11352
+29234
+23004
+14047
+11663
+11216
+8253
+22287
+29037
+503
+9390
+26751
+8259
+12282
+8761
+7111
+24168
+10013
+14175
+5423
+4635
+23744
+1457
+24752
+4110
+11499
+18386
+30795
+17332
+6107
+21785
+1422
+26587
+9280
+5938
+31698
+15172
+7437
+2556
+14380
+1879
+15004
+9601
+2004
+6503
+27582
+13817
+19770
+20798
+31082
+20435
+31157
+2732
+26900
+18878
+32216
+10195
+11690
+11196
+2484
+14202
+30595
+26639
+28647
+24002
+15654
+25653
+12482
+13357
+7039
+2476
+6278
+16542
+25335
+5634
+4979
+11483
+32023
+4433
+6227
+4678
+576
+22061
+30636
+31649
+12892
+28992
+24689
+20379
+30143
+7603
+2769
+22992
+1463
+26158
+9192
+6927
+21289
+29728
+9781
+7446
+20462
+27675
+9133
+21559
+10010
+31321
+5529
+7130
+18762
+21682
+4180
+7528
+22565
+14516
+26298
+4536
+32496
+32201
+19572
+2687
+20448
+10904
+12743
+12467
+22883
+7602
+19955
+15258
+15246
+7087
+11245
+8233
+7170
+2852
+8155
+9400
+1253
+3467
+27010
+1851
+32000
+12193
+4330
+15591
+7787
+10725
+22274
+30138
+15330
+3984
+23013
+30995
+6715
+28395
+15610
+24297
+17379
+5894
+24412
+14306
+11895
+23607
+16043
+31605
+1105
+7820
+8536
+16248
+12218
+6111
+32122
+29250
+29909
+9853
+31677
+22921
+24702
+12781
+31377
+4462
+9748
+11463
+28952
+10609
+32229
+7636
+32126
+4418
+10002
+13928
+3330
+23531
+19336
+8165
+19306
+14509
+13105
+7979
+32748
+13656
+19074
+16722
+10436
+12878
+25110
+18292
+26251
+22689
+25927
+24792
+8879
+21018
+24653
+11699
+29387
+16007
+12343
+7712
+6458
+26661
+30222
+12892
+31221
+31076
+19260
+1579
+16780
+1926
+18560
+1897
+18460
+22822
+7470
+29406
+27101
+25058
+28256
+8154
+26341
+6018
+30256
+7582
+10697
+29831
+446
+32642
+22876
+21809
+16273
+29437
+29275
+27853
+24142
+8351
+31512
+3650
+12113
+10082
+19483
+11548
+15937
+28073
+8092
+31245
+3512
+28863
+18488
+1841
+25840
+6831
+6860
+3290
+29262
+164
+19773
+1298
+14039
+2970
+22763
+21723
+13219
+19733
+21867
+15998
+432
+6000
+923
+27973
+256
+25052
+29021
+14076
+12676
+3597
+9759
+23998
+15440
+28236
+25467
+25215
+9338
+28883
+26175
+26574
+13174
+24179
+4008
+11210
+13759
+15350
+19304
+17950
+12982
+32666
+2083
+26847
+16526
+23699
+24373
+14828
+31463
+5838
+30864
+21308
+9750
+4958
+13283
+11587
+13968
+28190
+5006
+28832
+15832
+26587
+4316
+13070
+32176
+24522
+1634
+11204
+30715
+10146
+11641
+8084
+24967
+13565
+11089
+10258
+29715
+26777
+17150
+20740
+10627
+13720
+26128
+25462
+30448
+21076
+21062
+5312
+6138
+15919
+22352
+31791
+17199
+4969
+31539
+5069
+8261
+24982
+4194
+16613
+21431
+24254
+19090
+29285
+25643
+29543
+15950
+12213
+17422
+17072
+32403
+12023
+6390
+30974
+16615
+11068
+17663
+1362
+28261
+32514
+8877
+17683
+12737
+8591
+31649
+21229
+5841
+15810
+11066
+5990
+19503
+16547
+19451
+31811
+21769
+30575
+14341
+10915
+27740
+11018
+25576
+22641
+3690
+3982
+22907
+25380
+30694
+26194
+23201
+15014
+3809
+29693
+4430
+27123
+4889
+10904
+6445
+11093
+1771
+20295
+32004
+23064
+7788
+468
+17716
+30556
+30861
+9785
+2092
+10949
+7678
+25817
+2621
+650
+26930
+32575
+11356
+2788
+10721
+17326
+6736
+21518
+5831
+15975
+13831
+16701
+12014
+10862
+22304
+6648
+9948
+1973
+22030
+678
+14712
+15205
+6642
+15063
+12613
+27288
+18690
+20359
+31153
+10428
+10300
+12260
+28410
+3914
+5823
+2855
+21070
+20946
+1203
+9451
+25669
+4332
+7282
+8505
+30084
+1970
+32660
+1420
+28204
+12716
+26303
+24111
+7428
+8343
+18628
+24303
+30243
+10218
+9688
+18168
+27455
+12041
+14315
+30174
+3900
+27848
+4081
+20455
+2034
+17680
+19113
+28251
+13727
+10425
+12006
+17677
+32491
+10229
+4643
+22228
+18591
+31564
+30027
+25214
+26240
+1085
+25045
+16491
+22655
+12776
+20088
+612
+12751
+26970
+15272
+26710
+2068
+4067
+18107
+28097
+16560
+15058
+31711
+4057
+11646
+20014
+23721
+10998
+16073
+21254
+26656
+11441
+26020
+9888
+10942
+31908
+9955
+10627
+31253
+17432
+17421
+29518
+17692
+30617
+12537
+28543
+17178
+12493
+8594
+18234
+32549
+4493
+5221
+11558
+25918
+26275
+30587
+24813
+4944
+15599
+18293
+11197
+21795
+7499
+473
+5501
+8101
+11771
+30715
+9701
+13116
+25647
+30188
+4206
+28906
+25714
+14231
+19546
+22956
+781
+5759
+11658
+28964
+4195
+31417
+17738
+9889
+23029
+11459
+32199
+16548
+8968
+2570
+24393
+26048
+25544
+346
+27378
+31611
+30179
+25062
+29791
+10701
+8644
+31216
+17660
+20558
+29652
+13100
+13193
+7511
+32651
+20622
+28298
+17774
+23423
+11193
+14260
+18399
+21522
+11854
+15616
+31953
+21495
+13398
+16818
+17692
+27028
+12443
+13729
+8421
+25264
+23249
+3933
+19751
+23089
+6474
+28104
+1291
+20016
+2037
+16652
+15302
+2270
+26688
+1844
+4626
+3118
+30918
+27879
+28116
+13350
+1382
+5094
+4931
+14932
+1891
+9110
+5190
+16143
+3963
+12925
+24063
+20134
+14896
+26100
+19787
+18736
+6061
+6106
+10929
+1600
+1248
+20418
+4720
+13926
+2110
+28951
+15111
+29116
+13580
+18444
+17364
+20438
+5487
+20727
+21897
+24219
+21306
+16929
+14495
+28243
+23006
+14552
+10867
+2883
+14329
+31689
+2913
+22215
+18110
+2971
+5824
+22982
+12659
+10582
+6301
+17204
+26053
+14054
+30131
+27459
+9504
+7231
+12801
+11748
+8284
+10633
+10564
+29335
+13724
+20708
+22331
+4207
+9151
+4707
+19790
+31550
+27622
+7599
+8737
+20656
+2059
+12460
+7788
+8108
+10303
+30352
+1525
+16389
+9696
+29076
+31850
+12661
+14770
+10280
+8991
+3725
+10449
+26677
+5090
+13474
+18021
+12312
+17757
+7526
+24731
+9890
+30496
+10993
+30893
+685
+28093
+16812
+17777
+9794
+27950
+15191
+8700
+26581
+4554
+13139
+18074
+19894
+3945
+3301
+14826
+28600
+27657
+5270
+20825
+24531
+27453
+7031
+19834
+22965
+12061
+29757
+8087
+15788
+16404
+12648
+31876
+5607
+6329
+26640
+17983
+3473
+28051
+9713
+3993
+23555
+1224
+3420
+14028
+20323
+6578
+6175
+29036
+5086
+29132
+17192
+7425
+21533
+32634
+28592
+15354
+19421
+28811
+4479
+23721
+4593
+15263
+5286
+15895
+661
+16625
+13419
+12009
+7383
+9287
+24360
+1615
+112
+4186
+24574
+26453
+21288
+4198
+14700
+6757
+2835
+26233
+14870
+8923
+31628
+20973
+20367
+26830
+20772
+13092
+13265
+559
+31949
+5882
+14180
+11258
+23372
+13729
+7
+9150
+26545
+23806
+18849
+3003
+24831
+21759
+22378
+6761
+4129
+16248
+5109
+27115
+27693
+21375
+2365
+17468
+27620
+29185
+32053
+25175
+29375
+12941
+3510
+31993
+28625
+16538
+1687
+27250
+10327
+6591
+5784
+13064
+2625
+2885
+32693
+8406
+7550
+5087
+15787
+17663
+32626
+17199
+4019
+24462
+12864
+13501
+12863
+3380
+8315
+4559
+20522
+15732
+13173
+28322
+195
+14145
+11495
+17110
+19126
+15558
+6401
+20033
+18914
+22968
+25175
+6628
+27505
+3876
+11610
+5081
+22218
+5857
+14216
+25701
+17104
+12114
+1152
+18289
+29148
+27877
+23019
+12424
+30761
+9767
+6519
+251
+3549
+20252
+24945
+27044
+18783
+21128
+814
+5918
+1901
+22340
+2684
+31633
+13035
+6466
+6532
+26376
+32528
+12990
+32353
+16341
+26743
+11940
+26873
+29558
+6065
+2330
+12950
+22221
+20366
+5308
+3744
+24789
+30946
+23699
+4556
+7942
+25708
+15351
+7213
+10097
+3201
+16331
+18126
+9160
+21781
+29704
+24042
+26412
+11442
+6581
+27747
+5405
+28040
+11409
+16680
+1660
+27747
+9275
+20624
+22181
+2651
+31965
+23657
+4563
+626
+19017
+21692
+20917
+6409
+18854
+22206
+8617
+10100
+20034
+11584
+30609
+8526
+23227
+710
+22281
+23258
+24456
+2901
+12028
+160
+22750
+31938
+18918
+29319
+17049
+6453
+14215
+22967
+15096
+12208
+9287
+25957
+117
+13178
+22396
+24863
+1546
+18004
+24243
+24511
+19797
+25247
+22508
+1443
+16982
+26783
+18135
+6475
+24500
+25550
+18327
+22036
+28310
+30919
+2527
+21882
+70
+9394
+23541
+400
+29225
+15322
+5619
+19908
+19848
+19779
+8202
+16077
+20251
+10642
+3094
+7209
+6080
+4220
+1499
+13986
+2470
+13128
+2531
+28522
+28367
+3046
+24671
+16081
+17902
+21539
+5850
+3562
+20960
+1468
+9000
+17914
+18292
+16839
+12685
+27247
+24752
+8065
+1908
+8585
+22963
+13043
+6353
+7665
+5699
+19656
+1695
+30597
+30344
+14468
+14176
+20211
+161
+6367
+6128
+23350
+31751
+2773
+30713
+6830
+23769
+2184
+25267
+32707
+11239
+1359
+9288
+14885
+11912
+4051
+13171
+30559
+14165
+20252
+1724
+19089
+16140
+26648
+11495
+12263
+12712
+25513
+8166
+25487
+971
+16732
+17901
+26899
+6847
+17875
+28359
+2591
+7555
+22950
+18693
+12773
+608
+14106
+21300
+21487
+6504
+19766
+17115
+32072
+15006
+2283
+15618
+6678
+29651
+21103
+14946
+6596
+14629
+31492
+2285
+22251
+4700
+2757
+26728
+22393
+7040
+6328
+678
+14823
+5138
+28462
+4518
+249
+6690
+27741
+6947
+23838
+5600
+19783
+7950
+428
+657
+7198
+12711
+29766
+31364
+9465
+3192
+23586
+4300
+2331
+9099
+20186
+5454
+20761
+28915
+5126
+19701
+4948
+7968
+11270
+23324
+26862
+6902
+19338
+10641
+14181
+505
+10211
+27743
+29606
+20225
+30262
+5816
+11767
+30573
+19663
+20738
+30885
+25052
+29481
+26312
+6868
+9963
+22300
+6620
+340
+25611
+15494
+13521
+14359
+8934
+1426
+30705
+15486
+19960
+5825
+5759
+13691
+19135
+26588
+22229
+25795
+32482
+20495
+23276
+25075
+26726
+9655
+16122
+26434
+27789
+18675
+30932
+1202
+32382
+8417
+20422
+10501
+12251
+2675
+17129
+3404
+19392
+29839
+504
+967
+18582
+3593
+18783
+10763
+26005
+20838
+8333
+11833
+20559
+19994
+13153
+24701
+21340
+6061
+8539
+3309
+23623
+25993
+14848
+6255
+22617
+25399
+22584
+31390
+25863
+19599
+3281
+15760
+24929
+29605
+5099
+22716
+26869
+23451
+25840
+5514
+29306
+26957
+6004
+25494
+15301
+16796
+4488
+19100
+32156
+25011
+23585
+13963
+5706
+530
+17446
+16455
+16570
+13032
+27517
+12830
+32589
+20431
+17232
+29129
+1490
+19157
+8233
+3964
+28334
+5975
+5250
+14672
+3800
+25119
+8111
+25280
+23294
+11671
+25269
+5597
+5765
+13412
+21867
+3294
+29303
+218
+13695
+20652
+6804
+8793
+9349
+14556
+18683
+6024
+14731
+12159
+27459
+15703
+16024
+12167
+30547
+7764
+18613
+12805
+1816
+424
+5218
+30366
+13831
+23320
+24627
+25286
+26755
+17157
+9735
+13858
+6791
+22899
+22174
+26317
+29410
+5510
+26044
+27458
+23641
+12
+21758
+13974
+23364
+30789
+17401
+12240
+17529
+6326
+8374
+17333
+21197
+15722
+20190
+7988
+27532
+31414
+3919
+17754
+23160
+11229
+2772
+1183
+9497
+18041
+26123
+9422
+30888
+12801
+5362
+22898
+7889
+551
+30326
+29398
+4159
+19409
+9479
+18244
+5731
+3193
+8644
+30418
+30483
+22034
+21902
+11881
+18472
+23996
+384
+9841
+7533
+10385
+8265
+23445
+25481
+2686
+5584
+13191
+16528
+616
+16687
+11716
+29590
+15291
+14601
+13632
+18441
+28781
+15314
+9421
+20071
+28301
+7207
+30112
+1742
+28849
+16039
+841
+1505
+12339
+13260
+17543
+12933
+25450
+4755
+3759
+16612
+31048
+14071
+26979
+5582
+9363
+26180
+20582
+7147
+13344
+32414
+3468
+3039
+15084
+561
+11956
+23338
+28531
+3381
+25606
+30898
+18335
+16600
+22945
+31736
+30872
+6761
+7592
+8388
+27124
+19800
+6647
+19705
+5718
+6775
+11284
+8020
+8396
+29141
+30430
+3881
+27499
+30440
+12788
+14097
+5334
+6613
+12314
+20734
+11836
+9547
+10916
+20530
+17162
+5326
+7266
+7480
+26640
+6965
+3640
+9693
+7474
+29772
+434
+31247
+13017
+5741
+9132
+18612
+17750
+25686
+29582
+4054
+2446
+32044
+30650
+2495
+8624
+27971
+4922
+27974
+21444
+17961
+24673
+18420
+4875
+24140
+5605
+7017
+20301
+4045
+3353
+15387
+15494
+8644
+27936
+5592
+14264
+25222
+10053
+29970
+17320
+10378
+14035
+4634
+18050
+12433
+9660
+8450
+25795
+25930
+11834
+549
+2915
+24371
+25011
+22618
+17323
+17762
+29661
+32765
+853
+4832
+2547
+29239
+19638
+6282
+13886
+25773
+18091
+16223
+20149
+592
+3238
+12703
+6131
+7802
+10310
+22087
+688
+6500
+8192
+106
+2677
+14863
+22356
+8730
+30235
+7194
+5220
+28362
+18469
+12141
+31547
+32660
+30852
+31087
+7525
+4602
+1060
+7358
+11314
+18845
+4369
+12204
+3287
+8091
+6166
+5191
+32505
+20528
+9201
+32398
+24985
+23185
+12588
+6861
+23604
+12970
+25211
+21506
+4286
+27606
+20834
+19840
+25203
+7595
+31204
+6436
+24451
+18802
+1298
+5557
+19983
+26353
+8797
+21620
+24447
+23387
+23481
+31584
+4924
+2636
+22170
+21625
+10700
+22791
+4109
+25956
+16382
+6835
+32513
+17697
+17727
+31579
+16805
+5283
+7833
+4981
+3120
+20949
+18355
+5609
+13243
+1624
+20549
+13659
+17335
+16652
+15613
+16157
+19926
+30809
+28019
+15522
+31511
+20802
+5416
+8363
+27744
+22547
+9190
+11701
+27958
+9000
+19380
+26963
+26894
+13344
+23834
+32210
+9643
+15911
+5182
+6863
+21182
+24121
+17195
+29223
+11368
+13341
+7768
+31194
+6411
+23048
+7179
+21563
+18079
+11578
+30836
+15554
+1043
+22932
+10117
+27342
+6275
+25614
+31681
+25970
+22733
+14909
+16851
+9014
+28392
+25356
+24510
+20885
+16806
+16208
+20227
+6000
+4331
+32469
+83
+7366
+11869
+13014
+19982
+7270
+4818
+26246
+7006
+29664
+10048
+7630
+25890
+19563
+12259
+3928
+32639
+2334
+16742
+18070
+30129
+31767
+4819
+14131
+19975
+19002
+22774
+21047
+21894
+10983
+24382
+8386
+16005
+13469
+23214
+11325
+6042
+16457
+18093
+14644
+19104
+31435
+27349
+28680
+29772
+18648
+14653
+10041
+22857
+26329
+2362
+27978
+18642
+6236
+5612
+3236
+4509
+10286
+5833
+13839
+13993
+25066
+32671
+19107
+12610
+8483
+19145
+29564
+10699
+29240
+1962
+26081
+17372
+31812
+10018
+19213
+1620
+5572
+21444
+8537
+4386
+10923
+4337
+4556
+2550
+15258
+12379
+603
+30884
+30105
+15709
+25566
+14129
+20183
+17770
+1419
+13813
+17685
+9073
+31444
+19381
+548
+26246
+9329
+7963
+27002
+7441
+2063
+23277
+14981
+19582
+12570
+19162
+29139
+29673
+31870
+2918
+11440
+30340
+6866
+9908
+9521
+1063
+27480
+14275
+3458
+7184
+7273
+26377
+20790
+29152
+29182
+6077
+10745
+22104
+20308
+27703
+17310
+22696
+23464
+12415
+8939
+5858
+4218
+24951
+6794
+32690
+12211
+16592
+29062
+29203
+2352
+29229
+10526
+7829
+31132
+19536
+28179
+20932
+25322
+10875
+9241
+14200
+25217
+11672
+3807
+9086
+17949
+30070
+25445
+11605
+31137
+3783
+18303
+14286
+21749
+25491
+1786
+20475
+17474
+2499
+13516
+24936
+15852
+11565
+6330
+3928
+4767
+12802
+17293
+3270
+16763
+11084
+10580
+10369
+24135
+24139
+16931
+11131
+15026
+12645
+14209
+9568
+2375
+12609
+28838
+16306
+27086
+12021
+9641
+11156
+19703
+2738
+20588
+16256
+5514
+22935
+9584
+6272
+14748
+32637
+11384
+16438
+29637
+18983
+1869
+4740
+19792
+5373
+6894
+16119
+7198
+15854
+5475
+13487
+31572
+7387
+16467
+24808
+30015
+13557
+4812
+24622
+3934
+808
+29714
+28852
+22487
+17078
+22957
+7780
+3443
+11017
+11905
+13483
+25981
+15826
+28759
+1976
+32382
+17083
+13653
+32109
+20332
+26849
+12209
+25838
+3586
+506
+7308
+31071
+5429
+8509
+26194
+27871
+29257
+14574
+12573
+11776
+9617
+28794
+4526
+28297
+1011
+340
+23295
+22499
+9718
+27116
+12599
+27593
+4069
+10624
+18435
+29521
+4981
+2883
+31682
+20488
+30140
+19479
+16788
+3632
+15302
+5893
+30057
+24152
+1079
+31626
+31491
+13207
+16417
+4864
+16843
+16574
+13964
+22025
+13872
+15633
+23046
+4877
+28362
+17168
+31057
+699
+26409
+22301
+31123
+17212
+19034
+9253
+19424
+14934
+1849
+26711
+31246
+27393
+17961
+25435
+3205
+17726
+15366
+31358
+9960
+9667
+22046
+30585
+18769
+2965
+13467
+32396
+26714
+5338
+14733
+31107
+25249
+29152
+25274
+30939
+5558
+7291
+27701
+18491
+23247
+27229
+9068
+15179
+27906
+27247
+23257
+32316
+20067
+31319
+2277
+6852
+25646
+13633
+27459
+17570
+2756
+5834
+29661
+25638
+19363
+28691
+6244
+9528
+23709
+26929
+25339
+4568
+14304
+31862
+1111
+16092
+11137
+22572
+26828
+32661
+12519
+18124
+15572
+8622
+27404
+11218
+8241
+15587
+10864
+18419
+16867
+19576
+2382
+1627
+2625
+26275
+30274
+9212
+10237
+30241
+19079
+6931
+8870
+456
+8940
+27609
+12277
+21995
+5230
+3869
+5802
+17971
+3900
+24136
+3770
+7773
+3323
+24045
+4885
+29207
+27923
+16471
+22503
+11366
+14403
+2909
+23278
+26909
+5146
+2488
+15896
+27129
+8499
+30265
+23898
+2174
+20418
+4069
+10453
+27095
+29890
+7614
+23993
+30182
+8077
+3835
+16507
+2365
+10321
+533
+30341
+28104
+2560
+23688
+10110
+27077
+21784
+30056
+22456
+14307
+21574
+27034
+9137
+31518
+4473
+17674
+22192
+5617
+11139
+18406
+31627
+4820
+23395
+575
+18197
+1805
+8535
+29881
+22308
+22786
+26237
+15244
+8948
+2184
+15592
+32708
+21083
+12535
+23100
+21525
+22920
+10155
+9949
+16793
+19117
+22094
+17919
+13724
+24881
+30567
+19090
+31967
+26193
+9466
+13952
+21325
+2088
+21454
+19421
+15945
+570
+24920
+3988
+2171
+6484
+9952
+1841
+29031
+26268
+14771
+20491
+19102
+9673
+30557
+15546
+7678
+17683
+7455
+7911
+8987
+24524
+27427
+591
+14871
+31587
+15915
+16541
+12069
+19353
+30574
+30161
+12953
+5165
+17202
+25956
+10984
+2460
+32406
+1229
+23760
+14251
+4247
+22977
+22646
+32675
+19971
+29028
+2546
+11767
+30468
+26250
+19342
+11621
+28270
+11318
+18407
+18151
+15461
+12817
+11458
+18647
+30040
+10907
+17918
+25914
+25315
+29326
+3934
+4395
+28094
+9428
+9316
+28485
+16439
+9749
+2121
+10956
+27772
+27476
+12750
+860
+15477
+28890
+14239
+18314
+3240
+6489
+19978
+20092
+31107
+12904
+1807
+6485
+29582
+11571
+6034
+8476
+1751
+13708
+17007
+20881
+10398
+22045
+20769
+7439
+26476
+16203
+12720
+19343
+20457
+8529
+7798
+8825
+3756
+4866
+13352
+32481
+2796
+20639
+21756
+2515
+11919
+779
+738
+32755
+30424
+3728
+20998
+15312
+6013
+20612
+21814
+3769
+23163
+7616
+22045
+15558
+3804
+12997
+26428
+16134
+29547
+19124
+12174
+18888
+14428
+19183
+18645
+17358
+13658
+20905
+2049
+18551
+20782
+19362
+21490
+28592
+13256
+24416
+25668
+27435
+7231
+8945
+22541
+23815
+17032
+5471
+27651
+3376
+29522
+15074
+678
+10667
+23543
+1310
+5608
+1549
+6210
+17552
+29102
+13386
+13343
+11012
+20307
+1658
+26659
+30387
+4128
+19785
+7069
+13816
+32303
+25463
+21830
+9622
+15884
+10739
+26625
+14237
+25544
+9924
+16673
+10232
+19206
+18206
+19557
+11433
+16490
+10316
+14720
+21724
+2214
+9618
+19720
+29962
+7840
+23480
+12302
+11473
+4545
+19915
+735
+21665
+19628
+91
+6965
+22278
+7254
+5009
+18991
+6629
+13016
+15536
+4051
+14523
+21721
+16212
+17657
+28410
+12232
+19853
+4776
+31459
+30952
+32044
+5916
+24918
+3641
+32319
+4897
+6165
+13799
+11243
+2342
+22495
+3878
+16167
+26950
+8344
+13506
+1356
+6524
+20665
+24082
+7555
+14276
+22918
+10047
+18147
+5799
+408
+16801
+20842
+14423
+11114
+5619
+24819
+5234
+5856
+799
+12613
+968
+2885
+10392
+23209
+24590
+1411
+10192
+30157
+904
+1002
+8089
+12048
+8613
+11548
+19046
+3103
+6011
+25989
+8064
+21829
+24411
+29378
+28214
+22491
+8341
+13986
+6324
+622
+18299
+195
+24870
+12866
+22687
+25915
+10926
+9420
+2105
+12404
+18216
+18347
+21058
+11518
+30147
+6374
+31919
+8841
+10392
+12441
+19997
+30513
+1659
+18244
+4925
+22091
+12985
+12809
+14511
+15849
+26450
+22636
+17534
+32523
+21780
+25385
+16574
+21522
+7285
+28436
+11636
+29051
+3113
+10401
+11337
+16127
+11654
+32626
+13123
+10797
+13105
+4873
+2516
+1189
+10780
+22907
+23683
+22371
+23415
+9135
+21959
+15802
+21593
+25108
+19750
+7242
+2720
+24182
+22013
+10648
+30054
+15736
+12437
+10042
+11021
+10236
+27698
+8308
+20615
+9699
+3080
+2410
+11408
+24646
+25169
+24408
+10207
+21113
+22809
+9895
+20021
+19921
+3929
+25106
+25696
+11188
+3290
+26671
+6890
+15678
+24772
+13559
+5404
+14744
+25283
+4952
+10963
+17346
+11273
+19702
+30659
+31416
+26945
+1859
+32684
+20340
+6203
+30917
+10873
+14934
+15168
+16163
+27105
+24506
+28840
+28163
+14878
+24175
+2830
+3339
+8237
+7311
+17038
+16550
+6872
+4241
+29378
+26521
+8975
+24517
+13719
+28301
+14760
+31781
+4624
+1445
+18027
+26596
+19791
+9837
+1389
+3622
+9760
+20568
+24133
+10896
+1934
+22204
+3968
+18033
+17304
+30255
+19526
+15009
+24845
+20411
+9715
+6953
+21061
+22334
+989
+27206
+15772
+4173
+28467
+23144
+872
+23395
+32037
+16444
+52
+29382
+32623
+9919
+1642
+21752
+4238
+31046
+16615
+18640
+1989
+17468
+1604
+13506
+26933
+15889
+6245
+26518
+27490
+5348
+13999
+29601
+1464
+19140
+15194
+17019
+28667
+30621
+3754
+25853
+23437
+9159
+1757
+18597
+27058
+28258
+13633
+2835
+21305
+2842
+2347
+15125
+1650
+17686
+29607
+30383
+13054
+7062
+13374
+29780
+372
+5380
+4316
+1761
+31284
+2860
+10844
+16494
+4947
+30288
+16201
+11501
+13546
+8958
+6321
+23825
+15866
+15723
+30246
+31850
+28852
+2917
+14934
+4930
+12230
+10063
+31980
+9150
+25880
+12646
+25539
+29313
+7432
+15235
+19731
+18100
+11529
+31712
+31720
+30867
+16058
+30726
+11116
+31492
+6889
+29946
+477
+10246
+17051
+7201
+23355
+16176
+2310
+4080
+13192
+29881
+26110
+20039
+29294
+16212
+479
+30068
+28352
+16015
+17476
+8848
+24240
+15898
+30466
+26440
+26834
+25826
+22999
+25957
+9845
+9442
+18723
+21349
+18754
+25106
+12365
+15763
+23374
+11320
+27466
+3411
+6182
+10170
+20335
+12270
+26200
+26556
+14156
+10904
+6370
+21837
+29690
+25435
+11243
+10809
+13322
+14027
+27115
+4351
+6298
+19339
+24904
+5568
+16928
+1835
+24972
+24791
+3199
+11223
+19847
+5698
+5507
+32126
+14173
+24236
+4597
+7712
+3876
+11784
+23996
+8037
+17022
+8137
+29345
+18329
+22170
+20841
+2752
+1784
+18785
+19330
+30237
+11342
+783
+8247
+8196
+7024
+4509
+2268
+16959
+21834
+8913
+8667
+626
+22483
+19
+12369
+15603
+10692
+8330
+30469
+4203
+8665
+30275
+26679
+20127
+23350
+5244
+1756
+616
+10381
+3487
+2600
+5807
+25059
+21219
+27189
+31217
+30387
+1920
+2078
+14874
+14549
+28177
+17645
+20056
+8795
+24336
+20379
+28168
+8504
+5502
+20873
+6690
+19451
+32438
+8986
+12716
+27435
+31097
+6611
+11807
+19817
+18699
+14311
+25693
+22023
+15886
+15254
+16813
+27034
+13711
+30746
+11712
+18497
+19036
+10109
+12473
+3733
+7097
+12940
+15516
+26495
+26945
+21256
+24534
+3763
+20646
+32523
+616
+19547
+4438
+21560
+28648
+10913
+980
+5154
+29451
+9882
+1573
+1447
+28693
+10306
+14174
+6680
+18588
+15606
+28448
+16838
+24063
+25912
+24179
+2399
+2426
+24645
+29410
+244
+26145
+7807
+26203
+5175
+18221
+13510
+29652
+8756
+17927
+17756
+27497
+4936
+11529
+24502
+25661
+3223
+17747
+6122
+9886
+30432
+16234
+4057
+4973
+4229
+20612
+23523
+13755
+18008
+24890
+31722
+5927
+17279
+32551
+9148
+13646
+25970
+30654
+8607
+29354
+19717
+14683
+25106
+26707
+23982
+30834
+11603
+27720
+12996
+5204
+26858
+8915
+2446
+5022
+5605
+5538
+25495
+1191
+4906
+30650
+9741
+28292
+15794
+10147
+6291
+11346
+26010
+2475
+2689
+29378
+19264
+9196
+4588
+14894
+22346
+25602
+26064
+32279
+22053
+15727
+7761
+6498
+9987
+25885
+11800
+29530
+25713
+29773
+6660
+22645
+16203
+6567
+28417
+29394
+25722
+20290
+7192
+15311
+16551
+13350
+25361
+15958
+10213
+31926
+21537
+25089
+32323
+15652
+10238
+13225
+16438
+24078
+3380
+1470
+17272
+9039
+18570
+12360
+2051
+14162
+6922
+19957
+16498
+9724
+25272
+18390
+30025
+24236
+17448
+15151
+24424
+28151
+5433
+2331
+28775
+15742
+24875
+2808
+19077
+2327
+30360
+14036
+15806
+11039
+17932
+3098
+19620
+21278
+1796
+23206
+5511
+10208
+3088
+17709
+17719
+16049
+10842
+21155
+8752
+11765
+24026
+23776
+19050
+13719
+467
+7782
+26748
+18666
+15917
+10646
+31131
+31494
+31557
+17489
+22627
+28471
+13138
+29618
+30618
+16081
+19391
+7674
+15317
+18767
+11582
+3371
+12080
+11677
+28635
+13309
+20207
+1427
+16686
+30711
+13206
+5623
+23690
+2818
+30204
+8294
+22282
+10336
+2004
+3853
+30305
+8621
+9464
+20197
+28875
+19848
+19642
+8920
+16666
+20190
+29249
+19927
+6300
+968
+24350
+25858
+13229
+24441
+10718
+22442
+14052
+2136
+1359
+21544
+16830
+32318
+18179
+26721
+25334
+21215
+28967
+31082
+20361
+22064
+6627
+11591
+17722
+8717
+20353
+26448
+21837
+2627
+27339
+25674
+67
+26665
+5740
+10977
+15677
+4612
+27317
+25026
+19239
+11165
+3690
+529
+30716
+26728
+19288
+22506
+2604
+4704
+7845
+7141
+9812
+4023
+25101
+28746
+25787
+20906
+7538
+19869
+11263
+5320
+13352
+26807
+6763
+4225
+13294
+6551
+17978
+9921
+5808
+19809
+21372
+9202
+3664
+27915
+12428
+31154
+20907
+31076
+13357
+10204
+32400
+27855
+10818
+1814
+22622
+19282
+6006
+4466
+12328
+27481
+23002
+15336
+7339
+17845
+13331
+1132
+28344
+11002
+10533
+28241
+20767
+28781
+13996
+1695
+1492
+30912
+8637
+8184
+6448
+27423
+7427
+25215
+15131
+1868
+13494
+26219
+17970
+19267
+25104
+17640
+12029
+10210
+4392
+4090
+7911
+29875
+21462
+22520
+13979
+19984
+11027
+9338
+4370
+6
+24454
+11462
+16884
+13714
+23210
+2462
+647
+11581
+15718
+13408
+25276
+30795
+24554
+18139
+718
+17970
+19737
+20048
+1694
+5095
+26489
+1583
+8635
+7953
+23050
+2545
+28822
+15663
+3519
+20908
+5677
+473
+28663
+27580
+12578
+29602
+27373
+6198
+16101
+21265
+22446
+9380
+26113
+3178
+20795
+20621
+11501
+19874
+3272
+16706
+12378
+1591
+16931
+26083
+20898
+6508
+18708
+24675
+8810
+8982
+13386
+6398
+5283
+2359
+11350
+30933
+9621
+3628
+8794
+6219
+109
+11994
+15149
+9623
+1517
+22616
+16935
+13633
+31454
+16394
+4857
+18715
+26884
+16701
+13268
+18064
+19355
+66
+17544
+25253
+23609
+21927
+6829
+3679
+17297
+13295
+26393
+29176
+32695
+28025
+28548
+31535
+7106
+7625
+12236
+14353
+8962
+30198
+13078
+10517
+24413
+31200
+662
+31267
+22645
+13369
+10264
+5295
+14323
+3562
+15182
+7712
+31966
+7927
+8088
+30327
+12381
+21355
+27812
+24438
+32422
+25306
+12766
+13738
+19541
+956
+27394
+4729
+30484
+27671
+4327
+2582
+20018
+711
+5654
+14257
+1117
+20006
+22003
+28120
+19278
+11869
+4408
+19537
+12257
+7359
+23946
+19674
+7507
+21081
+2731
+9850
+13690
+10450
+13623
+28172
+1938
+11847
+25939
+19380
+22625
+4001
+27997
+18929
+9525
+1231
+26868
+17012
+8826
+6077
+18530
+20829
+25393
+20605
+6898
+13687
+26294
+32644
+32587
+23472
+23520
+5402
+32485
+15355
+8324
+2799
+9752
+18919
+1221
+31292
+17218
+29864
+30312
+30357
+3345
+2909
+15040
+22803
+11747
+25396
+15358
+20968
+4563
+3606
+1621
+26078
+5010
+31158
+28872
+11014
+21987
+24001
+24342
+21222
+18100
+2540
+14312
+8057
+26090
+15258
+6529
+12399
+2421
+6289
+32545
+28942
+8173
+11600
+14179
+27164
+31856
+20101
+9680
+9851
+807
+16251
+17735
+22075
+25074
+620
+17598
+13233
+31955
+11137
+27476
+2763
+22338
+22606
+4201
+13526
+27862
+2865
+27794
+14715
+26293
+20034
+9222
+19747
+29189
+32761
+25172
+9333
+15595
+2659
+14678
+25566
+10953
+12743
+20145
+6645
+18565
+16752
+19080
+17735
+27072
+29836
+24387
+26002
+29696
+20116
+1680
+6435
+27987
+3521
+20033
+15586
+19776
+17119
+27553
+19208
+15268
+26518
+27813
+25208
+24062
+11268
+26170
+8314
+22703
+6884
+3572
+23358
+30922
+24058
+29511
+26404
+11856
+15075
+26307
+18166
+4468
+7894
+8684
+24038
+19439
+28872
+12270
+30903
+22522
+6921
+4639
+474
+16451
+16913
+14407
+30213
+28141
+9852
+14636
+13372
+1540
+15228
+5667
+31298
+10613
+27066
+22127
+25720
+13796
+18788
+27068
+30205
+30801
+14296
+7816
+6446
+25243
+25658
+29446
+14954
+21920
+17358
+24511
+19014
+25919
+18253
+13410
+12504
+22219
+25726
+19236
+26800
+11739
+18906
+11012
+14217
+9542
+22884
+29622
+31772
+24937
+6
+24325
+1794
+22616
+8482
+6345
+23583
+10134
+6737
+3745
+10616
+15936
+5045
+30894
+4234
+2531
+18989
+11240
+23983
+26549
+15303
+12958
+29978
+13739
+9919
+7711
+16566
+17343
+29584
+14540
+7798
+12174
+28397
+19609
+30132
+13061
+15511
+32293
+31400
+279
+16983
+5813
+2652
+18876
+13292
+8823
+32625
+232
+23400
+21431
+18301
+2109
+8905
+22230
+7961
+18619
+9142
+11998
+10952
+917
+24566
+15183
+30006
+31132
+9155
+2580
+32104
+5137
+12496
+19504
+663
+21199
+24851
+26643
+23910
+1757
+19972
+8615
+5692
+5135
+10395
+30418
+12681
+26972
+17308
+26488
+8565
+17482
+12923
+26497
+30482
+6235
+9272
+9723
+13839
+19878
+1017
+3826
+25199
+8580
+16265
+2294
+4326
+15133
+11650
+29444
+10617
+28213
+8601
+1192
+2850
+7969
+26629
+16710
+738
+25134
+656
+25900
+30633
+7317
+12234
+19798
+27621
+15196
+14356
+22976
+5781
+22203
+24139
+22192
+23130
+31003
+4414
+20340
+680
+4775
+20172
+31671
+25811
+32382
+22096
+23505
+18112
+10265
+11577
+19227
+13654
+18250
+29543
+19653
+21195
+23492
+31793
+20153
+30101
+15474
+2389
+28438
+12075
+30328
+29313
+5607
+5864
+6667
+28860
+3757
+13641
+3422
+25655
+8462
+26007
+18725
+24751
+13071
+27184
+15553
+29711
+9144
+13895
+18355
+23285
+13281
+22163
+2191
+2128
+25588
+30557
+9433
+29478
+30513
+27622
+6605
+5344
+12875
+13684
+10122
+3734
+26490
+22185
+20146
+10075
+9145
+32743
+13229
+29535
+2037
+8959
+19543
+13789
+7465
+3430
+26329
+27878
+11789
+10395
+30820
+3673
+19328
+28082
+1845
+23382
+3647
+4548
+7478
+25885
+32359
+21305
+30360
+16158
+7229
+15799
+26031
+26508
+30275
+1233
+592
+8013
+20359
+18291
+9947
+14438
+22744
+32497
+21607
+24545
+32276
+29176
+32323
+8422
+32739
+12397
+7770
+31485
+6742
+25003
+31883
+18074
+23088
+22500
+22159
+28087
+18163
+13717
+6410
+8300
+24378
+10066
+16382
+31950
+1185
+1077
+28826
+23662
+32431
+13006
+19489
+20531
+26014
+10513
+22775
+32644
+26442
+26471
+29591
+32453
+26962
+25185
+31816
+4230
+32674
+15276
+18366
+22933
+30600
+16202
+28749
+8205
+673
+20475
+1742
+727
+18336
+10725
+13447
+17059
+9445
+27613
+12673
+19322
+31991
+716
+25342
+17914
+25308
+12706
+24535
+16355
+8749
+31767
+6519
+21
+8206
+19519
+26566
+15266
+12642
+16148
+24971
+17401
+18782
+2094
+22441
+13776
+13801
+9690
+19267
+14912
+3116
+28049
+3168
+14131
+15329
+21015
+4882
+24134
+1864
+21973
+15854
+30890
+11624
+16860
+6056
+19615
+13637
+6353
+1349
+13048
+1336
+16351
+28727
+31499
+24007
+32593
+17902
+17003
+17634
+31515
+1183
+15004
+10635
+13812
+26185
+3901
+17668
+14640
+10440
+4295
+17916
+20729
+11920
+3530
+930
+12383
+28457
+3537
+13631
+3765
+11971
+14470
+3814
+30861
+15936
+32692
+17294
+31383
+6883
+26741
+12614
+12847
+30094
+31315
+12531
+17330
+7621
+13686
+30605
+1216
+180
+2067
+24053
+18930
+24005
+30283
+26465
+26966
+12226
+1935
+26169
+22783
+6835
+8491
+16541
+23098
+25159
+220
+17869
+21255
+5056
+26864
+13299
+16876
+11375
+21178
+3173
+28925
+10232
+13356
+1544
+15854
+2646
+18015
+20867
+10305
+2619
+20882
+454
+17561
+16630
+2908
+3019
+28248
+11764
+18026
+145
+30410
+30241
+10697
+997
+2174
+16155
+10107
+12469
+25180
+21523
+1176
+20168
+26056
+30924
+27776
+25615
+25394
+16911
+8354
+4137
+19397
+7197
+24267
+764
+18813
+31473
+10515
+31084
+30471
+4385
+20777
+11879
+18320
+4823
+8052
+19446
+20611
+1930
+15210
+19787
+8293
+3204
+22716
+18311
+9820
+7831
+439
+14799
+5067
+9974
+2045
+11334
+26563
+22041
+21579
+21880
+3013
+23101
+10835
+30120
+4185
+31199
+32005
+32726
+25962
+22583
+23780
+13284
+334
+21544
+20093
+4814
+28000
+27693
+18756
+26486
+9553
+3530
+8901
+31686
+11425
+10813
+13764
+763
+21402
+19450
+22498
+36
+28881
+550
+13882
+18437
+31393
+15964
+23634
+22111
+20548
+20085
+3242
+15895
+12896
+5741
+11123
+18491
+18029
+27073
+7932
+22444
+7699
+10677
+20777
+5322
+207
+18465
+3382
+6633
+20436
+2655
+7028
+10337
+7243
+18551
+22845
+30931
+8397
+5620
+1630
+16080
+9972
+32203
+27510
+26609
+11325
+31159
+15301
+10950
+32642
+2319
+31748
+13095
+32212
+4528
+26563
+26647
+2530
+11119
+14690
+6704
+27448
+27541
+17630
+3787
+2003
+22807
+16723
+27093
+20998
+18886
+13948
+16397
+28593
+9569
+11176
+29269
+338
+27158
+30506
+8687
+29900
+21509
+24026
+22231
+26316
+12628
+23918
+8170
+4891
+1040
+31722
+6732
+18218
+19467
+14437
+10013
+10630
+21482
+29421
+29050
+17610
+21123
+24039
+1515
+9447
+26559
+20077
+8356
+18642
+2751
+23078
+5834
+17726
+17692
+24302
+4359
+10958
+26414
+14918
+5680
+1171
+8874
+25685
+13503
+7555
+21082
+14720
+18371
+6914
+24705
+24619
+32202
+11400
+19929
+7185
+18010
+953
+10423
+21410
+25862
+18634
+32503
+12534
+13162
+18599
+32546
+20228
+18782
+27656
+19809
+21839
+26579
+2265
+1763
+17970
+22132
+10036
+5276
+13316
+12686
+11340
+23176
+16975
+366
+1442
+5652
+11348
+5069
+18879
+18297
+30931
+2658
+24590
+28490
+9068
+18738
+10914
+4003
+28058
+23918
+10747
+27556
+11601
+15880
+14767
+21557
+9778
+22061
+28700
+3887
+2768
+32557
+13970
+30080
+27104
+5280
+24747
+20961
+12156
+7979
+5049
+8556
+3974
+23926
+15170
+3976
+19763
+10465
+3099
+29409
+23259
+694
+9864
+31430
+13814
+28880
+5387
+21074
+19235
+12196
+26456
+28714
+1495
+15426
+14463
+22795
+8973
+24789
+24228
+2978
+1888
+29562
+31024
+27282
+29046
+14643
+30420
+7142
+23469
+5494
+17283
+9504
+10033
+10140
+19368
+17919
+8972
+7620
+26562
+11042
+8713
+8738
+16551
+12574
+19958
+8837
+32038
+9433
+28436
+11849
+2062
+8108
+32671
+17786
+7481
+13195
+14856
+7094
+4083
+23156
+8661
+25494
+23958
+23008
+11476
+25452
+2366
+31115
+24832
+6013
+16502
+16698
+935
+30187
+18740
+13562
+16080
+31171
+10261
+15842
+3427
+7062
+23004
+9316
+24471
+30648
+2433
+6231
+17271
+4465
+19342
+5121
+1228
+17318
+2429
+18622
+31170
+1486
+17152
+26269
+4106
+15489
+30765
+31920
+17774
+29813
+28464
+27951
+24472
+20253
+5498
+22520
+8103
+22430
+4973
+7684
+27448
+32387
+26640
+17123
+26107
+26221
+17210
+22537
+3630
+6641
+16818
+12736
+23774
+18064
+17909
+32682
+5432
+17211
+12468
+17052
+27188
+20854
+20213
+26317
+15409
+28266
+17113
+27328
+9638
+30264
+8624
+26451
+17227
+12483
+7704
+27417
+32174
+23878
+16960
+17921
+8069
+6466
+1268
+32500
+6339
+19741
+30795
+11842
+7386
+21826
+8565
+10825
+26376
+1640
+27246
+2803
+10533
+2147
+25334
+24616
+11081
+25766
+7845
+7616
+1277
+8501
+21126
+3112
+16984
+26597
+5451
+11226
+10802
+25943
+29033
+19559
+8798
+6335
+30807
+27516
+26652
+25296
+1177
+6751
+7932
+21448
+6902
+26187
+25503
+11852
+11465
+26056
+23389
+4453
+11198
+5749
+9237
+494
+29766
+28433
+26605
+17321
+11429
+19717
+12047
+18276
+6302
+26493
+3073
+14866
+7448
+21866
+32498
+5789
+28531
+15543
+27181
+25223
+19116
+15075
+20338
+405
+13844
+5213
+3525
+15024
+20637
+9989
+24596
+31651
+22166
+26055
+13866
+11422
+5980
+24384
+14344
+24469
+28165
+17943
+15093
+25336
+20173
+18197
+20924
+22539
+27559
+28250
+9511
+18803
+23059
+13565
+7623
+6070
+20778
+25712
+18869
+24336
+12295
+17219
+2246
+19610
+24514
+5658
+21404
+26749
+16152
+32722
+2777
+29691
+16781
+18949
+12684
+11834
+15265
+3993
+21101
+15853
+15487
+2085
+3384
+6529
+2149
+16662
+21207
+24491
+5792
+14770
+32136
+6880
+11522
+9736
+1160
+7308
+20176
+5812
+20787
+13910
+27289
+2251
+29339
+27945
+16038
+21950
+30915
+9562
+26008
+11090
+27957
+32352
+30097
+8592
+18476
+25971
+6649
+21162
+13713
+24885
+1280
+5363
+7716
+5948
+4606
+30834
+11303
+26713
+19096
+2606
+31104
+28536
+32290
+6641
+23427
+21090
+22843
+26207
+2926
+14793
+22731
+19152
+18549
+9670
+6956
+2424
+30070
+28334
+12793
+11646
+23805
+8095
+14717
+23443
+17914
+22515
+26533
+14784
+11159
+29459
+9338
+27395
+15893
+1091
+28028
+2936
+16455
+11213
+31717
+16758
+18554
+2793
+7306
+29654
+14471
+19052
+21434
+1420
+2334
+16105
+2447
+16615
+19655
+26830
+31934
+27684
+20895
+22326
+24069
+26739
+4710
+9440
+14678
+26104
+22779
+30005
+7822
+17916
+19654
+11533
+28739
+24346
+20183
+21247
+1246
+21355
+17768
+30696
+31175
+9215
+917
+21750
+1537
+20109
+16809
+31534
+22542
+12544
+17803
+901
+24003
+25688
+30663
+30406
+5791
+21871
+13625
+23531
+23892
+29047
+5312
+29613
+15635
+27344
+22936
+25217
+19773
+12941
+27833
+10009
+1137
+22846
+16174
+9393
+2913
+16619
+8736
+882
+31890
+6143
+15660
+24981
+22456
+19601
+28226
+985
+24080
+11245
+29230
+20786
+26304
+6810
+8870
+26594
+24836
+30598
+11517
+18764
+20537
+30168
+5453
+12378
+14361
+14446
+5341
+3967
+11246
+21089
+11130
+11057
+27480
+14459
+22322
+16366
+32486
+28332
+2167
+23420
+32581
+19647
+12193
+13518
+2626
+10142
+12635
+4311
+18694
+30647
+26469
+28004
+6170
+30601
+32667
+15461
+11681
+29503
+24534
+458
+7848
+32622
+15639
+24890
+31801
+9827
+32340
+28891
+25335
+6521
+4626
+32415
+14682
+32019
+18673
+28511
+6902
+11781
+1234
+16369
+1791
+6354
+11088
+17882
+5009
+24174
+23348
+30683
+8256
+28910
+27110
+15782
+968
+26165
+30970
+10938
+17372
+25767
+22838
+14997
+24527
+25583
+11419
+10644
+30630
+31407
+18069
+7473
+12947
+31146
+14549
+26894
+27838
+19184
+582
+29704
+27066
+20858
+30669
+22475
+5652
+22733
+16768
+5348
+13555
+2618
+11019
+6622
+23292
+9243
+12896
+4613
+18782
+29520
+16044
+21310
+26923
+22565
+7543
+13816
+32287
+24683
+18818
+10354
+32307
+31825
+30893
+778
+11222
+9391
+3775
+20574
+29401
+14638
+10999
+1219
+18452
+27696
+1995
+19189
+19691
+13120
+22093
+5169
+20417
+18805
+25086
+15108
+24993
+27366
+16150
+5475
+19313
+3521
+10209
+21548
+20658
+387
+4138
+30036
+10743
+17647
+1355
+16008
+30155
+1996
+299
+29487
+24183
+32269
+12765
+26818
+14429
+6835
+8696
+19775
+14207
+7512
+22536
+16178
+7775
+18586
+18929
+7388
+30578
+11823
+19255
+23591
+19614
+17783
+21494
+6487
+27293
+15981
+3967
+12065
+29715
+16341
+23744
+982
+520
+32399
+15474
+11253
+6829
+11641
+8193
+30428
+1883
+5965
+26367
+13186
+29662
+13061
+22692
+14359
+5705
+19273
+19635
+22659
+15444
+27025
+24343
+15546
+6695
+7332
+7756
+25455
+21124
+8483
+15334
+8215
+1029
+11514
+4546
+2045
+14653
+1348
+31494
+1635
+6834
+21062
+16691
+17005
+22740
+32390
+27935
+24379
+17080
+6225
+17571
+18871
+24562
+20723
+14399
+20269
+27293
+12457
+25948
+11504
+1770
+9071
+7386
+20871
+13587
+14947
+25947
+815
+14007
+29209
+7512
+11984
+32008
+19316
+1035
+8892
+16150
+4630
+14268
+29462
+32003
+8358
+19589
+3077
+20472
+32557
+12587
+21831
+19767
+3920
+2434
+385
+23147
+26377
+12710
+13010
+9112
+1215
+29419
+23216
+11075
+5765
+8424
+12743
+10899
+19917
+7100
+28859
+21611
+31712
+20727
+14522
+23341
+14455
+24210
+1854
+19520
+22902
+9661
+25133
+10496
+30066
+18095
+17221
+12584
+32638
+29920
+30194
+9881
+11541
+30808
+9689
+30862
+27094
+2468
+5235
+12004
+12445
+16755
+8164
+3835
+13950
+16675
+5711
+26732
+23063
+20172
+32646
+24996
+1444
+114
+25087
+26758
+4255
+23531
+19412
+6042
+8137
+6659
+3245
+1816
+30298
+11819
+21424
+5879
+27365
+4596
+23987
+25939
+20505
+15849
+14793
+1155
+24969
+13983
+10755
+21029
+7665
+29415
+27593
+6759
+13720
+12243
+1904
+30994
+13361
+18317
+8974
+3201
+12856
+7082
+27113
+31307
+29832
+27418
+11517
+23995
+24069
+24839
+23324
+25030
+25158
+1866
+21152
+13407
+6845
+10452
+12938
+12077
+1329
+31185
+16572
+19812
+623
+25463
+16845
+19452
+25693
+17863
+13622
+17196
+12234
+6860
+806
+22493
+14950
+21613
+4043
+12150
+12106
+17437
+10442
+1092
+20237
+2652
+30373
+3708
+9839
+26948
+14076
+14270
+20222
+12612
+7961
+20302
+22709
+5226
+29940
+3674
+32695
+8657
+32235
+27908
+19777
+12661
+14051
+20097
+10246
+16953
+31861
+2343
+9479
+18134
+15798
+14141
+19188
+10014
+18313
+12982
+2546
+19197
+23300
+14513
+4694
+5055
+10791
+9010
+31177
+14749
+15064
+27192
+11842
+15274
+16560
+5566
+16093
+21615
+26107
+27190
+19874
+3942
+11456
+17369
+31457
+5579
+5089
+20066
+24608
+8248
+1318
+24356
+934
+18085
+18571
+29817
+23209
+23949
+2197
+17764
+27405
+18898
+13554
+19276
+17270
+11225
+22462
+14501
+1126
+30773
+10756
+17647
+29032
+6565
+21083
+30752
+16840
+4001
+26486
+5322
+32680
+9668
+5148
+24732
+30845
+9108
+3709
+20350
+989
+21932
+21948
+20156
+21171
+13552
+18640
+10994
+15811
+4255
+29870
+30915
+7757
+5318
+4712
+10886
+29630
+3365
+6857
+12872
+19129
+25198
+30857
+9354
+8398
+24744
+31265
+24092
+9938
+31733
+27690
+31985
+31667
+25008
+14775
+15322
+12925
+32362
+1499
+2858
+8393
+13726
+28576
+16440
+18668
+22476
+25436
+25618
+13681
+11524
+4715
+965
+14813
+6031
+32577
+11844
+16739
+31410
+29554
+28267
+20548
+25646
+20559
+17764
+22293
+25085
+22556
+25357
+13450
+1574
+32512
+10191
+9778
+20982
+11955
+17414
+2776
+3573
+1510
+31268
+5387
+22343
+18597
+28276
+21852
+17738
+22107
+9652
+4681
+17484
+2260
+23209
+10846
+17642
+5079
+15853
+14189
+11498
+32268
+31815
+23940
+11667
+18166
+428
+8443
+31785
+2513
+14539
+27394
+10737
+15272
+13446
+30432
+7106
+5497
+4454
+30680
+10223
+2771
+29940
+1272
+28945
+16684
+26474
+13794
+20082
+23575
+16483
+21098
+1452
+8304
+19633
+13733
+14822
+25502
+25572
+25404
+15619
+27892
+14668
+26380
+2547
+21025
+10238
+13029
+13153
+23565
+2307
+19956
+29463
+15561
+31152
+14177
+24946
+19238
+30650
+8009
+6360
+20068
+21934
+26756
+1900
+31468
+21808
+24758
+3648
+21229
+3396
+4526
+29011
+16224
+4155
+16717
+31986
+10383
+29288
+22990
+11857
+5851
+24937
+21515
+31797
+15398
+1051
+23318
+14661
+12024
+25902
+24078
+7431
+26731
+2253
+3713
+5177
+1852
+5877
+25535
+12362
+590
+9905
+32694
+22932
+21702
+12986
+28963
+266
+2062
+5865
+22907
+25371
+10908
+11574
+21472
+26586
+14833
+8506
+12286
+1716
+14253
+29825
+561
+8347
+27657
+24517
+14326
+7000
+31727
+19488
+6592
+10502
+29647
+22427
+16337
+23537
+25946
+18648
+6319
+15069
+9180
+4354
+21942
+29466
+21821
+25097
+23507
+16853
+23055
+26254
+20815
+28289
+32026
+1257
+10263
+13098
+24890
+31228
+23185
+15593
+5721
+20863
+15797
+4508
+25008
+8470
+24334
+19438
+17457
+16252
+6376
+23308
+6839
+1613
+378
+18175
+11594
+10623
+28215
+3823
+6623
+19905
+25469
+18406
+30621
+17005
+24284
+3573
+3531
+24087
+27707
+24976
+27489
+22912
+15484
+11568
+29128
+17825
+29696
+18789
+24177
+6738
+23449
+20818
+5061
+5272
+16882
+6600
+19962
+3717
+1458
+1851
+1370
+8707
+4094
+5218
+32231
+7470
+32270
+31870
+3950
+17224
+23793
+11765
+20479
+5353
+9599
+29864
+8030
+12290
+1576
+27329
+25512
+23529
+31648
+28654
+7190
+9755
+5102
+17239
+12829
+13594
+4774
+28249
+16655
+3515
+5031
+27679
+10711
+3181
+7154
+22785
+11625
+27416
+4870
+18287
+32668
+11816
+5974
+23185
+14210
+21619
+29543
+17147
+12816
+22850
+16378
+31009
+15348
+26191
+29025
+15161
+15867
+23814
+22190
+26500
+12284
+27191
+5903
+10290
+6466
+24580
+21870
+91
+11059
+22304
+15085
+16457
+6832
+29023
+15221
+18000
+2974
+26716
+8964
+32018
+29511
+26567
+29108
+8829
+1496
+28232
+5749
+3743
+11276
+2844
+4038
+13269
+6680
+19860
+20991
+5221
+16423
+6367
+12793
+32279
+28983
+839
+31440
+9857
+8973
+23726
+21194
+28260
+13483
+3759
+19002
+28826
+21988
+14502
+18382
+32288
+8349
+21210
+8540
+24413
+7490
+2176
+22603
+22033
+9161
+5592
+27017
+20243
+17598
+24611
+29892
+9215
+25195
+12070
+7993
+30093
+10457
+24786
+12124
+30281
+26031
+29117
+21733
+17818
+16054
+15970
+14294
+64
+11722
+29001
+17067
+6811
+4060
+21844
+19115
+19504
+1225
+27730
+9491
+23446
+743
+25991
+22421
+21480
+16782
+2256
+18687
+31771
+1051
+18698
+21713
+12500
+24566
+13115
+15010
+8518
+21038
+29795
+23947
+28937
+12255
+3525
+17240
+27958
+7327
+18692
+305
+1505
+5457
+14961
+3635
+1957
+14257
+5124
+20493
+16168
+11442
+356
+5295
+3689
+16374
+714
+30529
+6020
+14496
+13130
+25016
+10305
+26434
+25710
+19257
+16989
+4457
+14500
+26595
+12245
+26240
+11659
+10827
+20378
+24694
+14701
+24190
+24979
+11113
+18758
+23710
+12215
+20937
+15967
+978
+6147
+3400
+9534
+12430
+3864
+12928
+12860
+24130
+674
+8129
+26275
+4614
+8046
+5922
+25797
+27018
+10559
+8302
+25760
+347
+21635
+9347
+27992
+28085
+12709
+874
+25507
+1233
+3765
+20646
+31796
+32035
+22932
+13227
+23923
+29688
+29967
+25217
+22042
+3596
+22600
+32216
+13974
+27169
+22850
+6645
+27007
+24091
+3587
+9947
+17158
+1538
+14844
+655
+11269
+23069
+30791
+12561
+7644
+7253
+18625
+6750
+27565
+31022
+28969
+1070
+3416
+12024
+31452
+24205
+17969
+27500
+9268
+8715
+12834
+13253
+28533
+8922
+29367
+8715
+23470
+9061
+26983
+16163
+24693
+16496
+21511
+26094
+8042
+6805
+19160
+22950
+25866
+16441
+9811
+28661
+4904
+30938
+1193
+14724
+14509
+11110
+362
+4771
+18919
+6086
+7432
+11745
+16527
+17025
+19078
+17644
+4995
+23324
+26874
+12875
+3395
+28878
+15494
+10043
+17128
+24683
+27212
+17950
+31068
+19335
+13581
+18281
+3695
+17327
+15944
+4140
+30154
+30952
+27245
+19083
+11876
+30558
+25566
+17932
+26057
+4811
+32446
+7491
+27152
+24915
+26473
+27524
+25350
+19751
+4975
+4431
+12785
+27829
+13043
+5607
+19350
+3868
+12668
+7597
+32161
+2400
+20450
+11776
+19502
+13021
+6949
+29780
+4664
+14715
+6120
+18472
+26687
+12100
+20401
+9974
+5778
+325
+13163
+25689
+20266
+27448
+28619
+8514
+5543
+10124
+12581
+18902
+16655
+7548
+32108
+171
+31986
+15080
+275
+20089
+17663
+26559
+32719
+9134
+12375
+25676
+30555
+18093
+18294
+16294
+32069
+28988
+22473
+30040
+2000
+12156
+12242
+10228
+13814
+29048
+10540
+18501
+93
+10968
+7394
+22626
+23004
+13432
+21798
+29147
+16107
+1271
+12586
+3547
+369
+16548
+32410
+31780
+21892
+29497
+25050
+32691
+4985
+13336
+21817
+17270
+20417
+25855
+28538
+26443
+16827
+4563
+29487
+15421
+8497
+21133
+31259
+16817
+29685
+2626
+17963
+20658
+10350
+3482
+22026
+31725
+15735
+5499
+2548
+14967
+12048
+31416
+6180
+826
+10700
+14644
+22807
+7650
+651
+10634
+17521
+3958
+23737
+14224
+1911
+27336
+15027
+23161
+28755
+12354
+3402
+14413
+28297
+15336
+10374
+18265
+16614
+2495
+7562
+5100
+6179
+19120
+15247
+27464
+30842
+12561
+5975
+5683
+2914
+10189
+19400
+31468
+23518
+32148
+7970
+12635
+4205
+12351
+20509
+27654
+11617
+32018
+18071
+9983
+19717
+8618
+29409
+24549
+21504
+32631
+31763
+7890
+8062
+26176
+10901
+14678
+28752
+26962
+17715
+26258
+12074
+11580
+2871
+5087
+15675
+10489
+10071
+396
+12088
+16360
+30414
+3469
+29446
+16769
+14101
+6324
+5124
+14458
+4790
+14573
+1834
+2718
+18514
+14608
+32024
+23877
+32457
+28557
+16208
+15955
+25021
+24494
+28825
+3289
+11952
+19625
+16744
+17422
+7806
+80
+10623
+10851
+30602
+20834
+14012
+14462
+11312
+21934
+17308
+22273
+14347
+5245
+15711
+25529
+11011
+393
+4632
+1976
+24399
+24575
+13860
+6596
+18887
+20312
+28629
+23917
+20065
+839
+26324
+16926
+7028
+979
+17652
+9291
+410
+26221
+21446
+18367
+31296
+21109
+9674
+12303
+28035
+23512
+27652
+6203
+7752
+25045
+3180
+20221
+31538
+24704
+10929
+31767
+3715
+968
+31885
+20723
+19638
+26347
+3082
+4709
+22733
+15345
+4210
+26350
+18732
+15667
+32066
+20093
+19101
+9782
+19504
+4478
+4588
+20708
+25399
+3590
+27936
+11505
+22830
+933
+25521
+17273
+23836
+5425
+1595
+23480
+18646
+30714
+1191
+10445
+657
+20206
+8113
+23644
+19960
+10114
+4760
+30042
+16626
+11254
+25256
+19936
+120
+28110
+14713
+27443
+1783
+6228
+23284
+31213
+2745
+17805
+22811
+21740
+30298
+23258
+29388
+31287
+30286
+7303
+13322
+7100
+12663
+16379
+14027
+4765
+10790
+20840
+13671
+9764
+16746
+16907
+7198
+15119
+30038
+10994
+18184
+8159
+17288
+27300
+30539
+6280
+14668
+28424
+14218
+26740
+24706
+18105
+16584
+21782
+20388
+19705
+13157
+32324
+22910
+7420
+9864
+22162
+21165
+9994
+17978
+14260
+13173
+5890
+20857
+3413
+8008
+23123
+24042
+19924
+27452
+21397
+12268
+24646
+27695
+8537
+8792
+29146
+30166
+27230
+31242
+24462
+16719
+18236
+29365
+2402
+9112
+10310
+24704
+16242
+29697
+7643
+13948
+25531
+19363
+5753
+5424
+13054
+7921
+10577
+22867
+13323
+32767
+2716
+24488
+16686
+2911
+13812
+76
+7689
+10491
+12457
+18166
+31734
+31658
+32677
+30682
+17675
+29256
+32282
+7265
+23057
+14432
+23626
+13657
+10145
+24148
+12020
+22108
+22204
+4206
+28851
+7898
+15333
+2275
+2952
+16702
+31689
+1380
+15616
+9819
+24210
+27131
+32188
+6575
+24528
+1235
+28364
+19765
+28745
+7853
+6569
+24571
+6639
+30500
+11353
+18922
+26491
+286
+1793
+3455
+13534
+4652
+22121
+19828
+21955
+5760
+31020
+28029
+18816
+19172
+30637
+16430
+17179
+31358
+5963
+28966
+9733
+16224
+26119
+31284
+2605
+27704
+30896
+5572
+13737
+9402
+22371
+32099
+13479
+32033
+9602
+7313
+5315
+20562
+30738
+13694
+10119
+26842
+26285
+2154
+5276
+22853
+472
+26109
+32387
+2164
+21803
+17668
+26004
+690
+16847
+8238
+20133
+28941
+24535
+28892
+11804
+32114
+27918
+26027
+27895
+10639
+14207
+6271
+29928
+19934
+29884
+14451
+19538
+15810
+17992
+29062
+24226
+6108
+3405
+27507
+9580
+12786
+18163
+14861
+27989
+8292
+10602
+14715
+1898
+26019
+25323
+22768
+19989
+4633
+19226
+16462
+25768
+2144
+8413
+21204
+949
+983
+30256
+26060
+29797
+27073
+18665
+22050
+2402
+9585
+15588
+26978
+28526
+23945
+11046
+1141
+18648
+5754
+30972
+6319
+21100
+1604
+31787
+3956
+19158
+19202
+8364
+20169
+18540
+22299
+25234
+10103
+5513
+3716
+14943
+28238
+27304
+26900
+29135
+27426
+24444
+2254
+12037
+11418
+32206
+4195
+8936
+30035
+29428
+17548
+7927
+3030
+19848
+18811
+22779
+2639
+7004
+4209
+17153
+20532
+15442
+25718
+19008
+23150
+9128
+16596
+18597
+1729
+8109
+16516
+22684
+3168
+7107
+21226
+20039
+23655
+7926
+25060
+3884
+12426
+463
+3811
+12866
+12137
+15001
+15928
+28826
+18117
+20204
+6142
+24389
+2222
+670
+919
+30291
+29187
+254
+31422
+1423
+6414
+7717
+23402
+24051
+6383
+17418
+15930
+5372
+32216
+5266
+15189
+3886
+24168
+23352
+31983
+23250
+14815
+464
+18011
+20970
+7768
+30002
+26477
+21294
+13542
+11664
+27179
+22608
+18934
+3439
+18981
+5969
+2014
+16629
+16394
+9568
+30157
+9509
+29904
+11110
+27247
+26223
+24474
+6893
+2593
+21419
+11401
+1370
+6617
+20254
+32712
+26858
+10029
+11248
+24483
+2902
+32018
+23520
+11505
+15047
+3921
+21906
+13530
+10069
+6297
+11098
+17371
+9230
+28748
+16885
+2317
+28958
+13835
+26014
+12455
+18600
+22417
+8097
+12734
+21071
+5412
+16633
+23648
+17395
+20425
+16335
+23095
+10025
+15004
+9634
+25115
+5254
+2959
+2724
+13472
+19968
+5386
+29304
+21523
+25826
+25782
+3562
+12249
+3301
+20600
+18928
+1752
+4168
+13849
+27318
+3092
+17450
+21075
+8063
+9859
+2856
+8603
+29736
+7956
+3786
+18754
+16497
+5896
+27290
+21725
+15741
+8328
+148
+13618
+1547
+23554
+24370
+2281
+20566
+32262
+27509
+9100
+28383
+16671
+1523
+23481
+32625
+6347
+27462
+26087
+22772
+9858
+22828
+10359
+24101
+11571
+7439
+26958
+8499
+29614
+588
+3134
+909
+16177
+26855
+15555
+20722
+28095
+13643
+31992
+15963
+31390
+26028
+14418
+15256
+10167
+12965
+4330
+16364
+18382
+31659
+19418
+4831
+6286
+28410
+3987
+21823
+14242
+11741
+15660
+14420
+22811
+8513
+23975
+19978
+18273
+31188
+29008
+27845
+9172
+27042
+21812
+32660
+304
+9067
+7802
+9788
+19662
+3190
+15381
+15413
+25049
+6710
+30385
+9050
+11871
+11320
+21265
+21362
+13355
+19950
+27575
+5252
+10086
+17709
+23731
+12885
+16307
+22871
+32603
+28087
+22749
+23229
+22466
+9621
+7224
+31271
+26175
+3695
+29287
+4782
+1552
+14585
+4685
+21298
+21272
+8359
+31402
+32358
+10391
+11008
+23220
+11936
+18755
+32316
+27044
+27391
+18975
+5305
+10277
+28101
+27129
+2864
+12476
+9908
+7527
+2067
+16254
+16828
+25386
+12244
+11664
+8981
+24455
+25657
+12940
+22424
+29832
+26452
+27808
+12027
+32751
+26996
+29247
+17917
+15872
+4830
+21540
+24800
+18593
+2376
+5298
+32066
+21624
+23985
+16603
+9104
+7350
+3519
+14460
+30102
+27191
+1129
+15565
+3048
+1986
+4580
+20959
+16642
+8396
+32740
+10636
+18033
+29855
+12539
+30158
+26067
+12675
+15908
+21626
+27900
+13396
+18085
+20377
+2212
+30322
+2832
+9214
+7659
+2538
+15178
+11129
+24935
+25073
+18128
+16793
+28336
+14999
+18291
+29199
+24297
+16895
+27412
+5313
+16553
+16334
+10665
+21933
+8779
+17108
+17644
+6834
+27451
+16721
+29962
+1465
+26826
+25648
+25117
+2554
+16428
+17705
+25007
+31774
+15469
+24065
+16656
+8318
+23749
+18900
+12622
+9656
+3438
+26017
+26609
+12420
+389
+5521
+4790
+16730
+22393
+32457
+6179
+20204
+2652
+16876
+9154
+25957
+2161
+29159
+20103
+21593
+24079
+28610
+24001
+32070
+9038
+6801
+19069
+10221
+4687
+12833
+22811
+14348
+15710
+4652
+25082
+15465
+21124
+6844
+26540
+5803
+26162
+14286
+25250
+13116
+26960
+21555
+11103
+2888
+20268
+30908
+18318
+27710
+12453
+22045
+21411
+10963
+10896
+1216
+12183
+13965
+10811
+25553
+27446
+28539
+20868
+23864
+15820
+16078
+27733
+30794
+28825
+11063
+21945
+8620
+18757
+9992
+17958
+2159
+24588
+27626
+9164
+24061
+16256
+16184
+10801
+8255
+10818
+7569
+25983
+20928
+21896
+1029
+15639
+21659
+15165
+30056
+17584
+15785
+21904
+12773
+25129
+5742
+12546
+15318
+13243
+28697
+18594
+22592
+9356
+11342
+1632
+25339
+1944
+26376
+4257
+1411
+9249
+12694
+13842
+1071
+26034
+15523
+10710
+27713
+15979
+5361
+14084
+13714
+20234
+18976
+7208
+23549
+23458
+12709
+26824
+23421
+16861
+14500
+15738
+23639
+8175
+13188
+20625
+32268
+3925
+23293
+23753
+17647
+25516
+2633
+26399
+24985
+11162
+20630
+30169
+9334
+6625
+17197
+3625
+19502
+2240
+11910
+8555
+16082
+29964
+4672
+26478
+11197
+24522
+4366
+28739
+29886
+7431
+32446
+8416
+732
+23512
+7918
+15265
+3981
+6508
+15045
+32728
+31393
+12264
+29296
+26254
+7306
+27762
+31320
+23769
+24033
+9394
+19344
+12987
+13461
+21567
+14275
+11156
+23611
+32195
+18502
+7910
+19874
+2486
+11355
+14661
+9368
+19173
+22482
+14615
+15671
+17283
+30123
+27361
+8616
+16375
+7594
+9873
+17724
+8962
+11438
+4084
+7840
+22081
+7583
+25884
+18946
+31483
+8420
+5699
+14043
+15689
+8745
+27084
+11905
+23914
+3028
+23903
+15459
+12048
+5018
+2002
+7832
+11836
+8324
+25112
+20760
+9961
+10815
+18595
+25506
+31110
+9484
+22651
+19903
+3033
+12220
+2284
+29102
+6476
+3981
+18044
+9565
+20886
+31401
+10163
+3807
+31527
+30004
+31397
+10212
+13626
+3954
+25227
+23364
+6802
+12612
+9823
+23444
+4695
+13700
+11030
+31942
+19292
+16414
+11630
+21522
+6951
+28464
+2235
+21017
+16305
+21970
+6160
+31721
+8858
+29324
+27780
+2891
+4751
+6717
+18896
+13960
+27354
+22657
+9254
+25815
+32205
+15540
+16
+29976
+21037
+24865
+1584
+4141
+9301
+6233
+8346
+15319
+23864
+25439
+15502
+19726
+29694
+32072
+16275
+10265
+15682
+32133
+20823
+23296
+12255
+8536
+21068
+20499
+25839
+10142
+8286
+8214
+16523
+7505
+2472
+10054
+10210
+12723
+4255
+2631
+5284
+19618
+18889
+21986
+17373
+9184
+25680
+6500
+7898
+21481
+13920
+7093
+23898
+32639
+4938
+9082
+23708
+16763
+7234
+22204
+5549
+15754
+27358
+16429
+3470
+11188
+25830
+26996
+5204
+19460
+30573
+28951
+30525
+31697
+2369
+23889
+16538
+5427
+25693
+26095
+25517
+14930
+1395
+1234
+20135
+26825
+448
+2432
+25079
+25804
+20807
+17031
+2733
+4975
+32564
+31987
+1268
+24758
+30673
+4003
+27317
+19193
+20598
+11209
+21519
+22694
+16113
+24210
+4318
+13461
+18182
+174
+19484
+2627
+30219
+2766
+6731
+29930
+22413
+15257
+27410
+15413
+380
+9819
+22904
+29688
+22427
+9684
+11960
+28788
+8761
+4757
+7230
+27811
+799
+11871
+3149
+28018
+2175
+26685
+21123
+26275
+10447
+22214
+5143
+13387
+558
+29231
+4654
+17286
+18660
+14617
+29147
+13808
+21987
+20538
+27891
+7215
+10385
+6129
+8808
+3162
+14538
+9334
+29834
+23489
+14203
+10773
+7704
+3202
+25136
+5445
+16367
+10953
+17535
+4433
+5800
+17268
+6603
+13000
+15591
+1824
+6727
+20041
+24996
+5319
+17677
+31523
+659
+7956
+6272
+14305
+27205
+13665
+13529
+26720
+14313
+26574
+24421
+15045
+31108
+29567
+15068
+4670
+25487
+27487
+20295
+29115
+30496
+11263
+10504
+30071
+11707
+32250
+29084
+25881
+611
+2734
+18430
+8368
+18514
+18891
+30193
+27812
+11961
+4911
+18053
+7408
+5311
+11668
+3946
+11536
+21528
+12522
+30617
+14677
+9530
+17676
+29469
+4566
+10910
+15943
+29670
+17342
+16238
+11429
+9589
+22194
+6303
+5941
+25060
+31378
+18602
+16446
+29283
+3274
+29905
+2600
+32470
+16636
+15167
+21737
+14044
+19788
+5292
+22572
+26312
+2609
+19429
+27254
+15794
+9153
+2898
+3565
+4867
+137
+31403
+14992
+31147
+31758
+13138
+7650
+12624
+9755
+23749
+21655
+16241
+24991
+12559
+10237
+2968
+25538
+1820
+27845
+18087
+15512
+25345
+1679
+19554
+31290
+21302
+22048
+32145
+27082
+4984
+30858
+20079
+1148
+13569
+7996
+17312
+31376
+10723
+9458
+15483
+29118
+14306
+30282
+19904
+5424
+22928
+18944
+28944
+6114
+15663
+4837
+11392
+23520
+3282
+22938
+20808
+1705
+7584
+12484
+23152
+17745
+29192
+11599
+28941
+14068
+5469
+10781
+5731
+31365
+31952
+23766
+15115
+31154
+22965
+9045
+20615
+2012
+12462
+18337
+25202
+19234
+22460
+20629
+671
+13561
+6921
+6904
+20469
+8279
+28032
+10064
+18042
+10152
+11631
+10263
+22316
+24702
+14114
+14022
+8567
+14535
+19936
+19513
+25152
+11948
+28087
+21125
+26595
+6314
+3964
+24193
+16540
+29894
+17740
+19298
+21971
+23338
+16404
+15415
+24228
+4263
+6340
+7878
+7949
+17341
+2979
+6142
+23575
+5644
+15150
+29379
+10580
+8434
+17925
+6741
+30105
+22164
+27834
+17314
+24807
+11771
+22412
+20599
+30224
+17236
+1612
+3465
+25089
+28202
+17493
+32089
+14330
+13087
+27581
+1610
+328
+18172
+27077
+9989
+27416
+20267
+26994
+960
+26124
+15130
+18979
+29436
+11129
+16358
+20165
+2911
+13680
+32679
+19225
+6489
+30785
+11550
+21180
+32541
+26247
+22941
+8808
+11618
+12324
+11401
+2096
+19183
+24143
+14314
+2743
+5882
+17255
+20093
+5790
+3037
+13506
+26832
+30215
+32549
+603
+32577
+10853
+32301
+25834
+24920
+6045
+4288
+29759
+4470
+12524
+5164
+4800
+20469
+8579
+24729
+11972
+5611
+21216
+17603
+11646
+31220
+17388
+701
+4107
+32066
+22054
+1892
+4771
+16935
+19969
+28313
+7897
+558
+21341
+21137
+27558
+3783
+30394
+1575
+6156
+24763
+14138
+29282
+17884
+16747
+6557
+23821
+14950
+9064
+23473
+2987
+22976
+5429
+6807
+1513
+13410
+24550
+17502
+19317
+7154
+854
+24480
+14770
+10724
+23043
+18196
+10648
+31741
+24110
+24620
+10061
+28810
+20510
+9987
+27055
+1340
+23129
+25253
+26032
+14359
+5488
+14376
+3694
+4330
+9273
+26353
+32447
+27320
+6516
+13378
+5815
+28508
+15694
+1489
+9597
+21432
+29825
+27735
+4997
+19029
+22004
+23534
+9039
+27232
+6473
+12712
+26183
+31373
+5718
+15808
+20690
+22500
+24526
+2702
+17925
+7143
+5570
+15255
+420
+29734
+2787
+4101
+4713
+25081
+17066
+28091
+16189
+1947
+31940
+22561
+3400
+11191
+16648
+19501
+21310
+21860
+28495
+2291
+24600
+3097
+1999
+26852
+5529
+10364
+8653
+27682
+23125
+13913
+25034
+22138
+9393
+2166
+15372
+30929
+14344
+18187
+18951
+15859
+29764
+18815
+25312
+3387
+16043
+31581
+21927
+6938
+4829
+13623
+25910
+25045
+5472
+1270
+1692
+8241
+4638
+19292
+16517
+11949
+5431
+1577
+18804
+10117
+19673
+2624
+13990
+28483
+17019
+19501
+25360
+25570
+20751
+20125
+22223
+22250
+30885
+25304
+30745
+1698
+4764
+31087
+15712
+11561
+32003
+5615
+13322
+20584
+32298
+14735
+31417
+12547
+3555
+219
+23910
+10044
+32442
+4512
+17545
+15219
+17872
+2654
+17780
+30405
+8511
+29851
+5328
+16933
+17137
+10303
+4345
+1321
+1129
+19878
+9685
+27228
+23517
+23561
+31571
+14830
+4783
+23971
+7060
+21268
+30383
+3131
+7512
+16534
+32221
+1649
+10470
+22716
+23091
+29523
+6913
+10962
+5486
+3799
+3995
+24347
+2369
+20212
+12595
+17724
+6549
+14645
+4029
+28930
+26260
+19874
+1738
+25635
+3352
+28250
+1175
+6589
+8648
+29778
+22908
+11626
+17791
+21128
+13263
+13745
+13342
+30642
+6616
+29529
+2772
+10725
+9331
+19732
+10945
+13938
+17633
+24007
+141
+19690
+13915
+19500
+10847
+26012
+13660
+22475
+10312
+11166
+19452
+15078
+6425
+29866
+32631
+4502
+16011
+27785
+15591
+12387
+23613
+31864
+23827
+23388
+19415
+17746
+24325
+24398
+14844
+11571
+16808
+18211
+9825
+22490
+21921
+25216
+26306
+26742
+29941
+15717
+28861
+24069
+24093
+2241
+23199
+18170
+7768
+22716
+18231
+12826
+8052
+12229
+24937
+1911
+22069
+30654
+2776
+3969
+13222
+3934
+7783
+11142
+2570
+19461
+6282
+24038
+23261
+6186
+5262
+6750
+16956
+11795
+8110
+4435
+1848
+8008
+25268
+25697
+24096
+17328
+6075
+17369
+6104
+6252
+7090
+3440
+3845
+26205
+6363
+2621
+27728
+12875
+12413
+9047
+18952
+9166
+24571
+7671
+3517
+4806
+23820
+4294
+28886
+10329
+5839
+7290
+13484
+16513
+7117
+21089
+8500
+747
+27500
+19930
+18182
+13636
+13360
+2305
+27643
+20808
+983
+13973
+10800
+25291
+21977
+21133
+24091
+5360
+16147
+8769
+7755
+30807
+15266
+16918
+555
+7747
+32133
+32756
+14002
+6581
+5519
+12060
+7682
+28463
+7946
+8953
+12468
+20411
+23320
+18184
+533
+32388
+13031
+1737
+9578
+8464
+29546
+1108
+18967
+25930
+11509
+20364
+8134
+18066
+26631
+23163
+564
+25500
+19505
+20100
+29357
+2810
+29706
+5197
+31796
+3964
+13756
+1583
+17409
+30791
+16225
+8211
+1421
+12632
+25755
+22059
+32082
+15288
+25618
+6300
+22745
+26959
+2577
+13466
+17651
+1642
+20805
+11805
+16286
+23335
+1948
+14563
+26127
+51
+25249
+35
+6938
+32307
+1777
+5378
+23900
+8009
+11425
+20162
+20647
+20162
+24369
+20421
+27647
+412
+29316
+25141
+21403
+4289
+9237
+10777
+1558
+20273
+27775
+11919
+24128
+29578
+4173
+20526
+20928
+23193
+20074
+27531
+14111
+8685
+27876
+19083
+17602
+29763
+30666
+9417
+13830
+2213
+13184
+30147
+5202
+19115
+21046
+12082
+18608
+17329
+27630
+9213
+26660
+24064
+9918
+20467
+7122
+12424
+1871
+586
+6416
+11108
+529
+2031
+944
+19037
+28036
+8738
+6316
+7758
+13864
+12370
+12070
+16469
+16559
+19209
+1985
+12869
+31560
+23365
+23763
+25167
+438
+19
+7775
+16477
+22261
+12180
+17558
+11478
+21244
+25493
+30680
+10806
+26440
+29275
+20751
+26140
+25083
+21177
+4022
+9666
+13338
+14294
+7814
+5460
+25122
+345
+12067
+20728
+8547
+16953
+18809
+19245
+16778
+445
+27077
+23682
+9728
+5397
+14667
+4454
+4030
+13402
+18375
+30471
+8743
+19419
+27937
+15843
+12954
+19047
+30426
+7189
+32248
+27235
+22533
+21518
+982
+3538
+30325
+14276
+24188
+26649
+2194
+28544
+26495
+575
+21235
+28086
+29304
+23115
+7969
+27166
+31132
+8521
+5912
+20795
+9534
+14623
+25101
+26871
+27889
+29369
+3985
+15714
+3119
+4099
+28501
+4046
+26124
+18948
+29943
+11480
+23684
+11070
+15720
+16026
+11645
+11867
+9651
+25460
+342
+25053
+11664
+30470
+32030
+25302
+28816
+21193
+17148
+28807
+24121
+8837
+2468
+5554
+32746
+11561
+2362
+380
+16458
+31104
+543
+7177
+18801
+25572
+25217
+23500
+25248
+18033
+31146
+22132
+12883
+3241
+28503
+30965
+17355
+30647
+21831
+23942
+18180
+10778
+27390
+5145
+15090
+8986
+10309
+7326
+27441
+10211
+26445
+14871
+324
+20071
+29754
+21122
+30615
+7322
+2371
+10852
+20563
+5645
+31107
+10135
+27579
+30384
+28092
+2138
+2680
+10419
+11504
+1804
+20966
+31631
+5857
+24246
+11756
+57
+20808
+3100
+8876
+27903
+30431
+21765
+5014
+2901
+6285
+2772
+5160
+1517
+23668
+2779
+29789
+11231
+29869
+10446
+17962
+17154
+32228
+16881
+22177
+7754
+20378
+11475
+2303
+18045
+23722
+25768
+28943
+23420
+30579
+31036
+28592
+21242
+27258
+10914
+6631
+19413
+21694
+21536
+18811
+26537
+16507
+3229
+23883
+5302
+1165
+26739
+6211
+10168
+24952
+24069
+16861
+23028
+20903
+20342
+6585
+1447
+29432
+13317
+2853
+1099
+80
+16929
+14770
+64
+15289
+18864
+32469
+1022
+30021
+12744
+31914
+19773
+1651
+13908
+26331
+26124
+24597
+22651
+10997
+25729
+6556
+4935
+28900
+24415
+8585
+18974
+10739
+24678
+30511
+32098
+22600
+8937
+6327
+15416
+9619
+1894
+3117
+11107
+13931
+19375
+7408
+7874
+11120
+29715
+15645
+23955
+10391
+7845
+1916
+7111
+21769
+25217
+24406
+16172
+3406
+11843
+30870
+31980
+10077
+9794
+29464
+26202
+27791
+25044
+17407
+22875
+6845
+8738
+10741
+21568
+28892
+15343
+6603
+6732
+5443
+1284
+31505
+21275
+17186
+6675
+12134
+7886
+12680
+30082
+18927
+10474
+24562
+19688
+13807
+7861
+8596
+19622
+27972
+14155
+15635
+31367
+28514
+14387
+17392
+27821
+7348
+6562
+910
+15117
+4970
+16932
+4413
+6508
+17372
+18765
+10510
+5425
+7339
+20868
+3467
+28366
+29209
+4217
+20686
+15428
+25228
+3396
+17094
+5168
+14587
+6351
+27334
+16678
+27275
+557
+32131
+28069
+15233
+26187
+25406
+8054
+15212
+1621
+23903
+23345
+13689
+17301
+15399
+29396
+26021
+31787
+7017
+11685
+32110
+25753
+21618
+20471
+3636
+11194
+1036
+25994
+27106
+5604
+19732
+13658
+27266
+10853
+10936
+20189
+24614
+2051
+20515
+30422
+31958
+3337
+2368
+8720
+1460
+3631
+20604
+20128
+11235
+25119
+6376
+21472
+17356
+21979
+17539
+15532
+27034
+17425
+28460
+1104
+24107
+3803
+9025
+22308
+14180
+25792
+20231
+11488
+32652
+28260
+10551
+32116
+7636
+7060
+15652
+21111
+19851
+5482
+16397
+14222
+29962
+7170
+4582
+24063
+11665
+18045
+22491
+4650
+15287
+9070
+19167
+16552
+31599
+24245
+27869
+30729
+20493
+11633
+12008
+21036
+27895
+6210
+21116
+4321
+18576
+6075
+8778
+30587
+30268
+11608
+15338
+13845
+29464
+19133
+294
+16501
+27536
+31758
+19625
+15788
+13824
+27944
+2361
+7650
+16030
+21157
+6091
+12098
+25416
+13647
+10616
+11512
+28313
+7857
+16290
+25456
+3134
+23898
+31386
+19287
+4757
+7131
+30920
+19829
+28333
+29989
+3861
+28184
+3071
+24803
+2481
+29606
+21751
+18788
+955
+10728
+29428
+13344
+17968
+6147
+18945
+10566
+20983
+24151
+17952
+12602
+9790
+23807
+3946
+9078
+24109
+4899
+10296
+11179
+11406
+18670
+9900
+13238
+12021
+7721
+25563
+29342
+2861
+28362
+19221
+1289
+13026
+24867
+494
+30705
+5389
+18737
+23901
+24383
+25342
+16512
+17161
+24179
+27847
+10744
+32708
+23904
+5461
+19919
+11458
+19867
+21037
+24489
+11321
+5393
+11843
+22485
+15712
+17929
+6274
+19894
+4849
+25278
+31497
+20137
+27805
+32505
+15329
+24470
+11719
+230
+14750
+21088
+17070
+25389
+22907
+22119
+9902
+17108
+16809
+25886
+27237
+22505
+22658
+29315
+19476
+23604
+9768
+25663
+14257
+26254
+10126
+12068
+11388
+16412
+18833
+5926
+30802
+28561
+20754
+15596
+26476
+11872
+27737
+5636
+15802
+11614
+7743
+24013
+25180
+16761
+12424
+808
+21700
+14947
+25413
+5347
+8427
+32172
+257
+16144
+980
+6329
+24132
+7889
+1361
+23476
+11980
+30146
+21939
+13739
+8677
+2172
+11580
+27133
+5844
+26392
+11596
+31157
+11627
+30999
+7717
+11327
+9084
+16981
+32444
+4613
+15423
+29078
+26723
+25961
+3394
+17768
+32531
+31874
+28892
+6915
+2640
+15759
+5599
+3642
+21261
+15758
+31349
+14681
+24694
+2012
+8142
+13466
+10834
+8177
+20415
+19830
+13526
+29528
+13938
+16541
+12506
+4116
+24619
+27401
+27164
+30178
+27202
+20125
+29300
+19524
+20546
+22323
+5995
+14730
+12734
+29473
+11243
+4521
+3276
+32295
+23798
+22286
+10254
+1841
+32675
+26937
+27748
+19171
+22041
+15934
+12762
+15178
+11696
+19366
+13387
+20600
+15101
+32228
+15512
+17304
+26720
+11386
+14374
+8721
+13976
+30936
+23008
+16141
+19026
+9457
+8327
+10703
+8849
+9575
+24171
+3586
+30137
+28121
+3837
+19049
+27935
+27320
+8509
+32212
+8298
+13635
+6929
+7673
+580
+4861
+24918
+4882
+16307
+17157
+19534
+15787
+29052
+23605
+23358
+7656
+15477
+19300
+23281
+14860
+11005
+29489
+27849
+13985
+15797
+25690
+4882
+17080
+27753
+7699
+12931
+3745
+14562
+15017
+21399
+6304
+26827
+6627
+14910
+1128
+2153
+30467
+13549
+21469
+32068
+12463
+30045
+23993
+15766
+32154
+17021
+30974
+3102
+24355
+14753
+7365
+29147
+8247
+17600
+27413
+30814
+7477
+20477
+3888
+14586
+29902
+16306
+26519
+13280
+29335
+26423
+3937
+24439
+18534
+27765
+18502
+5218
+32305
+7943
+11624
+17121
+2958
+26373
+10552
+18053
+30855
+9490
+4097
+745
+12912
+12006
+16335
+30060
+24272
+30895
+25328
+6286
+28602
+25396
+12123
+13836
+30596
+22849
+23709
+27678
+23989
+24620
+7741
+3930
+5760
+26684
+30998
+18188
+6137
+14395
+18299
+4619
+12819
+10408
+1022
+14005
+23675
+21823
+14550
+6673
+6694
+26877
+551
+354
+6069
+8105
+23375
+19112
+2875
+4896
+14363
+10217
+26857
+20871
+12731
+16860
+11039
+16691
+19110
+7360
+7909
+32576
+5397
+17016
+9344
+32078
+18400
+25368
+1113
+9489
+11507
+18554
+4581
+1355
+15534
+7636
+31755
+26202
+30944
+24848
+6142
+28972
+16926
+30538
+21209
+30873
+15481
+21234
+19417
+12809
+7310
+1118
+5418
+8314
+31583
+27444
+22902
+30549
+17761
+13598
+28425
+5750
+22255
+4466
+30991
+28367
+4667
+10971
+14012
+4341
+26601
+14369
+17196
+13841
+18241
+13210
+1534
+10110
+28731
+31195
+26738
+17040
+8275
+23795
+7069
+9090
+24391
+31817
+24388
+12892
+2193
+9682
+11003
+56
+12762
+11782
+21794
+20347
+13832
+8443
+7283
+2155
+20502
+31600
+17917
+12991
+27738
+14876
+21535
+1919
+30864
+26332
+21265
+15794
+6424
+12938
+23350
+21381
+27133
+447
+28041
+4950
+18878
+10939
+12709
+9032
+32619
+27621
+25415
+31322
+2033
+15299
+12664
+26946
+10194
+3510
+18000
+25468
+13484
+23735
+14838
+8030
+10019
+9207
+31093
+14144
+2103
+2694
+9646
+28585
+4196
+14749
+20159
+31442
+7102
+316
+15050
+428
+2604
+32312
+22908
+14380
+8480
+27720
+10066
+11128
+945
+6367
+6847
+17844
+22489
+4575
+26759
+5570
+20922
+19770
+16980
+28738
+22374
+15891
+10167
+12926
+8845
+13205
+9988
+16984
+17359
+1431
+22390
+9609
+32213
+24810
+90
+28919
+8438
+12038
+23311
+30023
+18653
+23394
+15220
+29864
+5982
+29959
+25690
+1771
+3257
+3605
+8766
+15100
+11742
+27533
+16650
+15301
+9904
+10551
+6588
+22162
+23242
+20629
+6427
+1396
+9302
+17374
+21327
+7521
+28376
+25672
+23495
+11837
+27069
+21382
+11802
+26018
+15861
+19928
+18077
+8020
+4571
+104
+2466
+11525
+20180
+5003
+23586
+5340
+14971
+8430
+14494
+17615
+16812
+21244
+31223
+4854
+10836
+11275
+18917
+9053
+317
+32688
+17185
+27378
+21264
+25096
+11695
+24650
+25128
+30065
+27640
+12590
+1812
+27874
+7912
+16720
+8861
+3785
+20079
+1634
+22224
+3804
+21965
+18069
+8352
+14358
+30184
+5089
+22269
+21646
+29538
+27685
+7008
+29095
+21796
+481
+2165
+23602
+449
+27974
+17513
+26567
+26613
+17639
+24952
+21445
+28934
+28191
+21202
+13499
+8142
+25485
+3675
+6691
+5857
+26453
+12221
+24286
+25495
+2931
+20762
+23511
+7813
+22580
+3934
+16626
+9473
+12201
+22448
+4494
+10556
+32650
+5232
+584
+5106
+6655
+29954
+8405
+10486
+20559
+13954
+22495
+8142
+14439
+16926
+25289
+6563
+14969
+11891
+14268
+23493
+14242
+17734
+16908
+30686
+11459
+987
+26472
+1388
+20516
+3564
+21569
+9611
+1328
+15906
+20181
+12947
+3368
+1239
+4742
+23673
+23040
+24398
+11393
+28000
+2140
+4096
+8284
+16243
+14694
+8206
+15504
+27844
+31974
+4433
+2858
+12908
+4642
+9954
+1221
+30701
+15152
+32660
+6395
+14114
+20320
+22871
+11622
+19562
+27069
+6103
+24031
+3137
+15896
+30620
+20323
+15324
+13640
+18390
+28724
+14694
+11359
+23929
+563
+2593
+16661
+6240
+26459
+25669
+8293
+2832
+3112
+22502
+23450
+8495
+24298
+9306
+15717
+127
+22689
+21344
+5777
+19787
+18467
+6613
+18231
+6866
+5767
+11466
+8956
+490
+27625
+18729
+19327
+19443
+6747
+4859
+15781
+28652
+19268
+3016
+14075
+18047
+26094
+7394
+22286
+13581
+7630
+31254
+31881
+12145
+23091
+29110
+1328
+17798
+11952
+24982
+30827
+28182
+2081
+29875
+23748
+31196
+12493
+3271
+11735
+21275
+12943
+1394
+20836
+10908
+9364
+14983
+8896
+5956
+15396
+1361
+25002
+506
+25285
+20900
+12594
+2358
+32170
+19610
+21025
+19696
+21063
+28878
+6378
+1929
+1401
+31183
+22430
+2668
+27569
+22984
+5974
+25176
+9778
+29906
+15901
+10807
+24030
+26562
+5534
+31645
+20315
+5207
+2498
+19160
+26161
+21053
+22295
+19630
+3948
+16996
+30892
+13850
+7875
+26144
+25725
+3409
+27254
+13769
+17217
+2399
+4873
+29022
+28950
+14648
+15167
+17918
+22917
+29001
+13185
+8254
+9232
+17637
+20265
+14056
+31787
+18019
+15049
+6679
+10985
+29720
+6317
+12191
+10382
+17260
+1743
+14740
+21390
+27738
+19495
+12769
+32742
+10272
+28705
+21823
+21674
+6287
+5391
+21700
+24835
+15665
+1232
+14101
+29104
+13671
+12843
+550
+27023
+22625
+30486
+5852
+8103
+11877
+7872
+10482
+30346
+2745
+13878
+19318
+27353
+2419
+32042
+6350
+19911
+4840
+27404
+12744
+1077
+2718
+24854
+1963
+17723
+18347
+32657
+17779
+14337
+744
+31809
+11662
+1672
+2395
+27135
+7258
+2707
+23608
+1671
+9883
+11767
+21996
+6134
+21537
+30482
+27247
+19358
+11428
+29501
+18234
+30865
+19384
+20001
+10309
+5702
+10970
+2803
+339
+18677
+7117
+28414
+12230
+12374
+8617
+1272
+22483
+4965
+26890
+26660
+15623
+19820
+3926
+9490
+26633
+26100
+16296
+22439
+20267
+21784
+23186
+30130
+17224
+28836
+17153
+19045
+22401
+970
+28441
+6202
+17506
+22765
+27232
+26637
+31567
+18857
+19553
+10768
+24026
+20439
+28840
+23810
+19664
+11057
+16396
+12388
+13736
+20997
+25932
+14699
+26142
+5953
+26334
+5656
+13511
+7764
+24834
+3372
+25353
+16030
+16191
+7198
+19115
+30577
+14564
+20226
+13972
+214
+769
+1264
+856
+20854
+24488
+17631
+13466
+18361
+24645
+28955
+17298
+19609
+4400
+4515
+16560
+1700
+14006
+5039
+6138
+27227
+18934
+28694
+25728
+14989
+17364
+16153
+14224
+32074
+17755
+8654
+9179
+16226
+31806
+5819
+27957
+29209
+30241
+10453
+26426
+23923
+28117
+3736
+30519
+32177
+12374
+11328
+25816
+22977
+15052
+25187
+28478
+28819
+7913
+10509
+26135
+19013
+19196
+9631
+7068
+28455
+6060
+25232
+10237
+12429
+19758
+19749
+27167
+30594
+17520
+12795
+13344
+28805
+19003
+6299
+16419
+25739
+9678
+16784
+5601
+10715
+1449
+25156
+8345
+27472
+2070
+14500
+28909
+3526
+28574
+9741
+31340
+2349
+6231
+5443
+11482
+18403
+9663
+24476
+22705
+9252
+31779
+14497
+4574
+20992
+9167
+11194
+30730
+5942
+4647
+25904
+27986
+31851
+31304
+15032
+9405
+12684
+3121
+11074
+22133
+17927
+6033
+3779
+22143
+32626
+13912
+30793
+21034
+31344
+28469
+18178
+1252
+29063
+7815
+26151
+12025
+115
+23578
+27068
+3505
+4064
+1908
+29512
+15386
+11295
+28136
+27453
+19967
+16478
+6190
+4568
+7220
+25137
+15051
+3795
+25428
+26777
+13087
+2437
+17564
+13128
+25045
+15188
+24330
+13962
+19257
+20534
+16856
+30490
+6260
+11402
+22695
+22956
+31334
+7059
+31071
+32157
+4920
+893
+8651
+20516
+9799
+11202
+1923
+27041
+1866
+16833
+1630
+9963
+24034
+17335
+21560
+23433
+16781
+26073
+16608
+2523
+25117
+12967
+10818
+12558
+10960
+30074
+28571
+29064
+14824
+23783
+1980
+29872
+8131
+32133
+27405
+16277
+7503
+1884
+19049
+32576
+4639
+22728
+23456
+6853
+22989
+17394
+31787
+18529
+11501
+20121
+16635
+21186
+4604
+1241
+30687
+192
+876
+81
+26568
+9781
+14025
+27257
+20719
+18740
+6655
+1525
+24390
+13318
+17334
+10313
+8420
+6433
+5007
+17446
+27553
+22018
+15153
+15256
+11828
+7680
+14163
+23515
+24957
+30993
+8308
+15576
+10334
+30743
+22320
+13317
+25107
+8103
+22788
+25511
+1951
+3711
+23967
+15729
+6450
+16117
+3211
+11682
+1858
+7079
+7546
+25425
+692
+6128
+15591
+9607
+8048
+15648
+10999
+3775
+23979
+23562
+29012
+6862
+6098
+11178
+19586
+12593
+21033
+10571
+10092
+17159
+12371
+24271
+17839
+6034
+10646
+32593
+19496
+5170
+12479
+30507
+23503
+16653
+24704
+8015
+10013
+5574
+12717
+4553
+19634
+1026
+28320
+8159
+7482
+31446
+11143
+28484
+31498
+2854
+16214
+23204
+4545
+27226
+25237
+23006
+11086
+19609
+2689
+25584
+20246
+28033
+28506
+22807
+13098
+26321
+21980
+15534
+27076
+31137
+32474
+29392
+27688
+28788
+31964
+30055
+29417
+21544
+11115
+13224
+12418
+28835
+32431
+23070
+13128
+2969
+4665
+5661
+2996
+3966
+26744
+24819
+3987
+12416
+24907
+16734
+21290
+2312
+16126
+23275
+21388
+22833
+31356
+15698
+6951
+28568
+6864
+29686
+25961
+29768
+21217
+31918
+17422
+10834
+15195
+756
+32414
+29982
+17819
+804
+27317
+27387
+12860
+22535
+32344
+4541
+14964
+28225
+17641
+19997
+30395
+9181
+15306
+8321
+17554
+7770
+21505
+26455
+21258
+32082
+16804
+18505
+2835
+22687
+2471
+25701
+19195
+21815
+23913
+15532
+264
+26412
+6888
+15870
+18451
+29968
+16642
+9500
+4515
+14742
+19022
+30844
+25657
+13120
+20619
+2573
+13228
+8288
+13746
+28956
+11478
+23617
+29397
+18098
+7190
+16454
+30236
+30707
+10910
+9670
+11784
+21871
+14899
+10793
+10878
+30113
+15811
+29882
+7925
+3711
+4057
+8473
+7381
+12284
+30022
+3089
+22465
+25476
+14250
+17660
+9216
+21176
+24720
+19678
+19600
+17250
+2660
+2342
+21589
+30195
+31530
+8065
+3902
+23108
+686
+15909
+12898
+6674
+27909
+13608
+7297
+9884
+29088
+28344
+17245
+11332
+18423
+18150
+1022
+18042
+8481
+21278
+1827
+16146
+27552
+11453
+862
+26723
+6098
+31246
+27737
+26501
+9415
+22577
+14715
+28647
+32662
+32201
+18094
+5284
+27071
+19356
+19138
+24170
+20554
+20103
+16485
+25073
+23799
+11113
+10514
+1532
+5665
+31278
+2822
+30472
+26124
+31485
+8850
+28578
+9605
+6455
+16991
+10230
+11008
+14623
+22657
+21611
+6527
+11025
+14685
+14922
+29528
+19036
+6978
+9970
+5667
+3226
+10057
+32173
+12904
+28970
+14403
+4865
+18169
+18224
+29677
+29273
+27196
+16255
+30277
+28817
+27130
+29039
+21415
+13237
+29385
+13710
+11352
+2466
+13867
+2687
+27909
+986
+15038
+14093
+31549
+6313
+7568
+32702
+18229
+9896
+6082
+3681
+21714
+28144
+18178
+10646
+3805
+2013
+4993
+20672
+15680
+31583
+20993
+24062
+30304
+24226
+4009
+23927
+23629
+5189
+24769
+26584
+15972
+23074
+18696
+23973
+8244
+22077
+151
+28482
+7153
+2403
+4128
+19414
+396
+26750
+25484
+12964
+1678
+8753
+27733
+2134
+8080
+29179
+23051
+23821
+16959
+221
+20960
+2412
+15245
+30470
+27832
+20647
+12317
+90
+21509
+24124
+21718
+30577
+22035
+5946
+14871
+859
+11
+3301
+12739
+9396
+31861
+6796
+14516
+20966
+30856
+30626
+26603
+7712
+1464
+12395
+650
+3258
+12333
+5116
+15989
+16894
+18782
+25691
+20659
+15168
+5740
+15525
+5556
+1492
+17534
+28112
+19967
+20642
+3260
+21581
+25598
+27575
+30100
+861
+5940
+7608
+30888
+12488
+26839
+20182
+4792
+18794
+466
+18015
+19360
+17366
+29447
+2220
+208
+4938
+3945
+24856
+7397
+17738
+9316
+32077
+2720
+26768
+27387
+11069
+911
+27509
+30345
+19998
+21313
+32072
+13732
+23641
+12616
+2903
+21299
+2416
+25739
+9183
+12491
+11189
+7043
+24180
+24201
+11943
+8904
+21710
+20180
+31333
+19502
+14646
+16514
+21907
+22640
+17352
+9608
+19378
+13841
+23330
+29559
+25888
+22251
+5747
+13632
+15186
+8820
+18645
+21017
+6487
+20143
+2707
+2919
+24375
+26984
+22859
+2414
+19752
+18113
+26743
+1665
+16238
+2084
+14754
+22485
+11714
+24297
+17986
+25982
+25362
+32072
+16011
+14245
+30746
+6391
+9401
+17240
+25458
+32547
+30467
+2878
+20673
+24654
+28366
+17619
+9122
+1597
+25497
+11620
+7970
+11149
+28405
+21106
+24523
+15001
+15927
+11585
+17382
+25624
+1847
+28458
+28823
+9994
+10186
+6083
+11689
+30477
+20810
+29659
+32175
+3824
+969
+23041
+21664
+8657
+26745
+13660
+20553
+14384
+2584
+357
+12114
+3178
+10225
+29647
+26569
+31633
+16379
+14749
+9593
+19748
+9092
+20454
+14717
+29314
+27567
+24896
+22518
+3000
+31889
+29210
+17528
+31740
+13418
+17903
+27995
+12428
+31506
+7845
+12926
+4399
+26241
+20308
+14494
+13480
+23898
+777
+4482
+11206
+1695
+27648
+7913
+32124
+31330
+26004
+31925
+5938
+7955
+26343
+22
+26566
+21266
+3505
+4788
+8449
+7171
+25567
+26668
+24952
+19586
+11979
+15641
+29237
+12526
+437
+24619
+715
+32261
+19332
+26238
+4053
+2403
+5401
+17893
+27424
+18206
+14230
+10127
+19028
+4967
+28630
+28858
+31159
+8957
+20167
+11237
+29528
+14369
+7379
+9417
+24266
+24076
+8183
+25226
+1833
+22594
+945
+13456
+5784
+32338
+22716
+29215
+9386
+18916
+26771
+23415
+9805
+21019
+12785
+952
+31214
+5930
+7952
+10297
+3214
+29285
+5993
+6258
+14896
+25743
+3560
+16461
+12060
+31983
+29015
+13814
+715
+152
+8109
+14404
+15682
+22506
+7637
+10144
+15815
+10141
+25917
+24867
+30229
+7852
+20326
+3824
+22652
+3730
+12343
+18707
+15897
+4096
+5595
+6240
+5604
+27694
+28702
+27647
+21821
+18345
+32280
+6692
+24211
+23059
+17520
+13559
+28301
+18366
+17128
+23185
+4050
+25896
+19554
+3222
+26771
+20616
+27111
+23612
+4629
+30809
+14777
+25660
+25953
+5000
+26034
+24102
+25953
+28383
+5543
+11756
+16071
+8163
+11722
+24938
+14291
+13014
+8887
+16467
+12910
+7219
+3435
+2424
+505
+16666
+12769
+32055
+30269
+19967
+30877
+12386
+19668
+4325
+32233
+30239
+14280
+20825
+29945
+23987
+26166
+5513
+31129
+26721
+2196
+24898
+3547
+26291
+16330
+12184
+22299
+1474
+14470
+1625
+24269
+12205
+19143
+7482
+8692
+16255
+32449
+28605
+1620
+6362
+21603
+25209
+10408
+23713
+10083
+32421
+9905
+631
+9739
+26913
+7389
+15107
+30374
+12733
+12389
+2782
+8029
+19009
+7497
+32080
+27855
+13720
+13285
+11947
+7034
+14568
+21610
+22481
+6322
+30828
+16978
+18021
+24276
+25550
+7142
+25670
+29276
+12344
+31681
+32173
+6496
+9205
+28999
+10363
+27272
+21035
+14709
+25543
+30473
+8499
+24284
+24312
+10742
+2210
+28217
+10320
+18293
+2343
+10584
+31297
+3887
+12420
+22325
+4714
+4358
+19256
+4195
+12237
+2327
+1631
+9176
+714
+17535
+5374
+30169
+19612
+14664
+21381
+1835
+23246
+20932
+20625
+2810
+20150
+26134
+19819
+29483
+14647
+6262
+18180
+2706
+18103
+23721
+32406
+29251
+11641
+14654
+29216
+25492
+13548
+11221
+28186
+4826
+23471
+29038
+2982
+4110
+25042
+30807
+22979
+12575
+2995
+22298
+13846
+32054
+8097
+12398
+10766
+10558
+22149
+26103
+22752
+32600
+6086
+27084
+28123
+2299
+28133
+6614
+28536
+1820
+5763
+6732
+17195
+29159
+10845
+24583
+3797
+7451
+7762
+29333
+27002
+5068
+30927
+3090
+18597
+29568
+11608
+9206
+11600
+12318
+8495
+17837
+6207
+117
+10283
+20377
+31938
+29072
+19901
+22630
+20130
+7259
+16844
+134
+10013
+10073
+7163
+7678
+20177
+14172
+16489
+21194
+29812
+7048
+17266
+13540
+3981
+12259
+2048
+22693
+23875
+4811
+27356
+23910
+2798
+12774
+16689
+12319
+4134
+27971
+27373
+7210
+13367
+16776
+1959
+1737
+19363
+22544
+24770
+14865
+23412
+17112
+6469
+21893
+25058
+31284
+6028
+15739
+233
+25341
+8636
+24090
+19242
+25787
+32128
+10605
+29335
+28622
+1857
+2014
+16073
+10695
+4576
+18574
+8219
+6851
+11348
+1731
+2807
+10901
+25489
+32258
+3958
+12963
+4489
+26605
+18555
+10113
+18826
+12848
+7657
+26998
+6134
+25912
+7470
+31769
+2599
+13872
+25622
+7592
+23977
+24472
+11160
+20547
+14948
+8700
+31290
+5661
+10312
+12058
+6999
+6916
+27521
+13391
+24734
+26398
+8486
+3936
+8926
+19062
+25237
+29519
+115
+23160
+13745
+15410
+17181
+21221
+32675
+25783
+26057
+19841
+9450
+16415
+27990
+23441
+25784
+2552
+11659
+15919
+18604
+26493
+28322
+29401
+20803
+16518
+25858
+16787
+18665
+27516
+17635
+16670
+22478
+22657
+17946
+12867
+32139
+28807
+22242
+24753
+8727
+18261
+15706
+15623
+15410
+10733
+21499
+10609
+28307
+16191
+24661
+17685
+5344
+21733
+19703
+5280
+14119
+1836
+10105
+16017
+20183
+16307
+11703
+5963
+767
+25371
+11781
+3533
+24111
+1847
+32517
+19551
+16869
+29749
+24901
+19818
+15014
+11405
+14747
+14145
+13782
+10259
+18374
+26193
+11404
+27901
+885
+15032
+12290
+30282
+4716
+7689
+7908
+13107
+11206
+32298
+13164
+13807
+1832
+10980
+11145
+26989
+6727
+20399
+4145
+15602
+29417
+20956
+8166
+26968
+17328
+12313
+25957
+620
+15706
+5935
+20654
+11027
+4828
+1355
+22302
+12574
+20904
+3866
+4553
+28582
+21228
+14587
+15381
+17786
+28953
+26896
+26770
+31832
+12833
+21276
+6036
+5950
+3963
+5031
+40
+2708
+6669
+7240
+1314
+17645
+23887
+14515
+15931
+28013
+13178
+16704
+475
+28700
+29244
+29670
+16743
+11627
+339
+11291
+21818
+30233
+10883
+20174
+26230
+1959
+804
+1849
+26078
+6120
+8075
+4619
+12252
+15977
+12708
+11533
+25367
+17931
+14037
+7660
+9173
+7020
+3071
+19045
+30174
+26490
+16701
+13635
+5782
+4218
+23145
+17158
+24842
+5979
+5281
+10468
+15135
+15396
+8153
+13427
+15295
+21684
+14593
+9812
+52
+1144
+2768
+1583
+8850
+28377
+5489
+26294
+30698
+20404
+22018
+18457
+15123
+2987
+13106
+21982
+7396
+32065
+26102
+21857
+30408
+4035
+4508
+16403
+29577
+22048
+31588
+4142
+32026
+24694
+14494
+14932
+7641
+24571
+3163
+26363
+11820
+3810
+20178
+26149
+10417
+13609
+28539
+14584
+30177
+13002
+3400
+16917
+7233
+7849
+15505
+7486
+11548
+12715
+2766
+2165
+478
+29060
+21583
+14700
+3966
+14065
+25960
+16572
+20765
+26654
+19872
+28114
+11688
+14301
+11892
+2523
+25894
+22680
+9931
+5761
+18142
+30350
+10585
+16034
+11859
+31978
+9985
+23082
+13474
+21790
+23532
+14055
+15379
+12045
+18479
+12860
+9473
+7909
+4492
+18706
+29324
+2332
+14410
+20712
+32671
+26842
+31429
+19078
+27793
+24917
+25966
+29462
+21507
+13547
+22020
+17826
+15130
+32574
+27787
+24031
+44
+4568
+10953
+9818
+9659
+25181
+6657
+25169
+4384
+31140
+22781
+28040
+20875
+18639
+14519
+20419
+23651
+13532
+3070
+32034
+26406
+7757
+6584
+22197
+16754
+23547
+29730
+14081
+22909
+26796
+4412
+14916
+613
+4402
+2032
+21995
+23880
+31551
+3411
+28137
+9260
+1093
+10123
+24069
+27337
+29159
+11787
+657
+6876
+10092
+20438
+11509
+21822
+9950
+22243
+5112
+18159
+7802
+10516
+9794
+25299
+16201
+2034
+27115
+28132
+19069
+5154
+27027
+28668
+10187
+13909
+20544
+16165
+23586
+29350
+5844
+27011
+20415
+15430
+20281
+32132
+11962
+26781
+22902
+32150
+15380
+4843
+9927
+5761
+6666
+24305
+24263
+11618
+18376
+25273
+3446
+6134
+18886
+3033
+12573
+2153
+19695
+9837
+6856
+27476
+829
+24747
+21959
+14666
+26707
+22251
+10616
+17347
+28667
+9283
+20389
+11881
+9600
+5980
+27708
+9798
+4827
+13890
+24371
+12800
+16989
+12492
+30016
+6330
+8463
+32658
+130
+12431
+16059
+4846
+5936
+289
+20823
+31993
+26883
+27426
+15366
+24989
+22759
+19413
+18200
+6285
+30813
+25706
+15880
+11197
+21360
+8923
+8632
+24770
+6775
+7320
+6446
+20328
+32534
+15670
+29008
+23515
+12972
+6062
+26766
+24729
+3354
+31962
+9379
+1906
+8034
+1581
+21082
+14793
+1603
+18301
+15375
+19333
+12652
+24760
+2773
+26828
+30707
+10721
+11526
+15680
+21047
+26386
+31341
+21630
+19519
+27560
+1418
+19687
+9942
+23014
+25524
+27002
+32304
+9146
+13785
+3547
+16867
+24501
+12696
+6733
+29968
+4240
+8324
+26870
+19272
+16045
+9634
+24655
+5949
+17509
+8676
+20536
+26103
+25111
+360
+32738
+31100
+25692
+9035
+20381
+2568
+23544
+9683
+376
+10376
+18840
+30104
+4081
+15148
+625
+1409
+9092
+25458
+9094
+25456
+30800
+5886
+14967
+3938
+11117
+22331
+4329
+20584
+9849
+135
+16204
+20631
+17402
+1589
+20213
+3515
+5250
+14452
+4097
+22990
+8751
+4077
+20478
+30961
+20524
+21469
+9003
+32146
+16012
+9873
+6449
+2724
+13286
+3701
+19494
+29959
+28437
+26993
+20723
+8287
+6705
+16833
+6756
+15773
+25317
+913
+19972
+8891
+27522
+30921
+9287
+23547
+6752
+16062
+21807
+13454
+30331
+18522
+26405
+24848
+5387
+25180
+25234
+4083
+23373
+17868
+660
+24548
+13868
+19323
+18890
+12837
+20785
+16647
+20521
+30469
+16589
+9061
+4908
+22881
+6759
+111
+10515
+28235
+22171
+3745
+16048
+27895
+4636
+17319
+24170
+9492
+4116
+24062
+8771
+13429
+6275
+6307
+8316
+24913
+25576
+28656
+15171
+19659
+26102
+11890
+27636
+9106
+5205
+1136
+8939
+10842
+18534
+31159
+2380
+10777
+27670
+26820
+20404
+552
+27139
+8352
+5846
+1652
+28150
+20417
+19111
+13994
+12682
+493
+11826
+8954
+6462
+3842
+4898
+17393
+13388
+8366
+22661
+9885
+19315
+6579
+28753
+6878
+4475
+17346
+9394
+31307
+12159
+29093
+25216
+31514
+11423
+8448
+21752
+12562
+26070
+6928
+26568
+7143
+5480
+5382
+1302
+15157
+18055
+1689
+19140
+26379
+13385
+27701
+16427
+7368
+15562
+17010
+9347
+29067
+8634
+29011
+22545
+4544
+29968
+10680
+14122
+19034
+6890
+11159
+26119
+4483
+27273
+842
+8939
+4289
+12469
+31722
+6089
+17290
+25570
+22525
+19418
+31320
+20337
+20522
+17428
+12875
+14350
+16971
+5052
+17920
+22127
+19494
+11181
+8328
+3083
+32673
+23125
+14032
+26133
+9059
+3287
+8851
+2169
+25316
+14122
+24528
+9039
+14056
+30065
+4656
+26670
+29804
+8863
+12356
+7901
+3821
+5314
+4235
+14852
+1621
+29148
+21634
+17910
+30251
+18349
+20069
+28066
+24691
+27054
+27077
+19575
+27877
+29526
+20460
+13153
+23284
+1197
+7247
+22192
+3105
+6238
+30107
+13252
+24823
+14636
+10146
+14194
+23114
+26638
+9046
+1188
+1696
+7733
+29996
+30117
+16408
+2867
+6839
+1880
+30880
+4580
+26497
+30634
+26134
+2953
+29501
+24740
+25970
+25800
+21199
+18150
+23942
+24989
+17225
+13159
+28160
+29422
+13817
+9900
+13203
+15654
+15509
+13228
+14388
+10121
+15318
+8552
+21463
+9152
+19746
+12270
+30335
+15160
+9864
+22616
+15329
+23803
+11776
+14194
+31450
+14704
+7440
+15034
+21325
+16527
+3299
+13655
+996
+9178
+30924
+22497
+15432
+29696
+18975
+27514
+16656
+10474
+27067
+15137
+5706
+10957
+10902
+12850
+12630
+19088
+27671
+1227
+30096
+3217
+13116
+18003
+14336
+10215
+26705
+21536
+11657
+14146
+4512
+19479
+21430
+2502
+22247
+6746
+17597
+3843
+19252
+3126
+29664
+9147
+8917
+3415
+26796
+9685
+4430
+25407
+29437
+26933
+29819
+1972
+25531
+26109
+459
+27929
+8939
+20263
+19866
+3683
+19177
+17476
+10163
+80
+23530
+31796
+25289
+6675
+30764
+18429
+28362
+17572
+3926
+3267
+5894
+25853
+26559
+20334
+25979
+5709
+24055
+15450
+4496
+19188
+13259
+1247
+27064
+27410
+7290
+13783
+24427
+16298
+31817
+30580
+3613
+21175
+15912
+30645
+10923
+6149
+6240
+30088
+29869
+10249
+17274
+7164
+24256
+11466
+16913
+3486
+8316
+21317
+7410
+691
+26613
+19824
+10876
+21502
+4046
+16528
+31469
+6063
+16286
+23063
+24934
+8467
+2845
+26249
+29254
+5925
+9634
+20023
+7028
+1160
+21871
+8261
+24144
+32749
+22204
+28446
+19376
+19203
+1894
+29325
+19738
+1343
+10516
+1316
+8661
+30739
+17936
+2470
+9397
+10944
+18632
+31618
+28260
+3791
+1266
+24365
+18806
+10866
+17596
+21327
+10812
+9339
+24031
+31133
+31506
+12655
+16948
+8771
+7952
+6621
+7891
+25566
+16906
+29724
+7757
+10058
+7379
+14083
+22151
+23159
+424
+28555
+11844
+17209
+30664
+5599
+3594
+21517
+30012
+26646
+7283
+4959
+4028
+8656
+11293
+24215
+12588
+30602
+23650
+27658
+24360
+25635
+32322
+30114
+9065
+1681
+16839
+11212
+504
+1547
+27606
+25483
+4014
+12531
+21016
+31351
+16009
+18710
+1093
+10645
+9254
+24100
+25698
+271
+12551
+29445
+3893
+10244
+16927
+23239
+26101
+28256
+15587
+9671
+21243
+14378
+31359
+20955
+14796
+7489
+23697
+27427
+2942
+8544
+19593
+30522
+12519
+18585
+27807
+2814
+1003
+23759
+23631
+487
+8239
+8445
+5173
+24597
+15201
+9646
+6756
+28587
+26055
+11029
+4785
+30173
+22864
+14215
+13148
+13269
+8756
+13253
+8706
+30545
+8257
+21920
+7097
+12942
+25850
+11947
+13395
+31993
+30746
+19179
+13720
+25739
+11984
+14141
+10800
+31707
+7209
+28432
+10712
+28468
+31974
+4448
+23475
+7177
+24359
+6694
+24147
+21808
+27412
+12973
+13348
+22080
+24453
+29293
+11792
+22864
+17979
+3700
+5894
+10939
+11861
+4870
+14845
+20588
+12504
+20935
+14368
+25638
+8977
+28122
+22486
+28762
+23460
+13523
+18364
+15601
+9525
+25542
+31679
+5468
+29664
+19251
+23902
+6498
+5711
+25951
+29759
+9378
+16034
+13797
+28686
+21578
+8677
+15
+3951
+6136
+30498
+7634
+29724
+10015
+3360
+2072
+15343
+3054
+32293
+3265
+7820
+17315
+22677
+17074
+2417
+8737
+31470
+15899
+7676
+22254
+29844
+31047
+19973
+1841
+23343
+18237
+20838
+22371
+28546
+7155
+18908
+20078
+26169
+30166
+30095
+20484
+4089
+266
+5402
+10720
+23029
+7654
+3060
+2544
+11939
+11318
+19957
+22933
+3473
+30513
+30397
+5812
+9878
+2296
+29281
+307
+1397
+25131
+10013
+4015
+1080
+10663
+12528
+13265
+8169
+11759
+25148
+28685
+6925
+10719
+15334
+10181
+13110
+26928
+4936
+8390
+32384
+22452
+4523
+17569
+18491
+18668
+11642
+22915
+23716
+27046
+17505
+25400
+17549
+14889
+31090
+766
+17996
+23834
+5426
+10943
+8812
+12550
+24072
+13178
+12488
+26094
+7719
+19713
+9097
+8515
+1161
+27267
+2302
+6029
+29999
+5433
+6793
+16519
+8435
+26633
+23031
+8292
+19670
+16178
+16597
+6686
+29148
+28597
+1986
+3896
+27143
+10108
+1191
+3570
+11810
+2698
+12416
+22910
+3093
+32619
+3386
+9859
+14948
+8823
+22885
+19547
+2975
+16317
+21532
+21343
+21573
+14190
+19770
+24120
+675
+16076
+25011
+2718
+14325
+1281
+22137
+19531
+9936
+20024
+3765
+19316
+26718
+13384
+4595
+15492
+6807
+30561
+10554
+30750
+11643
+8780
+32649
+19558
+4440
+18910
+22024
+20385
+29537
+11195
+15258
+7252
+30158
+20122
+6860
+26165
+22652
+25366
+23459
+350
+28143
+9749
+26521
+4089
+22618
+20515
+21672
+5539
+11779
+27757
+10273
+19498
+1395
+4010
+12435
+16077
+14506
+24471
+25545
+32716
+21845
+7342
+6531
+5843
+5131
+11308
+8101
+13903
+13467
+21073
+5204
+22175
+4226
+6890
+9324
+25420
+17575
+21275
+19952
+27485
+18799
+25636
+9228
+12873
+31254
+28692
+31500
+8641
+16098
+4766
+7327
+15042
+14332
+8144
+26977
+32184
+261
+10898
+3833
+22700
+11054
+31387
+30727
+12721
+32539
+1073
+22536
+17668
+11151
+28788
+28714
+2305
+28413
+21069
+3695
+24667
+7523
+10036
+30988
+9033
+21703
+1518
+4899
+2457
+20499
+24910
+366
+6750
+15681
+11602
+12381
+23818
+4512
+18983
+28354
+15363
+8966
+7724
+13536
+32501
+20532
+9774
+13275
+14275
+5329
+17181
+27904
+24261
+3471
+24871
+32340
+4779
+14306
+12774
+16398
+31098
+24855
+27101
+20046
+15807
+31629
+10540
+12421
+7926
+30557
+20677
+25536
+5889
+32180
+25650
+25288
+30245
+6702
+718
+30143
+10044
+30462
+26132
+588
+4721
+3772
+30639
+13278
+25268
+25257
+541
+29821
+4646
+9879
+14821
+15147
+9323
+14168
+6040
+23270
+28694
+4701
+17054
+21390
+13543
+19128
+12068
+11091
+1592
+27138
+19836
+15164
+3208
+3560
+22012
+16497
+1745
+12044
+5519
+12891
+9350
+8987
+26551
+29697
+19310
+14
+18170
+26083
+15944
+4968
+25798
+18014
+8892
+13780
+19681
+29054
+16818
+22106
+27959
+28132
+23103
+8083
+16270
+14465
+24233
+21380
+20931
+1157
+1712
+20150
+21824
+7990
+23197
+9509
+18693
+5395
+17854
+29811
+27102
+13420
+17162
+2705
+29673
+30863
+13390
+10859
+11409
+16379
+7559
+16362
+14806
+18427
+31521
+23245
+31186
+6228
+187
+20878
+7448
+20178
+31030
+8888
+3874
+24080
+6626
+917
+30739
+31867
+19747
+1137
+19172
+2728
+15886
+15306
+2743
+14984
+2155
+18261
+19240
+2211
+23318
+17248
+6181
+19049
+4544
+8189
+14978
+19916
+26926
+7237
+9953
+18507
+4332
+10640
+24474
+18671
+2739
+19126
+10285
+29817
+3983
+6198
+17671
+6107
+393
+1955
+15187
+100
+24112
+32664
+11868
+21817
+21842
+13622
+6865
+25171
+30008
+22281
+24792
+11217
+19935
+3109
+31227
+2300
+9878
+6172
+2859
+32238
+17674
+17817
+28628
+6616
+2397
+29182
+8699
+1269
+7463
+13109
+10646
+31064
+20636
+24578
+27067
+20915
+23610
+4007
+23599
+20906
+17561
+16309
+21840
+19185
+18003
+13106
+27889
+6510
+11375
+26292
+31468
+21392
+26079
+25766
+3057
+18136
+21076
+23597
+13538
+11335
+7942
+2827
+12509
+18380
+23900
+26459
+19463
+5575
+6332
+7223
+8268
+4007
+27086
+29302
+32449
+27730
+20877
+10997
+3964
+18540
+29024
+11422
+1897
+8780
+30612
+21649
+19884
+1981
+12097
+6891
+5865
+14429
+4423
+686
+12446
+12138
+676
+5166
+32507
+27386
+3448
+28059
+161
+9921
+9855
+13184
+28174
+7817
+23318
+8088
+25899
+3763
+20140
+11041
+14873
+7247
+14841
+14173
+269
+8326
+3238
+2409
+28367
+31905
+23671
+26176
+11219
+22490
+19125
+250
+23094
+17356
+24603
+27018
+3095
+3576
+13253
+30009
+17542
+30017
+23422
+28089
+27019
+21605
+23509
+15170
+17381
+15661
+2503
+3700
+7841
+11906
+6042
+19542
+26876
+20425
+22460
+20199
+22763
+25393
+31858
+27052
+28444
+14841
+24808
+15914
+30802
+30927
+10897
+14623
+25322
+6737
+5993
+8280
+12025
+7286
+21222
+10043
+13871
+27157
+12322
+10327
+6747
+4964
+26434
+30782
+344
+4093
+28170
+32118
+5487
+25397
+23209
+26241
+24635
+4669
+8231
+14755
+15429
+2394
+7205
+29289
+31804
+6032
+18936
+3519
+10937
+12407
+11348
+30590
+14738
+29739
+31125
+20046
+5989
+14275
+7822
+10968
+27738
+24149
+21922
+15735
+11623
+2248
+18227
+15538
+29741
+23429
+13225
+30707
+11986
+7460
+28821
+5355
+30999
+2691
+23959
+14264
+26549
+28945
+13650
+19148
+27997
+10589
+18031
+32666
+1934
+12971
+16307
+8110
+6751
+7774
+20554
+24831
+8869
+19454
+15821
+12137
+20136
+8756
+11962
+3423
+7044
+13344
+23549
+31982
+18756
+12580
+25772
+5399
+13988
+6432
+16572
+12541
+21615
+28015
+28362
+18905
+27959
+24123
+7971
+3705
+31469
+5192
+17420
+5143
+8774
+29993
+2081
+30915
+3619
+30527
+6800
+15433
+7787
+13604
+6272
+19316
+26724
+14215
+17012
+712
+15119
+31742
+13242
+18098
+32084
+25097
+26769
+17808
+8116
+12198
+29548
+26385
+11070
+16997
+9312
+24860
+17122
+13430
+24766
+6505
+5017
+29277
+27234
+1665
+13987
+13923
+24469
+21474
+23812
+23519
+19374
+23541
+29824
+8012
+3518
+32696
+23740
+23627
+22
+26798
+14012
+13716
+10066
+11360
+30769
+8569
+27154
+5444
+20493
+21887
+16722
+8321
+19689
+9477
+2313
+2284
+30671
+26682
+5219
+3719
+7507
+351
+23927
+30331
+12199
+15682
+26144
+7475
+10704
+29276
+4768
+30997
+4384
+9745
+24197
+5693
+15636
+4324
+6167
+26760
+32036
+26610
+1643
+12361
+10645
+12943
+9869
+14208
+2175
+27461
+9285
+32661
+26809
+7644
+2313
+20461
+7375
+13274
+23549
+27994
+25073
+14887
+13140
+1177
+31282
+16757
+4024
+9362
+12485
+8099
+12540
+18773
+5020
+8105
+26744
+23813
+7552
+29322
+30615
+32689
+29222
+18402
+32267
+16705
+25794
+19716
+26408
+14188
+20327
+6399
+23767
+21564
+19660
+4989
+16130
+19466
+298
+11935
+9561
+11682
+12273
+7493
+28627
+15567
+25040
+18268
+1696
+11373
+27238
+7387
+3999
+21394
+29374
+24957
+2271
+12900
+29651
+32108
+28643
+32154
+19080
+17563
+27112
+13454
+29730
+12197
+13846
+4621
+29189
+24480
+17843
+17845
+3991
+18344
+15557
+24792
+15447
+19243
+10350
+9968
+4303
+15439
+9286
+10436
+11031
+5507
+5816
+22464
+20881
+13410
+27760
+23906
+32444
+7364
+19925
+697
+7017
+10459
+3203
+7762
+27966
+15223
+8752
+13805
+12432
+2528
+1981
+21220
+8930
+18727
+17787
+23958
+27431
+27883
+31003
+31207
+1748
+30407
+16874
+6701
+21476
+24321
+26151
+13981
+7938
+23637
+31150
+17127
+4120
+28426
+19721
+15180
+8107
+27165
+13975
+12518
+6041
+30827
+5334
+2513
+15767
+25247
+30197
+30852
+27284
+17179
+16827
+8221
+9385
+5916
+29604
+18664
+13328
+19813
+29855
+7975
+30878
+9423
+25900
+27097
+27635
+19608
+21412
+3729
+29242
+28869
+28580
+12982
+43
+25462
+102
+577
+10978
+3690
+5697
+18197
+607
+27769
+15710
+10683
+4575
+1387
+23587
+9699
+2396
+17214
+21626
+14731
+30913
+7164
+30723
+15396
+12162
+11318
+18939
+11905
+19571
+20693
+10123
+22624
+15967
+9774
+13355
+11268
+5108
+5391
+17766
+27417
+24143
+29030
+8131
+27372
+23126
+30420
+30495
+22969
+12618
+18475
+11116
+28722
+6800
+3591
+7117
+27139
+3417
+32662
+30710
+1788
+19108
+4967
+4834
+32547
+10299
+2147
+17786
+2227
+27889
+28781
+25184
+12706
+10739
+18198
+7678
+11281
+16979
+10164
+17444
+24480
+24244
+19537
+9012
+278
+26615
+24868
+21561
+12180
+28668
+9968
+31446
+19149
+11386
+6678
+22465
+31300
+12943
+27020
+10108
+23746
+28823
+29153
+8459
+32414
+2866
+20862
+18541
+15813
+842
+8288
+18057
+5421
+27242
+2887
+8099
+15571
+2834
+29389
+18829
+1946
+12661
+6676
+23529
+28155
+6496
+3910
+795
+10917
+2720
+19555
+19614
+14724
+13440
+27082
+4484
+18827
+30736
+4127
+1663
+16140
+27471
+27859
+12404
+18749
+883
+17895
+29003
+17796
+13457
+25555
+20630
+18820
+19864
+29854
+26143
+20565
+14162
+9734
+30175
+23456
+12958
+18481
+14703
+24921
+16097
+575
+12124
+27710
+8507
+22964
+5057
+2784
+21071
+29888
+16263
+24077
+32642
+21634
+29200
+20029
+18778
+25140
+28462
+32564
+28533
+15983
+8620
+27397
+26641
+29207
+32402
+22236
+18942
+6972
+22498
+32506
+9750
+16862
+12763
+18109
+31634
+29997
+7805
+22641
+12560
+24593
+18873
+18523
+9500
+5234
+29073
+1016
+20326
+2098
+23103
+13147
+18960
+3700
+10739
+19950
+25196
+28974
+18259
+21075
+7948
+3567
+2122
+28507
+5315
+23303
+30981
+2726
+26872
+18617
+8418
+30331
+17891
+22830
+31024
+1654
+982
+8344
+6772
+32460
+24869
+30698
+26215
+19047
+2985
+12806
+21702
+14845
+26081
+21559
+6347
+26443
+19369
+30861
+15067
+20012
+1578
+31732
+8526
+13772
+3011
+24777
+26895
+2802
+27668
+25724
+19134
+11681
+29914
+15474
+16177
+32671
+16012
+8188
+4098
+16769
+17457
+11959
+8258
+28777
+13287
+17226
+20800
+910
+5193
+29568
+3341
+9564
+5638
+8112
+1314
+20117
+24683
+15672
+28622
+23955
+5528
+651
+8859
+9608
+10878
+28360
+22439
+28205
+9355
+23420
+31971
+26303
+17781
+24331
+5231
+20466
+16826
+25928
+6673
+7719
+27520
+22364
+5003
+23638
+28349
+27681
+11903
+19466
+32319
+2069
+15003
+27854
+29190
+5951
+25743
+8627
+9648
+28259
+17259
+25158
+13049
+15804
+10972
+3491
+5476
+10784
+26087
+20165
+11494
+23730
+19536
+22588
+27916
+2147
+27581
+29187
+22452
+3370
+24499
+3144
+3367
+14270
+19724
+2295
+20087
+12441
+19393
+5233
+19664
+14277
+15842
+829
+19864
+21774
+22932
+9238
+21620
+15245
+20045
+18848
+24987
+10837
+31097
+17287
+9124
+14887
+5756
+17591
+1803
+4570
+20413
+18838
+25505
+541
+23658
+841
+19477
+5647
+0
+8433
+28054
+23182
+28145
+11010
+26920
+29694
+29280
+18885
+26009
+20095
+9059
+1499
+19112
+8280
+14412
+18877
+26934
+13825
+13787
+29519
+8759
+6158
+3174
+8945
+14551
+21856
+20839
+30216
+15747
+14076
+7403
+14083
+17733
+31731
+23307
+20411
+14608
+31234
+19407
+23793
+7506
+18728
+3034
+28382
+27662
+21192
+8069
+5844
+26099
+4513
+1624
+18886
+17231
+6033
+20340
+449
+24960
+18704
+5944
+9737
+30309
+10950
+24218
+6094
+2938
+6601
+3671
+17952
+14485
+25760
+28495
+20067
+25840
+29366
+14975
+5938
+12346
+32569
+15565
+26814
+22598
+4134
+21104
+25544
+4323
+19398
+4470
+6835
+12661
+10133
+27769
+13728
+26280
+26925
+19467
+16207
+5878
+16788
+8480
+1879
+4681
+7843
+5535
+7779
+9719
+7197
+26945
+30655
+28565
+18386
+2448
+32025
+10188
+28698
+29001
+7531
+7808
+14785
+22242
+22910
+1172
+25475
+20299
+373
+969
+8682
+10952
+29484
+5266
+21239
+7424
+7298
+23852
+15989
+5757
+9229
+3660
+27236
+32115
+14240
+15310
+3653
+7881
+20536
+16817
+29968
+9761
+24132
+32119
+16085
+27434
+19970
+14248
+13875
+2254
+15206
+29244
+24688
+4141
+6889
+26681
+9026
+30989
+32338
+894
+30290
+17091
+25065
+10574
+29250
+5356
+19253
+24929
+23654
+26910
+28565
+27645
+27916
+27547
+16317
+27479
+24562
+20793
+20064
+13436
+31513
+29201
+185
+9449
+24308
+2731
+8714
+3277
+8328
+31838
+9803
+23816
+3114
+14991
+11346
+26379
+11745
+13046
+29297
+7863
+11892
+27433
+11169
+6208
+26358
+21460
+13934
+14160
+7511
+5510
+14316
+2908
+28431
+3121
+2856
+17925
+5719
+24270
+19307
+4215
+14776
+6708
+29046
+13371
+20724
+5609
+8855
+5732
+23227
+32630
+26740
+22236
+14713
+24905
+15991
+15578
+12043
+7233
+15815
+1208
+10806
+836
+4536
+31350
+8908
+18111
+27303
+7209
+758
+6342
+6976
+19726
+791
+3988
+23373
+23334
+24513
+15617
+18048
+17150
+22660
+4841
+20833
+23295
+19835
+9065
+28385
+9925
+1780
+7635
+25096
+18104
+13361
+12002
+13726
+27127
+1642
+29112
+12956
+18868
+7356
+17083
+13379
+24924
+4758
+29436
+14507
+12387
+31454
+11327
+3049
+18533
+11550
+18410
+32451
+32660
+29581
+25701
+30751
+5017
+18756
+20477
+3214
+25029
+5956
+5409
+22839
+32130
+8585
+24572
+30448
+12219
+23664
+26906
+25811
+9953
+16014
+6235
+18814
+9557
+15530
+4700
+5534
+23339
+3637
+3359
+13056
+8320
+23276
+28422
+8264
+6176
+13684
+29045
+1523
+14913
+14735
+5750
+26077
+18857
+15974
+19243
+16559
+23020
+19024
+30546
+1489
+3324
+7856
+26345
+8657
+21819
+27493
+31464
+22519
+22471
+7957
+24141
+15188
+12671
+10604
+16480
+514
+10403
+12747
+13161
+3976
+27528
+24820
+26257
+32404
+25254
+7520
+20442
+8760
+26200
+21085
+2402
+16162
+29289
+2536
+13495
+2599
+25047
+17729
+24039
+13475
+2595
+15962
+19537
+32316
+19870
+6482
+9037
+28937
+22379
+22718
+26274
+17230
+24349
+6661
+4672
+29802
+2341
+12889
+7830
+17709
+20418
+30311
+2520
+30745
+21045
+29638
+28764
+25452
+5768
+2012
+12243
+3106
+23807
+14454
+5553
+13744
+26126
+32261
+13526
+1582
+23933
+4970
+12455
+24510
+27554
+13636
+17113
+23962
+28202
+19783
+15735
+7774
+22492
+30159
+4446
+2339
+4509
+8648
+5823
+4153
+15968
+16822
+23713
+5117
+5071
+8914
+20821
+28114
+10930
+11391
+9253
+12777
+28335
+356
+4754
+3080
+6386
+3428
+30274
+1825
+12006
+23317
+5413
+27893
+4959
+29286
+18830
+23252
+17885
+29292
+12157
+5285
+10729
+19203
+3439
+9128
+12085
+31109
+23290
+1648
+21663
+13734
+20608
+21803
+16492
+9771
+9956
+7449
+29993
+972
+1393
+3848
+8841
+32415
+15483
+25221
+10658
+7683
+1399
+5540
+31392
+19465
+16297
+7858
+503
+22382
+8442
+23149
+22060
+6229
+8240
+30268
+7681
+7534
+27467
+19323
+10459
+2850
+3583
+12613
+29600
+21188
+29967
+19627
+9189
+21932
+18857
+6231
+10982
+9946
+4107
+7223
+14869
+25343
+11533
+2949
+29039
+20865
+16990
+20793
+17405
+20521
+27713
+19876
+9009
+3916
+32218
+20118
+10512
+6687
+3428
+21714
+27868
+9279
+26371
+17232
+28489
+32448
+3439
+12380
+13091
+25574
+27953
+2347
+9258
+32503
+10236
+26971
+11269
+15992
+749
+22900
+10625
+32003
+5593
+31548
+29180
+2723
+3241
+29796
+9504
+1549
+29750
+13481
+30862
+26241
+27646
+17290
+26650
+15122
+22642
+28602
+18701
+14564
+19323
+13546
+9037
+18842
+22869
+9496
+1290
+4702
+13589
+9567
+20742
+13319
+29019
+27330
+13548
+19320
+22674
+13361
+14051
+4677
+19764
+24490
+20746
+14462
+12066
+32632
+24282
+24089
+5741
+7969
+21283
+19816
+14076
+6719
+15956
+19208
+9496
+9446
+14411
+30499
+24318
+7519
+31636
+1492
+25187
+2525
+20570
+6833
+13324
+20306
+20958
+27641
+26300
+6455
+8742
+4461
+25544
+1555
+5496
+13087
+29984
+9670
+17061
+6193
+25880
+16859
+18044
+7313
+15484
+7613
+14572
+11609
+2050
+25226
+5512
+23941
+30894
+6732
+8365
+5746
+19507
+28993
+15489
+22333
+17623
+8580
+10751
+20085
+11494
+3540
+8573
+20289
+23711
+7635
+11530
+10979
+21031
+7633
+18507
+3468
+14319
+20440
+9660
+8399
+11406
+29972
+5651
+30492
+2561
+9430
+10206
+4970
+21476
+15012
+16466
+31978
+2525
+13162
+19923
+32483
+1703
+4101
+32391
+28568
+16737
+3631
+19568
+30753
+6099
+29581
+24556
+20389
+12299
+22923
+26843
+14592
+23253
+1664
+3493
+9608
+21095
+2225
+16044
+18505
+21846
+20015
+4558
+13608
+11563
+1249
+3782
+4391
+16743
+2458
+271
+14152
+2916
+11889
+21803
+19086
+22000
+16255
+483
+10589
+19100
+27911
+5085
+22074
+15505
+6964
+4812
+23225
+29386
+24697
+18246
+31551
+14860
+11902
+9247
+15352
+23011
+5486
+4625
+26383
+17948
+12595
+21630
+21362
+2346
+26972
+15095
+25191
+4688
+27575
+4780
+13428
+32187
+8737
+20784
+27254
+5993
+18440
+20679
+26018
+14699
+15692
+4861
+21049
+20918
+22287
+28477
+24144
+1460
+4079
+22557
+5504
+17103
+18890
+5052
+30681
+28314
+24909
+10261
+7180
+9314
+29169
+10983
+17632
+5942
+31337
+24234
+9003
+11135
+31788
+25654
+15425
+10810
+26487
+30160
+27090
+30714
+26159
+28181
+26064
+22616
+6475
+16902
+27565
+32638
+23058
+3335
+1924
+10922
+20371
+5466
+2456
+2814
+25650
+23349
+7675
+10390
+23253
+4393
+17601
+5841
+7291
+5850
+32650
+2372
+3553
+21144
+11037
+16184
+13882
+22231
+30412
+29895
+32483
+14198
+29795
+19366
+7326
+32641
+7873
+23100
+19178
+28365
+328
+24170
+20536
+21919
+3995
+18906
+16323
+14743
+3992
+28965
+32136
+12957
+261
+19976
+9556
+19986
+20798
+27935
+21462
+22070
+14623
+25130
+31027
+24435
+21006
+12775
+21622
+16558
+6374
+32404
+20092
+29490
+10195
+15558
+10687
+28537
+8302
+21690
+12267
+14686
+1606
+10008
+24767
+24338
+25059
+21795
+17259
+18135
+31877
+23571
+9295
+6888
+17429
+30088
+23859
+23748
+30029
+24667
+11141
+1356
+837
+29876
+30884
+4015
+28015
+16332
+4564
+13355
+15023
+4331
+24171
+3192
+20139
+24157
+23370
+6072
+3057
+15700
+5431
+7378
+22792
+19331
+11438
+6864
+27715
+30289
+2672
+30187
+21556
+27208
+25977
+12726
+20650
+28649
+22987
+27164
+1830
+4817
+32215
+21184
+29645
+27083
+19310
+25365
+15783
+22612
+10641
+17141
+15979
+638
+16507
+5521
+9242
+215
+32498
+5138
+911
+24512
+25410
+19874
+28343
+1993
+21693
+31395
+5633
+27224
+27159
+15350
+29025
+20290
+12174
+19293
+4537
+22486
+25479
+25205
+5025
+30193
+32438
+5740
+16852
+4610
+26682
+31681
+32569
+5277
+5896
+19075
+12324
+22489
+7595
+30708
+30601
+5279
+101
+6571
+30195
+22039
+18309
+6177
+29440
+14305
+22343
+15092
+4456
+26507
+5570
+11299
+25538
+6032
+16039
+4096
+8535
+266
+22113
+11522
+32334
+25325
+30748
+12652
+24897
+19296
+26974
+25348
+29177
+23392
+22755
+16836
+29757
+31190
+7117
+93
+7814
+18806
+8397
+7298
+14366
+29660
+10971
+26649
+1690
+17396
+26205
+7494
+9607
+26911
+16340
+13602
+3442
+3021
+24641
+4139
+5389
+24084
+9578
+3771
+20599
+22964
+26960
+20254
+5871
+21559
+11307
+24504
+32703
+7712
+5839
+9221
+29198
+6947
+27940
+12481
+723
+8807
+22628
+23270
+25965
+6120
+20087
+7845
+5622
+6590
+22035
+5940
+9730
+29219
+32530
+10299
+4382
+5167
+22268
+29632
+339
+14279
+15587
+32488
+32182
+31204
+10875
+8870
+27364
+29407
+25302
+4472
+177
+12456
+7953
+15598
+32249
+8380
+15765
+16049
+11173
+6482
+7941
+18319
+15407
+31588
+7270
+15574
+20556
+1855
+4930
+3190
+19663
+29109
+28249
+24401
+2445
+14965
+29926
+934
+17706
+5043
+4105
+26981
+9859
+14594
+333
+15541
+18895
+30721
+25303
+27186
+5760
+19265
+13967
+4505
+32124
+31141
+27860
+3053
+5114
+19442
+14123
+10774
+15973
+247
+7808
+16551
+14680
+26129
+9850
+13521
+12204
+31478
+22675
+29491
+20628
+22777
+28241
+22136
+9506
+11781
+7977
+740
+6075
+15788
+12693
+20958
+3177
+4186
+14841
+26761
+22022
+29391
+13080
+15929
+22816
+6740
+15594
+24320
+22212
+8825
+21486
+25317
+23311
+24494
+20137
+28285
+31707
+14737
+13845
+20721
+15096
+13879
+3951
+26385
+21316
+27786
+32231
+6796
+5635
+15932
+10792
+28854
+2701
+22241
+29151
+9605
+32287
+22427
+22919
+25138
+5178
+9286
+6447
+8727
+23832
+28662
+16095
+23825
+20652
+3489
+8977
+27594
+27850
+2831
+11643
+14580
+23706
+20029
+16653
+3544
+14225
+17566
+13991
+20639
+17874
+3958
+17092
+29340
+1888
+27308
+28218
+26785
+26555
+31314
+16255
+24341
+5709
+27249
+16764
+22619
+5101
+31295
+24143
+22038
+24209
+16404
+4956
+16280
+25869
+32193
+15064
+28443
+89
+10121
+26238
+277
+18810
+4694
+9791
+14341
+1260
+27638
+2054
+32080
+19751
+31330
+1076
+15698
+9920
+18129
+3168
+7860
+3467
+19005
+7732
+16778
+2191
+10997
+28959
+25788
+7997
+3989
+13621
+27328
+1931
+31129
+26609
+14859
+26369
+7192
+14755
+19472
+25109
+11068
+16815
+1510
+2479
+7742
+13423
+14471
+26612
+8407
+17454
+20266
+30700
+25314
+10987
+27945
+26134
+25770
+3361
+16807
+23225
+29025
+26593
+5759
+3303
+12542
+16601
+4505
+32267
+20038
+32414
+30711
+16572
+6897
+25428
+16156
+29276
+14273
+32750
+12395
+25840
+5170
+7835
+1466
+7081
+8900
+13263
+10867
+13817
+9431
+22570
+23592
+4704
+14407
+24372
+7118
+4753
+4868
+5473
+15417
+2315
+23195
+21587
+20574
+31119
+15952
+12456
+2483
+1248
+14216
+5430
+20364
+17310
+31896
+12161
+6835
+14056
+4518
+27905
+12877
+3975
+13028
+20018
+28717
+29833
+3640
+9080
+23633
+8397
+12477
+3510
+28372
+22660
+3708
+12133
+22642
+27210
+32054
+9358
+13524
+4952
+13835
+11730
+28076
+3499
+10827
+21127
+19034
+9993
+2599
+12357
+8587
+27808
+21326
+18340
+2387
+17902
+22506
+30948
+32282
+9568
+1458
+17427
+28110
+6532
+25626
+8017
+8220
+14277
+5063
+11814
+24867
+4614
+31459
+6827
+10732
+3353
+3424
+16321
+25779
+24287
+21121
+13998
+7618
+20496
+3142
+31928
+23324
+22721
+8846
+27231
+16419
+27531
+15775
+22354
+7145
+9976
+4293
+16891
+5286
+24958
+22844
+11634
+18476
+29276
+15136
+29071
+16429
+2083
+32279
+15554
+14547
+31247
+15159
+16900
+19108
+9718
+4854
+3050
+23767
+21107
+6541
+21744
+5823
+6647
+26995
+17391
+18181
+27863
+24635
+27131
+8967
+22768
+5133
+9465
+4129
+11760
+3705
+32071
+301
+22705
+2210
+6725
+1031
+17179
+30075
+3225
+19351
+21968
+1986
+11281
+19349
+23571
+10667
+22096
+16684
+25530
+31696
+23542
+16745
+10528
+7117
+25526
+32593
+24592
+30971
+465
+25158
+10978
+14621
+18922
+31634
+19807
+14832
+31388
+15128
+23317
+450
+6567
+30197
+20897
+30484
+6306
+2993
+27035
+31053
+1628
+13491
+10518
+14175
+6701
+23782
+21677
+31350
+2205
+13697
+26912
+749
+18123
+1256
+18374
+14287
+18831
+3892
+24117
+6782
+31977
+27223
+5589
+7200
+6191
+30558
+30064
+19284
+11696
+13483
+6381
+18146
+30937
+12079
+32360
+13719
+542
+21185
+14845
+16236
+1762
+8552
+22514
+6213
+10407
+15206
+22057
+17644
+1403
+32733
+17864
+5348
+18592
+15796
+13920
+2971
+8499
+20988
+11463
+1436
+31280
+8826
+15415
+32371
+32146
+22442
+7101
+24033
+11771
+30987
+28104
+3195
+13450
+6137
+14551
+26099
+1972
+5498
+10016
+19539
+4083
+27197
+1205
+19880
+4585
+1582
+23235
+3467
+20395
+9907
+21249
+13410
+15296
+28230
+26734
+12113
+19253
+12644
+26173
+26709
+20091
+7453
+8814
+10140
+17049
+5969
+2965
+3868
+17342
+16647
+29113
+31847
+10059
+29182
+32221
+23162
+12749
+22507
+15325
+26623
+17374
+20986
+5004
+5088
+10489
+19786
+30362
+6872
+2739
+7099
+23520
+1401
+8682
+17589
+7513
+32180
+31858
+25409
+3454
+9490
+6084
+1506
+2244
+17333
+27731
+6363
+6402
+3532
+9247
+8445
+28294
+22730
+28131
+8270
+3310
+9328
+3860
+15811
+1741
+18945
+16387
+17961
+32042
+29683
+6582
+22030
+20949
+11452
+10009
+8667
+21190
+2158
+8340
+4423
+4878
+16270
+16220
+3791
+25261
+3241
+27101
+27128
+20819
+16220
+909
+22308
+11859
+31966
+4012
+6257
+28005
+20477
+13994
+7138
+18438
+14440
+20754
+12054
+28722
+6095
+16784
+1906
+32735
+17273
+2554
+20039
+28032
+6465
+22309
+29502
+3855
+32459
+878
+18899
+30217
+28228
+23463
+24868
+20920
+21587
+20223
+4506
+18820
+13284
+25656
+23621
+4059
+5166
+763
+26315
+23791
+10779
+9141
+5534
+1829
+24623
+30532
+19592
+8794
+7784
+5671
+3019
+32113
+12138
+364
+30953
+21783
+6550
+6381
+5374
+23088
+14600
+30073
+31012
+24716
+19314
+19523
+4522
+22089
+30802
+5068
+31475
+14865
+26454
+31293
+30912
+20796
+32193
+15320
+8987
+27933
+16396
+1153
+24533
+18730
+10784
+30013
+6418
+5146
+24261
+6457
+16926
+358
+4149
+16747
+5556
+10976
+10769
+5412
+10676
+16170
+2819
+18242
+29946
+30795
+19682
+15306
+9057
+21448
+18271
+19865
+8225
+13262
+28049
+26803
+3524
+27887
+6318
+7935
+5307
+23069
+30810
+12459
+21603
+2581
+1923
+27751
+13652
+17709
+16731
+2271
+8205
+27610
+3710
+11998
+20036
+3160
+9509
+27886
+17409
+15874
+19651
+15303
+21576
+32085
+817
+10587
+26634
+6262
+12108
+26015
+27553
+23703
+6286
+26705
+17267
+21174
+28505
+32406
+20259
+20985
+30298
+20250
+31411
+23081
+31398
+28285
+501
+12561
+9939
+11567
+15742
+21825
+18849
+13516
+29044
+6324
+4187
+30595
+30145
+32630
+28090
+7374
+23299
+18120
+16630
+9683
+1881
+14532
+32054
+6389
+15342
+24665
+5602
+32076
+24490
+13901
+14245
+24607
+23152
+3864
+9062
+15084
+32314
+28503
+25623
+32510
+30908
+11794
+25801
+9563
+17390
+3946
+14771
+20040
+2505
+14085
+23209
+26349
+28382
+24285
+13946
+22274
+7037
+25714
+21764
+17007
+19887
+28556
+6991
+9236
+26853
+25529
+9525
+4756
+22129
+18308
+31351
+17641
+30820
+7106
+3001
+28791
+20633
+8856
+21661
+25688
+5032
+16156
+30056
+14483
+26059
+4368
+30597
+415
+9889
+15477
+31341
+22043
+20794
+28732
+12690
+13815
+8703
+17638
+3567
+27847
+23291
+15875
+23589
+20459
+8028
+30405
+8656
+3221
+10617
+6404
+122
+26457
+21816
+30147
+5165
+25344
+19357
+25616
+12522
+7133
+3795
+6668
+22093
+2402
+15135
+11405
+12757
+14266
+13503
+8872
+7256
+7804
+6151
+16500
+10758
+12205
+20707
+7020
+6255
+29030
+8917
+28413
+28851
+7613
+10796
+19395
+17360
+19834
+23050
+25413
+8450
+19705
+9667
+24810
+29843
+32707
+11106
+21031
+12081
+31333
+10635
+8679
+30761
+30243
+6493
+18932
+20694
+15927
+12798
+27385
+18047
+30479
+12788
+25413
+28608
+650
+30701
+12741
+9123
+32569
+6625
+17778
+1432
+1350
+29849
+2663
+6673
+1535
+17793
+24541
+29080
+31914
+7420
+8839
+5992
+87
+32693
+4703
+22715
+15033
+3775
+27766
+198
+5032
+20882
+889
+16137
+8471
+16408
+4345
+32699
+3265
+7399
+13495
+7618
+31421
+24156
+16931
+21826
+3620
+4924
+32071
+26767
+17903
+10927
+8330
+28669
+8492
+30720
+1134
+30122
+12995
+21220
+8034
+3604
+6994
+21831
+28874
+868
+20292
+22214
+8880
+1496
+30874
+28938
+3062
+32173
+1854
+6025
+30063
+27249
+22274
+1401
+27762
+31799
+10041
+14699
+19217
+8742
+6328
+7966
+3231
+22349
+13504
+23558
+24015
+32012
+25806
+13742
+856
+12531
+26868
+4028
+12438
+4338
+21321
+3200
+21377
+23359
+20022
+31502
+12007
+29574
+13898
+3601
+9740
+11429
+24277
+16520
+15964
+12046
+272
+27688
+1575
+15681
+19507
+20825
+32575
+21366
+17403
+20491
+15663
+7927
+16697
+16958
+9597
+2556
+10229
+32333
+7541
+19070
+22631
+4098
+12372
+10400
+16768
+22790
+19134
+11477
+30990
+16358
+16085
+27813
+24878
+23209
+12813
+14196
+21228
+10823
+24830
+25161
+26770
+28289
+30606
+14764
+502
+30692
+24965
+4524
+4176
+8002
+18081
+12214
+8654
+2959
+1512
+25020
+20271
+19131
+1190
+28040
+14919
+15471
+24703
+498
+21952
+28407
+14268
+21813
+15320
+1951
+32168
+23355
+16717
+24470
+6795
+20088
+19121
+644
+30236
+32027
+16039
+4958
+16073
+11574
+21515
+16878
+4179
+30699
+9225
+5919
+6466
+30240
+3311
+15698
+3993
+14808
+17907
+30082
+25867
+32613
+30828
+19356
+5516
+23376
+12574
+1173
+31882
+2986
+26554
+13209
+14889
+967
+10142
+19519
+28471
+17320
+725
+11337
+5148
+31453
+675
+21988
+16336
+10461
+2445
+17057
+32721
+8412
+6820
+15369
+12921
+20099
+15704
+4766
+7695
+2760
+31962
+31223
+26590
+31774
+15399
+27020
+7472
+1388
+9152
+26245
+17760
+31608
+21528
+20408
+3800
+18952
+5189
+23930
+18061
+29570
+15060
+29128
+16911
+12079
+3514
+854
+16015
+25657
+2044
+1256
+16616
+4558
+5473
+14682
+7041
+29446
+20518
+8183
+20696
+23068
+14179
+29215
+4684
+22951
+1239
+29680
+15701
+26405
+25562
+11980
+12244
+21366
+11423
+9688
+16957
+32096
+29830
+19931
+8503
+20698
+26191
+28937
+11312
+10210
+13426
+30737
+23124
+7817
+32087
+5947
+23408
+21499
+19343
+21179
+4737
+5
+32555
+8392
+28237
+22837
+31418
+8743
+32319
+2352
+22138
+1255
+7882
+11686
+16926
+6571
+24939
+26398
+14014
+5048
+27325
+28444
+16464
+4201
+31331
+9110
+9663
+29697
+4738
+20601
+25994
+30131
+1764
+7660
+18713
+13761
+20044
+11997
+28248
+2954
+18658
+6016
+90
+23083
+32231
+26629
+21922
+8683
+30605
+5461
+7175
+27603
+10192
+30835
+30967
+19879
+12336
+17598
+13432
+25737
+5846
+27319
+14620
+5115
+3356
+18662
+6166
+9915
+30082
+28721
+20193
+18390
+32463
+8827
+2368
+27826
+25018
+16517
+13729
+1245
+31099
+19850
+23376
+5804
+18669
+24513
+6104
+9440
+3262
+17155
+22277
+18471
+20903
+26133
+14934
+12057
+22178
+26981
+13254
+11404
+14635
+23225
+24609
+28258
+13359
+19797
+21748
+8139
+2498
+20092
+26434
+16785
+13597
+22125
+26810
+15690
+30708
+32303
+29960
+14562
+11278
+27266
+15296
+22930
+14939
+986
+4061
+7148
+25827
+19367
+6386
+29096
+29675
+28034
+8571
+14822
+20422
+9172
+24414
+17526
+26141
+9964
+30976
+4109
+4536
+30000
+32390
+26277
+31377
+8717
+21002
+19586
+11400
+15237
+24098
+24584
+817
+11190
+26053
+3539
+24205
+8656
+5767
+7575
+27691
+15801
+3950
+16140
+32079
+30361
+27137
+7268
+6238
+4846
+1365
+11395
+31805
+17621
+8008
+29146
+29447
+32736
+7737
+22661
+20673
+19496
+32212
+17584
+17399
+14279
+13569
+1709
+28818
+9602
+17015
+16378
+22546
+19328
+2229
+31875
+20023
+20058
+6795
+15160
+11404
+18829
+28762
+30162
+20533
+9276
+15162
+1027
+13172
+9491
+19031
+19650
+1559
+728
+2212
+4252
+6415
+29955
+28900
+9630
+19082
+29812
+10257
+19359
+1907
+21930
+13871
+3858
+13397
+1366
+28247
+19063
+28661
+2027
+2955
+4741
+12939
+26030
+20217
+5585
+9289
+28563
+30522
+10928
+16604
+2398
+20332
+24335
+9905
+28061
+11081
+29377
+13861
+29851
+9551
+5076
+26510
+17374
+20067
+32255
+18908
+14265
+7588
+20144
+22803
+12785
+32012
+21228
+11086
+23446
+620
+12844
+15810
+19207
+23538
+17384
+29320
+24798
+20028
+1594
+26694
+746
+7353
+24133
+22596
+30948
+4850
+6513
+30292
+21795
+4776
+2724
+20951
+12544
+12162
+19359
+22356
+28081
+21458
+15817
+11020
+22291
+30564
+9125
+27326
+9323
+13677
+13796
+15780
+634
+13991
+14174
+19968
+2170
+13449
+11996
+10338
+29021
+11813
+14232
+4495
+8249
+17326
+30717
+21165
+3840
+9811
+22461
+3018
+14087
+23292
+8802
+29016
+32388
+25482
+15587
+14480
+20956
+26758
+30809
+22578
+1018
+18033
+27228
+1347
+8357
+27597
+8257
+22496
+25624
+7869
+12312
+16141
+13437
+22466
+11381
+31599
+22074
+16865
+16198
+20010
+430
+3143
+14953
+30813
+20471
+13230
+5579
+7429
+29317
+21284
+14227
+17737
+24441
+10179
+6307
+4799
+32198
+5398
+13279
+20508
+414
+22077
+2981
+21357
+27336
+6385
+9108
+8028
+7980
+14622
+5641
+19698
+25023
+2150
+6910
+20890
+9917
+6275
+5873
+22670
+9047
+24396
+14167
+32245
+15
+5160
+32549
+11240
+12858
+10038
+1354
+25454
+28632
+10253
+11997
+1550
+19320
+24490
+14163
+19768
+15348
+17356
+17711
+20150
+14609
+14030
+24647
+5529
+5382
+24508
+30952
+1670
+26959
+27031
+22702
+9926
+22791
+8373
+8701
+7093
+18359
+29864
+27241
+29261
+15858
+6950
+3411
+28790
+1516
+1603
+18793
+20551
+2798
+20264
+2307
+27177
+107
+10511
+17642
+5179
+21364
+11911
+25094
+7576
+4786
+1014
+14235
+26237
+19943
+14417
+752
+10558
+29237
+20729
+12486
+17798
+13269
+2536
+7159
+18672
+9519
+1579
+8251
+7979
+29131
+26646
+8448
+10909
+18713
+17556
+3535
+26663
+31677
+32104
+23836
+11463
+27618
+30561
+18647
+28718
+32521
+29169
+17435
+9566
+23673
+16743
+7497
+23783
+2505
+18484
+7833
+6993
+300
+11897
+21969
+23926
+4554
+3755
+10513
+16291
+6382
+2686
+9762
+13639
+27077
+11362
+11570
+20992
+11597
+17387
+17781
+14178
+18960
+6877
+18179
+17575
+19971
+24223
+19192
+11069
+21658
+28644
+5602
+30366
+21410
+1571
+5100
+8487
+22501
+13907
+19878
+29880
+14874
+22216
+10276
+3774
+13645
+28762
+24462
+2220
+6528
+16543
+24469
+26709
+22151
+4377
+18276
+18457
+9996
+17014
+3079
+26085
+22147
+25082
+10737
+15809
+3720
+22199
+17942
+27784
+2437
+17753
+6961
+29158
+983
+28153
+19007
+6964
+8883
+15616
+28327
+14699
+20920
+9276
+4772
+9962
+2450
+29955
+21208
+11274
+7311
+17488
+2976
+25750
+4690
+27444
+21129
+24350
+26150
+7381
+12463
+23907
+16606
+26980
+21267
+8795
+12323
+4222
+26055
+5572
+9338
+4941
+17702
+6964
+12704
+12766
+12575
+10995
+28516
+25394
+3618
+12724
+19373
+27469
+27138
+21234
+19883
+21566
+21928
+10444
+8813
+17711
+17629
+22690
+11110
+4544
+4336
+7646
+12892
+2036
+30339
+21657
+25116
+28465
+18858
+30174
+27348
+12191
+5253
+29573
+23015
+29682
+27551
+28893
+24564
+25370
+24589
+12787
+7142
+28114
+6078
+25698
+32286
+6163
+14463
+17106
+3539
+21378
+19208
+21290
+14682
+7122
+10913
+21031
+23741
+14853
+22156
+8250
+24050
+3975
+4216
+27557
+17102
+7643
+22807
+20333
+7247
+25746
+2522
+4080
+11500
+838
+10253
+14352
+22798
+26282
+20127
+25173
+28428
+12616
+6115
+5269
+996
+12399
+6222
+27689
+18850
+32621
+30324
+25136
+23855
+31516
+16498
+20694
+18455
+2952
+19431
+30269
+31115
+29161
+17739
+3979
+17164
+4571
+31205
+22447
+21309
+460
+18591
+27139
+7597
+26202
+25977
+4405
+20433
+24524
+28858
+4274
+15962
+22621
+28169
+16908
+30288
+10964
+2827
+14467
+23606
+668
+4672
+24217
+23088
+10874
+22075
+35
+18608
+15776
+3894
+18996
+25223
+25009
+2192
+22130
+10936
+28863
+20389
+4778
+2977
+5960
+20083
+8023
+20799
+14062
+7460
+30083
+10791
+17177
+20997
+30998
+23413
+8839
+29417
+18182
+8959
+22434
+27908
+29484
+3004
+2958
+17066
+18108
+4017
+20022
+3311
+21570
+22266
+1171
+11182
+20445
+28180
+2679
+17973
+2684
+31529
+32553
+13814
+32355
+16431
+3121
+9709
+12067
+23080
+10840
+21710
+30705
+17371
+4876
+11982
+11040
+6274
+16254
+16228
+31992
+8428
+3757
+19619
+12511
+22892
+27901
+4284
+23889
+13513
+13576
+29757
+3301
+23712
+12914
+1876
+15421
+31286
+8078
+27514
+17015
+28415
+30811
+31066
+21187
+17502
+11020
+27504
+14362
+31348
+29421
+25514
+24997
+19754
+13334
+23553
+1968
+3680
+24482
+14316
+2902
+31910
+15464
+32665
+27071
+11712
+23123
+21436
+6033
+29088
+25155
+15049
+4155
+28569
+32605
+20212
+13424
+17678
+18371
+11322
+16184
+11141
+26298
+603
+28171
+25398
+6472
+3159
+28996
+29609
+32717
+12126
+5989
+7459
+11761
+20056
+9894
+12521
+12803
+5749
+5476
+13370
+7313
+4570
+12409
+4882
+19026
+2858
+17162
+2965
+9334
+4118
+15724
+18264
+12216
+6654
+19644
+10023
+7551
+14204
+21304
+10100
+257
+13113
+3988
+5985
+1090
+13083
+23757
+19727
+16573
+31365
+21785
+1351
+7991
+7370
+22166
+28116
+19410
+4868
+11587
+19479
+6971
+27667
+29336
+1730
+19248
+32093
+5407
+780
+16207
+11763
+1360
+29155
+5261
+2799
+29975
+24535
+27031
+25903
+18095
+14024
+16464
+28328
+30209
+29894
+17608
+27754
+17490
+16626
+4112
+23148
+16757
+16868
+11660
+28625
+24216
+976
+4710
+12544
+6118
+12342
+26883
+30540
+28306
+27317
+17752
+16966
+19522
+16437
+2407
+5244
+12948
+19364
+14558
+16891
+3510
+32572
+29029
+21677
+22396
+26871
+23757
+14021
+1739
+8191
+20207
+1171
+27522
+18884
+9642
+28561
+17852
+32583
+12392
+9090
+1718
+14086
+4108
+10528
+10425
+24510
+1931
+26078
+5744
+26432
+22622
+12083
+1610
+1655
+17226
+19499
+24136
+31872
+5578
+12248
+16775
+16866
+12021
+31767
+30044
+8101
+15697
+12657
+11362
+31386
+27878
+17352
+7874
+8663
+25389
+25508
+28272
+13336
+20001
+12159
+22709
+156
+13488
+26048
+15882
+14940
+5263
+25546
+14683
+22821
+18031
+25468
+14778
+10895
+15784
+4423
+3816
+30477
+9469
+9966
+3753
+19919
+2043
+10746
+11410
+28391
+10785
+9732
+5419
+27754
+25928
+7607
+9706
+24721
+2827
+16088
+5595
+6607
+8849
+11821
+24432
+22966
+25479
+27317
+24958
+19598
+11459
+3659
+9833
+22748
+9890
+348
+32571
+14784
+4326
+2446
+5936
+3383
+29556
+28369
+11519
+24223
+21281
+14745
+18189
+21698
+16206
+29864
+24173
+1420
+21832
+15180
+17829
+1046
+5159
+14175
+25953
+873
+15828
+26264
+18679
+5704
+10971
+15006
+7733
+1614
+2743
+19534
+17895
+32627
+1327
+11740
+1559
+3207
+8149
+9817
+19354
+18899
+29607
+30574
+4291
+20652
+6068
+24736
+22873
+3878
+17308
+25264
+14140
+961
+8431
+29838
+27461
+21178
+2021
+491
+4363
+4955
+28072
+30119
+24783
+2932
+7778
+22086
+12733
+13727
+10405
+7798
+11726
+22134
+9473
+9235
+1832
+9659
+21543
+30966
+7858
+26401
+1598
+3351
+12672
+29637
+23311
+665
+16242
+7939
+22172
+19155
+15201
+13746
+31761
+32082
+25433
+5034
+14011
+31983
+954
+21828
+13169
+2266
+21539
+7094
+30653
+18673
+1287
+21725
+9168
+22202
+10777
+9679
+5157
+11697
+29364
+13409
+29562
+30679
+29959
+19571
+18430
+11679
+23523
+14458
+3101
+28632
+4198
+16249
+22755
+30890
+1552
+12055
+25749
+3758
+32209
+18738
+11923
+32324
+22099
+14270
+27282
+28943
+18634
+5735
+27545
+17819
+4787
+20169
+12663
+7504
+18446
+13868
+24296
+7397
+10963
+10454
+13026
+15199
+5636
+12189
+16814
+25550
+6129
+6853
+8271
+23223
+17572
+3049
+12190
+25077
+21764
+9153
+32738
+31040
+4449
+7199
+24789
+30920
+22971
+10948
+27394
+1330
+25937
+18439
+3294
+27766
+31581
+19217
+28093
+13078
+15855
+14451
+11983
+29668
+14376
+29118
+17943
+17190
+11721
+6565
+30718
+2499
+3837
+17199
+30767
+29391
+18272
+19667
+22336
+1188
+28881
+25883
+4691
+18493
+22634
+18513
+3095
+27897
+11106
+26546
+11531
+24899
+16808
+16051
+3079
+23314
+17747
+6735
+2347
+15244
+15679
+13351
+3052
+23905
+21376
+6073
+14351
+4595
+16808
+8509
+22910
+3754
+3273
+1765
+22968
+30478
+24446
+32094
+23257
+10385
+4464
+10665
+23159
diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/small_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/small_array.txt
new file mode 100644
index 000000000000..d351c8437d0a
--- /dev/null
+++ b/tools/perf/tests/shell/tools/coresight/bubble_sort_thread/small_array.txt
@@ -0,0 +1,10 @@
+11637
+3799
+23116
+15091
+13022
+15840
+27029
+27563
+25641
+28703
--
2.32.0


2021-12-15 16:04:54

by Carsten Haitzler

[permalink] [raw]
Subject: [PATCH 12/12] perf test: Add docs for coresight and related tests

From: Carsten Haitzler <[email protected]>

This adds documentation about the coresight specific tests as part of
perf test

Signed-off-by: Carsten Haitzler <[email protected]>
---
MAINTAINERS | 1 +
tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
2 files changed, 141 insertions(+)
create mode 100644 tools/perf/Documentation/arm-coresight.txt

diff --git a/MAINTAINERS b/MAINTAINERS
index d46e8469c467..1a93977a0132 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
F: drivers/hwtracing/coresight/*
F: include/dt-bindings/arm/coresight-cti-dt.h
F: include/linux/coresight*
+F: tools/perf/Documentation/arm-coresight.txt
F: tools/perf/arch/arm/util/auxtrace.c
F: tools/perf/arch/arm/util/cs-etm.c
F: tools/perf/arch/arm/util/cs-etm.h
diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
new file mode 100644
index 000000000000..3a9e6c573c58
--- /dev/null
+++ b/tools/perf/Documentation/arm-coresight.txt
@@ -0,0 +1,140 @@
+Arm Coresight Support
+=====================
+
+Coresight is a feature of some Arm based processors that allows for
+debugging. One of the things it can do is trace every instruction
+executed and remotely expose that information in a hardware compressed
+stream. Perf is able to locally access that stream and store it to the
+output perf data files. This stream can then be later decoded to give the
+instructions that were traced for debugging or profiling purposes. You
+can log such data with a perf record command like:
+
+ perf record -e cs_etm//u testbinary
+
+This would run some test binary (testbinary) until it exits and record
+a perf.data trace file. That file would have AUX sections if coresight
+is working correctly. You can dump the content of this file as
+readable text with a command like:
+
+ perf report --stdio --dump -i perf.data
+
+You should find some sections of this file have AUX data blocks like:
+
+ 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
+
+ . ... CoreSight ETM Trace data: size 73168 bytes
+ Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
+ Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
+ Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
+ Idx:26; ID:10; I_TRACE_ON : Trace On.
+ Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
+ Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
+ Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
+ Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
+ Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
+ ...
+
+If you see these above, then your system is tracing coresight data
+correctly.
+
+To compile perf with coresight support in the perf directory do
+
+ make CORESIGHT=1
+
+This will compile the perf tool with coresight support as well as
+build some small test binaries for perf test. This requires you also
+be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
+perf coresight tracing are in tests/shell/tools/coresight.
+
+You will also want coresight support enabled in your kernel config.
+Ensure it is enabled with:
+
+ CONFIG_CORESIGHT=y
+
+There are various other coresight options you probably also want
+enabled like:
+
+ CONFIG_CORESIGHT_LINKS_AND_SINKS=y
+ CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
+ CONFIG_CORESIGHT_CATU=y
+ CONFIG_CORESIGHT_SINK_TPIU=y
+ CONFIG_CORESIGHT_SINK_ETBV10=y
+ CONFIG_CORESIGHT_SOURCE_ETM4X=y
+ CONFIG_CORESIGHT_STM=y
+ CONFIG_CORESIGHT_CPU_DEBUG=y
+ CONFIG_CORESIGHT_CTI=y
+ CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
+
+Please refer to the kernel configuration help for more information.
+
+Perf test - Verify kernel and userspace perf coresight work
+===========================================================
+
+When you run perf test, it will do a lot of self tests. Some of those
+tests will cover Coresight (only if enabled and on ARM64). You
+generally would run perf test from the tools/perf directory in the
+kernel tree. Some tests will check some internal perf support like:
+
+ Check Arm CoreSight trace data recording and synthesized samples
+
+Some others will actually use perf record and some test binaries that
+are in tests/shell/tools/coresight and will collect traces to ensure a
+minimum level of functionality is met. The scripts that launch these
+tests are in tests/shell. These will all look like:
+
+ Coresight / Memcpy 1M 25 Threads
+ Coresight / Unroll Loop Thread 2
+ ...
+
+These perf record tests will not run if the tool binaries do not exist
+in tests/shell/tools/coresight/*/ and will be skipped. If you do not
+have coresight support in hardware then either do not build perf with
+coresight support or remove these binaries in order to not have these
+tests fail and have them skip instead.
+
+These tests will log historical results in the current working
+directory (e.g. tools/perf) and will be named stats-*.csv like:
+
+ stats-asm_pure_loop-out.csv
+ stats-bubble_sort-random.csv
+ ...
+
+These statistic files log some aspects of the AUX data sections in
+the perf data output counting some numbers of certain encodings (a
+good way to know that it's working in a very simple way). One problem
+with coresight is that given a large enough amount of data needing to
+be logged, some of it can be lost due to the processor not waking up
+in time to read out all the data from buffers etc.. You will notice
+that the amount of data collected can vary a lot per run of perf test.
+If you wish to see how this changes over time, simply run perf test
+multiple times and all these csv files will have more and more data
+appended to it that you can later examine, graph and otherwise use to
+figure out if things have become worse or better.
+
+Be aware that amny of these tests take quite a while to run, specifically
+in processing the perf data file and dumping contents to then examine what
+is inside.
+
+You can change where these csv logs are stored by setting the
+PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
+test like:
+
+ export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
+ perf test
+
+They will also store resulting perf output data in the current
+directory for later inspection like:
+
+ perf-memcpy-1m.data
+ perf-thread_loop-2th.data
+ ...
+
+You can alter where the perf data files are stored by setting the
+PERF_TEST_CORESIGHT_DATADIR environment variable such as:
+
+ PERF_TEST_CORESIGHT_DATADIR=/var/tmp
+ perf test
+
+You may wish to set these above environment variables if you which to
+keep the output of tests outside of the current working directory for
+longer term storage and examination.
--
2.32.0


2021-12-16 10:22:26

by Daniel Thompson

[permalink] [raw]
Subject: Re: [PATCH 02/12] perf test: Shell - only run .sh shell files to skip other files

On Wed, Dec 15, 2021 at 04:03:53PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> You edit your scripts in the tests and end up with your usual shell
> backup files with ~ or .bak or something else at the end, but then your
> next perf test run wants to run the backups too. You might also have perf
> .data files in the directory or something else undesireable as well. You end
> up chasing which test is the one you edited and the backup and have to keep
> removing all the backup files, so automatically skip any files that are
> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>
> Signed-off-by: Carsten Haitzler <[email protected]>

Why require both executable *and* endswith('.sh')?


> ---
> tools/perf/tests/builtin-test.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index ece272b55587..849737ead9fd 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -297,7 +297,20 @@ static const char *shell_test__description(char *description, size_t size,
> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> if (!is_directory(base, ent) && \
> is_executable_file(base, ent) && \
> - ent->d_name[0] != '.')
> + ent->d_name[0] != '.' && \
> + (shell_file_is_sh(ent->d_name) == 0))
> +
> +static int shell_file_is_sh(const char *file)
> +{
> + const char *ext;
> +
> + ext = strchr(file, '.');

Shouldn't this be strrchr()?


Daniel.

2021-12-16 19:45:46

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 02/12] perf test: Shell - only run .sh shell files to skip other files



On 12/16/21 10:22, Daniel Thompson wrote:
> On Wed, Dec 15, 2021 at 04:03:53PM +0000, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> You edit your scripts in the tests and end up with your usual shell
>> backup files with ~ or .bak or something else at the end, but then your
>> next perf test run wants to run the backups too. You might also have perf
>> .data files in the directory or something else undesireable as well. You end
>> up chasing which test is the one you edited and the backup and have to keep
>> removing all the backup files, so automatically skip any files that are
>> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>
> Why require both executable *and* endswith('.sh')?

Paranoia. :) Making sure we really only run things that are meant to be
run and avoid other junk/tmp/whatever files.

>> ---
>> tools/perf/tests/builtin-test.c | 15 ++++++++++++++-
>> 1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
>> index ece272b55587..849737ead9fd 100644
>> --- a/tools/perf/tests/builtin-test.c
>> +++ b/tools/perf/tests/builtin-test.c
>> @@ -297,7 +297,20 @@ static const char *shell_test__description(char *description, size_t size,
>> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
>> if (!is_directory(base, ent) && \
>> is_executable_file(base, ent) && \
>> - ent->d_name[0] != '.')
>> + ent->d_name[0] != '.' && \
>> + (shell_file_is_sh(ent->d_name) == 0))
>> +
>> +static int shell_file_is_sh(const char *file)
>> +{
>> + const char *ext;
>> +
>> + ext = strchr(file, '.');
>
> Shouldn't this be strrchr()?

Oh indeed probably should be. My bad. Nothing uses a dot inside the
filename yet. I can fix that - will wait for the rest to come in before
doing an update

2021-12-17 14:55:58

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH 01/12] perf test: Shell - Limit to only run executable scripts in tests

On 15/12/2021 16:03, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> Perf test's shell runner will just run everything in the tests
> directory (as long as it's not another directory or does not begin
> with a dot), but sometimes you find files in there that are not shell
> scripts - perf.data output for example if you do some testing and then
> the next time you run perf test it tries to run these. Check the files
> are executable so they are actually intended to be test scripts and
> not just some "random junk" files there.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> tools/perf/tests/builtin-test.c | 4 +++-
> tools/perf/util/path.c | 12 ++++++++++++
> tools/perf/util/path.h | 1 +
> 3 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index 8cb5a1c3489e..ece272b55587 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -295,7 +295,9 @@ static const char *shell_test__description(char *description, size_t size,
>
> #define for_each_shell_test(entlist, nr, base, ent) \
> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> - if (!is_directory(base, ent) && ent->d_name[0] != '.')
> + if (!is_directory(base, ent) && \
> + is_executable_file(base, ent) && \
> + ent->d_name[0] != '.')

If we reorder the checks, we could potentially avoid a few
syscalls for hidden items. i.e., if we do ent->d_name[0] != '.'
first.

>
> static const char *shell_tests__dir(char *path, size_t size)
> {
> diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
> index caed0336429f..7dde8c230ae8 100644
> --- a/tools/perf/util/path.c
> +++ b/tools/perf/util/path.c
> @@ -92,3 +92,15 @@ bool is_directory(const char *base_path, const struct dirent *dent)
>
> return S_ISDIR(st.st_mode);
> }
> +
> +bool is_executable_file(const char *base_path, const struct dirent *dent)
> +{
> + char path[PATH_MAX];
> + struct stat st;
> +
> + sprintf(path, "%s/%s", base_path, dent->d_name);

Should this be snprintf() for additional safety ?

> + if (stat(path, &st))
> + return false;
> +
> + return !S_ISDIR(st.st_mode) && (st.st_mode & S_IXUSR);

Otherwise looks good to me.

Suzuki

2021-12-17 15:00:24

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH 02/12] perf test: Shell - only run .sh shell files to skip other files

On 15/12/2021 16:03, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> You edit your scripts in the tests and end up with your usual shell
> backup files with ~ or .bak or something else at the end, but then your
> next perf test run wants to run the backups too. You might also have perf
> .data files in the directory or something else undesireable as well. You end
> up chasing which test is the one you edited and the backup and have to keep
> removing all the backup files, so automatically skip any files that are
> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> tools/perf/tests/builtin-test.c | 15 ++++++++++++++-
> 1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index ece272b55587..849737ead9fd 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -297,7 +297,20 @@ static const char *shell_test__description(char *description, size_t size,
> for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++) \
> if (!is_directory(base, ent) && \
> is_executable_file(base, ent) && \
> - ent->d_name[0] != '.')
> + ent->d_name[0] != '.' && \
> + (shell_file_is_sh(ent->d_name) == 0))
> +
> +static int shell_file_is_sh(const char *file)

nit: In line with the other "helpers", could this be:

is_shell_file_sh() or even is_shell_script() ?

Also, for consistency, could this be bool, like the other helpers ?

i.e., returns true when the condition matches ?

Suzuki

> +{
> + const char *ext;
> +
> + ext = strchr(file, '.');
> + if (!ext)
> + return -1;
> + if (!strcmp(ext, ".sh"))
> + return 0;
> + return -1;
> +}


>
> static const char *shell_tests__dir(char *path, size_t size)
> {


2021-12-17 17:18:54

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 01/12] perf test: Shell - Limit to only run executable scripts in tests



On 12/17/21 14:55, Suzuki K Poulose wrote:
> On 15/12/2021 16:03, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> Perf test's shell runner will just run everything in the tests
>> directory (as long as it's not another directory or does not begin
>> with a dot), but sometimes you find files in there that are not shell
>> scripts - perf.data output for example if you do some testing and then
>> the next time you run perf test it tries to run these. Check the files
>> are executable so they are actually intended to be test scripts and
>> not just some "random junk" files there.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>> ---
>>   tools/perf/tests/builtin-test.c |  4 +++-
>>   tools/perf/util/path.c          | 12 ++++++++++++
>>   tools/perf/util/path.h          |  1 +
>>   3 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/tests/builtin-test.c
>> b/tools/perf/tests/builtin-test.c
>> index 8cb5a1c3489e..ece272b55587 100644
>> --- a/tools/perf/tests/builtin-test.c
>> +++ b/tools/perf/tests/builtin-test.c
>> @@ -295,7 +295,9 @@ static const char *shell_test__description(char
>> *description, size_t size,
>>   #define for_each_shell_test(entlist, nr, base,
>> ent)                    \
>>       for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++)    \
>> -        if (!is_directory(base, ent) && ent->d_name[0] != '.')
>> +        if (!is_directory(base, ent) && \
>> +            is_executable_file(base, ent) && \
>> +            ent->d_name[0] != '.')
>
> If we reorder the checks, we could potentially avoid a few
> syscalls for hidden items. i.e., if we do ent->d_name[0] != '.'
> first.

Could do that, thought this certainly is not a performance critical path
and the code certainly shows that and doesn't care - can fix that too.

>>   static const char *shell_tests__dir(char *path, size_t size)
>>   {
>> diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
>> index caed0336429f..7dde8c230ae8 100644
>> --- a/tools/perf/util/path.c
>> +++ b/tools/perf/util/path.c
>> @@ -92,3 +92,15 @@ bool is_directory(const char *base_path, const
>> struct dirent *dent)
>>       return S_ISDIR(st.st_mode);
>>   }
>> +
>> +bool is_executable_file(const char *base_path, const struct dirent
>> *dent)
>> +{
>> +    char path[PATH_MAX];
>> +    struct stat st;
>> +
>> +    sprintf(path, "%s/%s", base_path, dent->d_name);
>
> Should this be snprintf() for additional safety ?

Ylou're right - I was just following the existing pattern int he code
right above in is_directory() that uses sprintf :) I can fix both.

>> +    if (stat(path, &st))
>> +        return false;
>> +
>> +    return !S_ISDIR(st.st_mode) && (st.st_mode & S_IXUSR);
>
> Otherwise looks good to me.
>
> Suzuki

2021-12-17 17:23:00

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 02/12] perf test: Shell - only run .sh shell files to skip other files



On 12/17/21 15:00, Suzuki K Poulose wrote:
> On 15/12/2021 16:03, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> You edit your scripts in the tests and end up with your usual shell
>> backup files with ~ or .bak or something else at the end, but then your
>> next perf test run wants to run the backups too. You might also have perf
>> .data files in the directory or something else undesireable as well.
>> You end
>> up chasing which test is the one you edited and the backup and have to
>> keep
>> removing all the backup files, so automatically skip any files that are
>> not plain *.sh scripts to limit the time wasted in chasing ghosts.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>> ---
>>   tools/perf/tests/builtin-test.c | 15 ++++++++++++++-
>>   1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/perf/tests/builtin-test.c
>> b/tools/perf/tests/builtin-test.c
>> index ece272b55587..849737ead9fd 100644
>> --- a/tools/perf/tests/builtin-test.c
>> +++ b/tools/perf/tests/builtin-test.c
>> @@ -297,7 +297,20 @@ static const char *shell_test__description(char
>> *description, size_t size,
>>       for (int __i = 0; __i < nr && (ent = entlist[__i]); __i++)    \
>>           if (!is_directory(base, ent) && \
>>               is_executable_file(base, ent) && \
>> -            ent->d_name[0] != '.')
>> +            ent->d_name[0] != '.' && \
>> +            (shell_file_is_sh(ent->d_name) == 0))
>> +
>> +static int shell_file_is_sh(const char *file)
>
> nit: In line with the other "helpers", could this be:
>
> is_shell_file_sh() or even is_shell_script() ?
>
> Also, for consistency, could this be bool, like the other helpers ?
>
> i.e., returns true when the condition matches ?
>
> Suzuki

Sure - I was going for the other pattern where 0 ==
true/matches/succeeds pattern but can use the bool one and give it a
slight rename.

>> +{
>> +    const char *ext;
>> +
>> +    ext = strchr(file, '.');
>> +    if (!ext)
>> +        return -1;
>> +    if (!strcmp(ext, ".sh"))
>> +        return 0;
>> +    return -1;
>> +}
>
>
>>   static const char *shell_tests__dir(char *path, size_t size)
>>   {
>

2021-12-21 12:35:49

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 03/12] perf test: Use 3 digits for test numbering now we can have more tests

On Wed, Dec 15, 2021 at 04:03:54PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This is in preparation for adding more tests that will need the test
> number to be 3 digts so they align nicely in the output.
>
> Signed-off-by: Carsten Haitzler <[email protected]>

Reviewed-by: Leo Yan <[email protected]>

> ---
> tools/perf/tests/builtin-test.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> index 849737ead9fd..8652dcc4912c 100644
> --- a/tools/perf/tests/builtin-test.c
> +++ b/tools/perf/tests/builtin-test.c
> @@ -435,7 +435,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width,
> continue;
>
> st.file = ent->d_name;
> - pr_info("%2d: %-*s:", i, width, test_suite.desc);
> + pr_info("%3d: %-*s:", i, width, test_suite.desc);
>
> if (intlist__find(skiplist, i)) {
> color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
> @@ -485,7 +485,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
> continue;
> }
>
> - pr_info("%2d: %-*s:", i, width, test_description(t, -1));
> + pr_info("%3d: %-*s:", i, width, test_description(t, -1));
>
> if (intlist__find(skiplist, i)) {
> color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
> @@ -525,7 +525,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
> curr, argc, argv))
> continue;
>
> - pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
> + pr_info("%3d.%1d: %-*s:", i, subi + 1, subw,
> test_description(t, subi));
> test_and_print(t, subi);
> }
> @@ -560,7 +560,7 @@ static int perf_test__list_shell(int argc, const char **argv, int i)
> if (!perf_test__matches(t.desc, curr, argc, argv))
> continue;
>
> - pr_info("%2d: %s\n", i, t.desc);
> + pr_info("%3d: %s\n", i, t.desc);
>
> }
>
> @@ -582,14 +582,14 @@ static int perf_test__list(int argc, const char **argv)
> if (!perf_test__matches(test_description(t, -1), curr, argc, argv))
> continue;
>
> - pr_info("%2d: %s\n", i, test_description(t, -1));
> + pr_info("%3d: %s\n", i, test_description(t, -1));
>
> if (has_subtests(t)) {
> int subn = num_subtests(t);
> int subi;
>
> for (subi = 0; subi < subn; subi++)
> - pr_info("%2d:%1d: %s\n", i, subi + 1,
> + pr_info("%3d:%1d: %s\n", i, subi + 1,
> test_description(t, subi));
> }
> }
> --
> 2.32.0
>

2021-12-21 15:03:59

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight

Hi Carsten,

On Wed, Dec 15, 2021 at 04:03:55PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This adds the initial test harness to run perf record and examine the
> resuling output when coresight is enabled on arm64 and check the
> resulting quality of the output as part of perf test.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> MAINTAINERS | 3 +
> tools/perf/Makefile.perf | 14 +-
> .../tests/shell/coresight_asm_pure_loop.sh | 18 +++
> tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
> tools/perf/tests/shell/tools/Makefile | 26 ++++
> .../perf/tests/shell/tools/coresight/Makefile | 27 ++++
> .../shell/tools/coresight/Makefile.miniconfig | 23 ++++
> .../tools/coresight/asm_pure_loop/Makefile | 30 ++++
> .../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
> 9 files changed, 297 insertions(+), 2 deletions(-)
> create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
> create mode 100644 tools/perf/tests/shell/lib/coresight.sh
> create mode 100644 tools/perf/tests/shell/tools/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S

The folder naming is okay for me, but it is cyclic with the format:
"tools/.../tools/". So I am wandering if below two pathes are better?

tools/perf/tests/shell/prog/coresight/
or
tools/perf/tests/shell/coresight/

I'd like to leave this question for Arnaldo / Jiri for the folder
layout.

> diff --git a/MAINTAINERS b/MAINTAINERS
> index 13f9a84a617e..d46e8469c467 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
> F: tools/perf/arch/arm/util/cs-etm.c
> F: tools/perf/arch/arm/util/cs-etm.h
> F: tools/perf/arch/arm/util/pmu.c
> +F: tools/perf/tests/shell/coresight_*
> +F: tools/perf/tests/shell/tools/Makefile
> +F: tools/perf/tests/shell/tools/coresight/*
> F: tools/perf/util/cs-etm-decoder/*
> F: tools/perf/util/cs-etm.*
>
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 80522bcfafe0..26467a2c71f4 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
> $(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
> $(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@
>
> -all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
> +TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
> +
> +tests-tools-targets: FORCE
> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
> +
> +tests-tools-targets-clean:
> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
> +
> +all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets
>
> # Create python binding output directory if not already present
> _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
> @@ -1020,6 +1028,7 @@ install-tests: all install-gtk
> $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
> $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
> + $(Q)$(MAKE) -C tests/shell/tools install-tests
>
> install-bin: install-tools install-tests install-traceevent-plugins
>
> @@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
> bpf-skel-clean:
> $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
>
> -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
> +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
> $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
> $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
> $(Q)$(RM) $(OUTPUT).config-detected
> @@ -1155,5 +1164,6 @@ FORCE:
> .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
> .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
> .PHONY: libtraceevent_plugins archheaders
> +.PHONY: $(TESTS_TOOLS_TARGETS)
>
> endif # force_fixdep
> diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> new file mode 100755
> index 000000000000..542d4a37e349
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / ASM Pure Loop
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="asm_pure_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS=""
> +DATV="out"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS

Is $ARGS redundant and can be removed?

> +perf_dump_aux_verify "$DATA" 2601 334 334

These three magic numbers "2601 334 334" would be hard to understand.
One way is the code can dynamically calculate these values based on the
loop times (the loop is is predefined in asm_pure_loop.S), or it's
good to give explanation in comments for these values.

> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
> new file mode 100644
> index 000000000000..cd6c1283e6f5
> --- /dev/null
> +++ b/tools/perf/tests/shell/lib/coresight.sh
> @@ -0,0 +1,130 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +# This is sourced from a driver script so no need for #!/bin... etc. at the
> +# top - the assumption below is that it runs as part of sourcing after the
> +# test sets up some basic env vars to say what it is.
> +
> +# perf record options for the perf tests to use
> +PERFRECMEM="-m ,128M"

We must use 128Mb for the AUX trace buffer? The big buffer size is
not friendly for embedded system.

> +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
> +
> +# These tests need to be run as root or coresight won't allow large buffers
> +# and will not collect proper data
> +UID=`id -u`
> +if test "$UID" -ne 0; then
> + echo "Not running as root... skip"
> + exit 2
> +fi
> +
> +TOOLS=$(dirname $0)/tools
> +DIR="$TOOLS/coresight/$TEST"
> +BIN="$DIR/$TEST"
> +# If the test tool/binary does not exist and is executable then skip the test
> +if ! test -x "$BIN"; then exit 2; fi
> +DATD="."

It's blur to set DATD and STATD to ".". If the user doesn't specify
the envs, it's not clear it will point to which folder.

> +# If the data dir env is set then make the data dir use that instead of ./
> +if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
> + DATD="$PERF_TEST_CORESIGHT_DATADIR";
> +fi
> +# If the stat dir env is set then make the data dir use that instead of ./
> +STATD="."
> +if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
> + STATD="$PERF_TEST_CORESIGHT_STATDIR";
> +fi
> +
> +# Called if the test fails - error code 2
> +err() {
> + echo "$1"
> + exit 1
> +}
> +
> +# Check that some statistics from our perf
> +check_val_min() {
> + STATF="$4"
> + if test "$2" -lt "$3"; then
> + echo ", FAILED" >> "$STATF"
> + err "Sanity check number of $1 is too low ($2 < $3)"
> + fi
> +}
> +
> +perf_dump_aux_verify() {
> + # Some basic checking that the AUX chunk contains some sensible data
> + # to see that we are recording something and at least a minimum
> + # amount of it. We should almost always see F3 atoms in just about
> + # anything but certainly we will see some trace info and async atom
> + # chunks.
> + DUMP="$DATD/perf-tmp-aux-dump.txt"
> + perf report --stdio --dump -i "$1" | \
> + grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
> + # Simply count how many of these atoms we find to see that we are
> + # producing a reasonable amount of data - exact checks are not sane
> + # as this is a lossy process where we may lose some blocks and the
> + # compiler may produce different code depending on the compiler and
> + # optimization options, so this is rough just to see if we're
> + # either missing almost all the data or all of it
> + ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
> + ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
> + ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
> + rm -f "$DUMP"
> +
> + # Arguments provide minimums for a pass
> + CHECK_F3_MIN="$2"
> + CHECK_ASYNC_MIN="$3"
> + CHECK_TRACE_INFO_MIN="$4"
> +
> + # Write out statistics, so over time you can track results to see if
> + # there is a pattern - for example we have less "noisy" results that
> + # produce more consistent amounts of data each run, to see if over
> + # time any techinques to minimize data loss are having an effect or
> + # not
> + STATF="$STATD/stats-$TEST-$DATV.csv"
> + if ! test -f "$STATF"; then
> + echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
> + fi
> + echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
> +
> + # Actually check to see if we passed or failed.
> + check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
> + check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
> + check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
> + echo ", Ok" >> "$STATF"
> +}
> +
> +perf_dump_aux_tid_verify() {

This function is not used in the test contained in this patch.

> + # Specifically crafted test will produce a list of Tread ID's to
> + # stdout that need to be checked to see that they have had trace
> + # info collected in AUX blocks in the perf data. This will go
> + # through all the TID's that are listed as CID=0xabcdef and see
> + # that all the Thread IDs the test tool reports are in the perf
> + # data AUX chunks
> +
> + # The TID test tools will print a TID per stdout line that are being
> + # tested
> + TIDS=`cat "$2"`
> + # Scan the perf report to find the TIDs that are actually CID in hex
> + # and build a list of the ones found
> + FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
> + grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
> + uniq | sort | uniq`
> +
> + # Iterate over the list of TIDs that the test says it has and find
> + # them in the TIDs found in the perf report
> + MISSING=""
> + for TID2 in $TIDS; do
> + FOUND=""
> + for TIDHEX in $FOUND_TIDS; do
> + TID=`printf "%i" $TIDHEX`
> + if test "$TID" -eq "$TID2"; then
> + FOUND="y"
> + break
> + fi
> + done
> + if test -z "$FOUND"; then
> + MISSING="$MISSING $TID"
> + fi
> + done
> + if test -n "$MISSING"; then
> + err "Thread IDs $MISSING not found in perf AUX data"
> + fi
> +}
> diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
> new file mode 100644
> index 000000000000..c7ada20922fd
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/Makefile
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../../../../../tools/scripts/Makefile.include
> +include ../../../../../tools/scripts/Makefile.arch
> +include ../../../../../tools/scripts/utilities.mak

To be honest, I don't understand well for perf's build and config
system. Seems to me, a good example for building program is jevents.

Please take a look for the code:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Makefile.perf#n667

If follow the same method with jevents for building test programs,
I can see one benefit is we don't need to create a Makefile, on the
other hand, we can reuse the perf's build system and simply create a
Build file under the folder tools/perf/tests/shell/.../coresight/.

> +
> +SUBDIRS = \
> + coresight
> +
> +all: $(SUBDIRS)
> +$(SUBDIRS):
> + $(Q)$(MAKE) -C $@
> +
> +INSTALLDIRS = $(SUBDIRS:%=install-%)
> +
> +install-tests: all $(INSTALLDIRS)
> +$(INSTALLDIRS):
> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> +
> +CLEANDIRS = $(SUBDIRS:%=clean-%)
> +
> +clean: $(CLEANDIRS)
> +$(CLEANDIRS):
> + $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
> +
> +.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> new file mode 100644
> index 000000000000..723006ea827c
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../../../../../../tools/scripts/Makefile.include
> +include ../../../../../../tools/scripts/Makefile.arch
> +include ../../../../../../tools/scripts/utilities.mak
> +
> +SUBDIRS = \
> + asm_pure_loop
> +
> +all: $(SUBDIRS)
> +$(SUBDIRS):
> + $(Q)$(MAKE) -C $@
> +
> +INSTALLDIRS = $(SUBDIRS:%=install-%)
> +
> +install-tests: $(INSTALLDIRS)
> +$(INSTALLDIRS):
> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> +
> +CLEANDIRS = $(SUBDIRS:%=clean-%)
> +
> +clean: $(CLEANDIRS)
> +$(CLEANDIRS):
> + $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
> +
> +.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> +
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> new file mode 100644
> index 000000000000..cedd26c6a0eb
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> @@ -0,0 +1,23 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +ifndef DESTDIR
> +prefix ?= $(HOME)
> +endif
> +
> +DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
> +perfexecdir = libexec/perf-core
> +perfexec_instdir = $(perfexecdir)
> +
> +ifneq ($(filter /%,$(firstword $(perfexecdir))),)
> +perfexec_instdir = $(perfexecdir)
> +else
> +perfexec_instdir = $(prefix)/$(perfexecdir)
> +endif
> +
> +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
> +INSTALL = install
> +
> +include ../../../../../../scripts/Makefile.include
> +include ../../../../../../scripts/Makefile.arch
> +include ../../../../../../scripts/utilities.mak

As suggested above, if we refer the building method of jevent, I think
this Makefile.miniconfig is not needed anymore.

> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> new file mode 100644
> index 000000000000..10c5a60cb71c
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> @@ -0,0 +1,30 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +include ../Makefile.miniconfig
> +
> +BIN=asm_pure_loop
> +LIB=
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).S
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> new file mode 100644
> index 000000000000..262876451021
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Tamas Zsoldos <[email protected]>, 2021 */
> +
> +.globl _start
> +_start:
> + mov x0, 0x000fffff
> + mov x1, xzr
> +loop:
> + nop
> + nop
> + cbnz x1, noskip
> + nop
> + nop
> + adrp x2, skip
> + add x2, x2, :lo12:skip
> + br x2
> + nop
> + nop
> +noskip:
> + nop
> + nop
> +skip:
> + sub x0, x0, 1
> + cbnz x0, loop
> +
> + mov x0, #0
> + mov x8, #93 // __NR_exit syscall
> + svc #0

I verified this code on Arm64 machine and it works!

I am a bit worry about the code for using the hard code number for
system call. Another option is to use the inline assembly
in C code, I think you have considered for this approach, this might
introduce noise for extra branch instructions during the testing,
but it can allow us to program standard C program (and don't worry
about the program exiting).

If you think using assembly code is better than inline assembly, it
would be fine for me. Eventually, the system call number is very
seldomly to be changed.

Thanks,
Leo

2021-12-21 20:40:20

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight

Em Tue, Dec 21, 2021 at 11:03:49PM +0800, Leo Yan escreveu:
> Hi Carsten,
>
> On Wed, Dec 15, 2021 at 04:03:55PM +0000, [email protected] wrote:
> > From: Carsten Haitzler <[email protected]>
> >
> > This adds the initial test harness to run perf record and examine the
> > resuling output when coresight is enabled on arm64 and check the
> > resulting quality of the output as part of perf test.
> >
> > Signed-off-by: Carsten Haitzler <[email protected]>
> > ---
> > MAINTAINERS | 3 +
> > tools/perf/Makefile.perf | 14 +-
> > .../tests/shell/coresight_asm_pure_loop.sh | 18 +++
> > tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
> > tools/perf/tests/shell/tools/Makefile | 26 ++++
> > .../perf/tests/shell/tools/coresight/Makefile | 27 ++++
> > .../shell/tools/coresight/Makefile.miniconfig | 23 ++++
> > .../tools/coresight/asm_pure_loop/Makefile | 30 ++++
> > .../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
> > 9 files changed, 297 insertions(+), 2 deletions(-)
> > create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
> > create mode 100644 tools/perf/tests/shell/lib/coresight.sh
> > create mode 100644 tools/perf/tests/shell/tools/Makefile
> > create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
> > create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> > create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> > create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>
> The folder naming is okay for me, but it is cyclic with the format:
> "tools/.../tools/". So I am wandering if below two pathes are better?
>
> tools/perf/tests/shell/prog/coresight/
> or
> tools/perf/tests/shell/coresight/

The later, its descriptive enough, I think, and the shortest variant so
far.

- Arnaldo

> I'd like to leave this question for Arnaldo / Jiri for the folder
> layout.
>
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 13f9a84a617e..d46e8469c467 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
> > F: tools/perf/arch/arm/util/cs-etm.c
> > F: tools/perf/arch/arm/util/cs-etm.h
> > F: tools/perf/arch/arm/util/pmu.c
> > +F: tools/perf/tests/shell/coresight_*
> > +F: tools/perf/tests/shell/tools/Makefile
> > +F: tools/perf/tests/shell/tools/coresight/*
> > F: tools/perf/util/cs-etm-decoder/*
> > F: tools/perf/util/cs-etm.*
> >
> > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> > index 80522bcfafe0..26467a2c71f4 100644
> > --- a/tools/perf/Makefile.perf
> > +++ b/tools/perf/Makefile.perf
> > @@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
> > $(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
> > $(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@
> >
> > -all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
> > +TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
> > +
> > +tests-tools-targets: FORCE
> > + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
> > +
> > +tests-tools-targets-clean:
> > + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
> > +
> > +all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets
> >
> > # Create python binding output directory if not already present
> > _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
> > @@ -1020,6 +1028,7 @@ install-tests: all install-gtk
> > $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
> > $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
> > $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
> > + $(Q)$(MAKE) -C tests/shell/tools install-tests
> >
> > install-bin: install-tools install-tests install-traceevent-plugins
> >
> > @@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
> > bpf-skel-clean:
> > $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
> >
> > -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
> > +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
> > $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
> > $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
> > $(Q)$(RM) $(OUTPUT).config-detected
> > @@ -1155,5 +1164,6 @@ FORCE:
> > .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
> > .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
> > .PHONY: libtraceevent_plugins archheaders
> > +.PHONY: $(TESTS_TOOLS_TARGETS)
> >
> > endif # force_fixdep
> > diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> > new file mode 100755
> > index 000000000000..542d4a37e349
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> > @@ -0,0 +1,18 @@
> > +#!/bin/sh -e
> > +# Coresight / ASM Pure Loop
> > +
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Carsten Haitzler <[email protected]>, 2021
> > +
> > +TEST="asm_pure_loop"
> > +. $(dirname $0)/lib/coresight.sh
> > +ARGS=""
> > +DATV="out"
> > +DATA="$DATD/perf-$TEST-$DATV.data"
> > +
> > +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
>
> Is $ARGS redundant and can be removed?
>
> > +perf_dump_aux_verify "$DATA" 2601 334 334
>
> These three magic numbers "2601 334 334" would be hard to understand.
> One way is the code can dynamically calculate these values based on the
> loop times (the loop is is predefined in asm_pure_loop.S), or it's
> good to give explanation in comments for these values.
>
> > +
> > +err=$?
> > +exit $err
> > diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
> > new file mode 100644
> > index 000000000000..cd6c1283e6f5
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/lib/coresight.sh
> > @@ -0,0 +1,130 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Carsten Haitzler <[email protected]>, 2021
> > +
> > +# This is sourced from a driver script so no need for #!/bin... etc. at the
> > +# top - the assumption below is that it runs as part of sourcing after the
> > +# test sets up some basic env vars to say what it is.
> > +
> > +# perf record options for the perf tests to use
> > +PERFRECMEM="-m ,128M"
>
> We must use 128Mb for the AUX trace buffer? The big buffer size is
> not friendly for embedded system.
>
> > +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
> > +
> > +# These tests need to be run as root or coresight won't allow large buffers
> > +# and will not collect proper data
> > +UID=`id -u`
> > +if test "$UID" -ne 0; then
> > + echo "Not running as root... skip"
> > + exit 2
> > +fi
> > +
> > +TOOLS=$(dirname $0)/tools
> > +DIR="$TOOLS/coresight/$TEST"
> > +BIN="$DIR/$TEST"
> > +# If the test tool/binary does not exist and is executable then skip the test
> > +if ! test -x "$BIN"; then exit 2; fi
> > +DATD="."
>
> It's blur to set DATD and STATD to ".". If the user doesn't specify
> the envs, it's not clear it will point to which folder.
>
> > +# If the data dir env is set then make the data dir use that instead of ./
> > +if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
> > + DATD="$PERF_TEST_CORESIGHT_DATADIR";
> > +fi
> > +# If the stat dir env is set then make the data dir use that instead of ./
> > +STATD="."
> > +if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
> > + STATD="$PERF_TEST_CORESIGHT_STATDIR";
> > +fi
> > +
> > +# Called if the test fails - error code 2
> > +err() {
> > + echo "$1"
> > + exit 1
> > +}
> > +
> > +# Check that some statistics from our perf
> > +check_val_min() {
> > + STATF="$4"
> > + if test "$2" -lt "$3"; then
> > + echo ", FAILED" >> "$STATF"
> > + err "Sanity check number of $1 is too low ($2 < $3)"
> > + fi
> > +}
> > +
> > +perf_dump_aux_verify() {
> > + # Some basic checking that the AUX chunk contains some sensible data
> > + # to see that we are recording something and at least a minimum
> > + # amount of it. We should almost always see F3 atoms in just about
> > + # anything but certainly we will see some trace info and async atom
> > + # chunks.
> > + DUMP="$DATD/perf-tmp-aux-dump.txt"
> > + perf report --stdio --dump -i "$1" | \
> > + grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
> > + # Simply count how many of these atoms we find to see that we are
> > + # producing a reasonable amount of data - exact checks are not sane
> > + # as this is a lossy process where we may lose some blocks and the
> > + # compiler may produce different code depending on the compiler and
> > + # optimization options, so this is rough just to see if we're
> > + # either missing almost all the data or all of it
> > + ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
> > + ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
> > + ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
> > + rm -f "$DUMP"
> > +
> > + # Arguments provide minimums for a pass
> > + CHECK_F3_MIN="$2"
> > + CHECK_ASYNC_MIN="$3"
> > + CHECK_TRACE_INFO_MIN="$4"
> > +
> > + # Write out statistics, so over time you can track results to see if
> > + # there is a pattern - for example we have less "noisy" results that
> > + # produce more consistent amounts of data each run, to see if over
> > + # time any techinques to minimize data loss are having an effect or
> > + # not
> > + STATF="$STATD/stats-$TEST-$DATV.csv"
> > + if ! test -f "$STATF"; then
> > + echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
> > + fi
> > + echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
> > +
> > + # Actually check to see if we passed or failed.
> > + check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
> > + check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
> > + check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
> > + echo ", Ok" >> "$STATF"
> > +}
> > +
> > +perf_dump_aux_tid_verify() {
>
> This function is not used in the test contained in this patch.
>
> > + # Specifically crafted test will produce a list of Tread ID's to
> > + # stdout that need to be checked to see that they have had trace
> > + # info collected in AUX blocks in the perf data. This will go
> > + # through all the TID's that are listed as CID=0xabcdef and see
> > + # that all the Thread IDs the test tool reports are in the perf
> > + # data AUX chunks
> > +
> > + # The TID test tools will print a TID per stdout line that are being
> > + # tested
> > + TIDS=`cat "$2"`
> > + # Scan the perf report to find the TIDs that are actually CID in hex
> > + # and build a list of the ones found
> > + FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
> > + grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
> > + uniq | sort | uniq`
> > +
> > + # Iterate over the list of TIDs that the test says it has and find
> > + # them in the TIDs found in the perf report
> > + MISSING=""
> > + for TID2 in $TIDS; do
> > + FOUND=""
> > + for TIDHEX in $FOUND_TIDS; do
> > + TID=`printf "%i" $TIDHEX`
> > + if test "$TID" -eq "$TID2"; then
> > + FOUND="y"
> > + break
> > + fi
> > + done
> > + if test -z "$FOUND"; then
> > + MISSING="$MISSING $TID"
> > + fi
> > + done
> > + if test -n "$MISSING"; then
> > + err "Thread IDs $MISSING not found in perf AUX data"
> > + fi
> > +}
> > diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
> > new file mode 100644
> > index 000000000000..c7ada20922fd
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/tools/Makefile
> > @@ -0,0 +1,26 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +# Carsten Haitzler <[email protected]>, 2021
> > +include ../../../../../tools/scripts/Makefile.include
> > +include ../../../../../tools/scripts/Makefile.arch
> > +include ../../../../../tools/scripts/utilities.mak
>
> To be honest, I don't understand well for perf's build and config
> system. Seems to me, a good example for building program is jevents.
>
> Please take a look for the code:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Makefile.perf#n667
>
> If follow the same method with jevents for building test programs,
> I can see one benefit is we don't need to create a Makefile, on the
> other hand, we can reuse the perf's build system and simply create a
> Build file under the folder tools/perf/tests/shell/.../coresight/.
>
> > +
> > +SUBDIRS = \
> > + coresight
> > +
> > +all: $(SUBDIRS)
> > +$(SUBDIRS):
> > + $(Q)$(MAKE) -C $@
> > +
> > +INSTALLDIRS = $(SUBDIRS:%=install-%)
> > +
> > +install-tests: all $(INSTALLDIRS)
> > +$(INSTALLDIRS):
> > + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> > +
> > +CLEANDIRS = $(SUBDIRS:%=clean-%)
> > +
> > +clean: $(CLEANDIRS)
> > +$(CLEANDIRS):
> > + $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
> > +
> > +.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> > diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> > new file mode 100644
> > index 000000000000..723006ea827c
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> > @@ -0,0 +1,27 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +# Carsten Haitzler <[email protected]>, 2021
> > +include ../../../../../../tools/scripts/Makefile.include
> > +include ../../../../../../tools/scripts/Makefile.arch
> > +include ../../../../../../tools/scripts/utilities.mak
> > +
> > +SUBDIRS = \
> > + asm_pure_loop
> > +
> > +all: $(SUBDIRS)
> > +$(SUBDIRS):
> > + $(Q)$(MAKE) -C $@
> > +
> > +INSTALLDIRS = $(SUBDIRS:%=install-%)
> > +
> > +install-tests: $(INSTALLDIRS)
> > +$(INSTALLDIRS):
> > + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> > +
> > +CLEANDIRS = $(SUBDIRS:%=clean-%)
> > +
> > +clean: $(CLEANDIRS)
> > +$(CLEANDIRS):
> > + $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
> > +
> > +.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> > +
> > diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> > new file mode 100644
> > index 000000000000..cedd26c6a0eb
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> > @@ -0,0 +1,23 @@
> > +# SPDX-License-Identifier: GPL-2.0-only
> > +# Carsten Haitzler <[email protected]>, 2021
> > +
> > +ifndef DESTDIR
> > +prefix ?= $(HOME)
> > +endif
> > +
> > +DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
> > +perfexecdir = libexec/perf-core
> > +perfexec_instdir = $(perfexecdir)
> > +
> > +ifneq ($(filter /%,$(firstword $(perfexecdir))),)
> > +perfexec_instdir = $(perfexecdir)
> > +else
> > +perfexec_instdir = $(prefix)/$(perfexecdir)
> > +endif
> > +
> > +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
> > +INSTALL = install
> > +
> > +include ../../../../../../scripts/Makefile.include
> > +include ../../../../../../scripts/Makefile.arch
> > +include ../../../../../../scripts/utilities.mak
>
> As suggested above, if we refer the building method of jevent, I think
> this Makefile.miniconfig is not needed anymore.
>
> > diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> > new file mode 100644
> > index 000000000000..10c5a60cb71c
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> > @@ -0,0 +1,30 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Carsten Haitzler <[email protected]>, 2021
> > +
> > +include ../Makefile.miniconfig
> > +
> > +BIN=asm_pure_loop
> > +LIB=
> > +
> > +all: $(BIN)
> > +
> > +$(BIN): $(BIN).S
> > +ifdef CORESIGHT
> > +ifeq ($(ARCH),arm64)
> > + $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
> > +endif
> > +endif
> > +
> > +install-tests: all
> > +ifdef CORESIGHT
> > +ifeq ($(ARCH),arm64)
> > + $(call QUIET_INSTALL, tests) \
> > + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> > + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> > +endif
> > +endif
> > +
> > +clean:
> > + $(Q)$(RM) -f $(BIN)
> > +
> > +.PHONY: all clean install-tests
> > diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> > new file mode 100644
> > index 000000000000..262876451021
> > --- /dev/null
> > +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> > @@ -0,0 +1,28 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/* Tamas Zsoldos <[email protected]>, 2021 */
> > +
> > +.globl _start
> > +_start:
> > + mov x0, 0x000fffff
> > + mov x1, xzr
> > +loop:
> > + nop
> > + nop
> > + cbnz x1, noskip
> > + nop
> > + nop
> > + adrp x2, skip
> > + add x2, x2, :lo12:skip
> > + br x2
> > + nop
> > + nop
> > +noskip:
> > + nop
> > + nop
> > +skip:
> > + sub x0, x0, 1
> > + cbnz x0, loop
> > +
> > + mov x0, #0
> > + mov x8, #93 // __NR_exit syscall
> > + svc #0
>
> I verified this code on Arm64 machine and it works!
>
> I am a bit worry about the code for using the hard code number for
> system call. Another option is to use the inline assembly
> in C code, I think you have considered for this approach, this might
> introduce noise for extra branch instructions during the testing,
> but it can allow us to program standard C program (and don't worry
> about the program exiting).
>
> If you think using assembly code is better than inline assembly, it
> would be fine for me. Eventually, the system call number is very
> seldomly to be changed.
>
> Thanks,
> Leo

--

- Arnaldo

2021-12-21 20:51:40

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH 03/12] perf test: Use 3 digits for test numbering now we can have more tests

Em Tue, Dec 21, 2021 at 08:35:40PM +0800, Leo Yan escreveu:
> On Wed, Dec 15, 2021 at 04:03:54PM +0000, [email protected] wrote:
> > From: Carsten Haitzler <[email protected]>
> >
> > This is in preparation for adding more tests that will need the test
> > number to be 3 digts so they align nicely in the output.
> >
> > Signed-off-by: Carsten Haitzler <[email protected]>
>
> Reviewed-by: Leo Yan <[email protected]>

Cherry picking this one while the other issues get resolved.

Thanks, applied.

- Arnaldo

> > ---
> > tools/perf/tests/builtin-test.c | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
> > index 849737ead9fd..8652dcc4912c 100644
> > --- a/tools/perf/tests/builtin-test.c
> > +++ b/tools/perf/tests/builtin-test.c
> > @@ -435,7 +435,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width,
> > continue;
> >
> > st.file = ent->d_name;
> > - pr_info("%2d: %-*s:", i, width, test_suite.desc);
> > + pr_info("%3d: %-*s:", i, width, test_suite.desc);
> >
> > if (intlist__find(skiplist, i)) {
> > color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
> > @@ -485,7 +485,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
> > continue;
> > }
> >
> > - pr_info("%2d: %-*s:", i, width, test_description(t, -1));
> > + pr_info("%3d: %-*s:", i, width, test_description(t, -1));
> >
> > if (intlist__find(skiplist, i)) {
> > color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n");
> > @@ -525,7 +525,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
> > curr, argc, argv))
> > continue;
> >
> > - pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
> > + pr_info("%3d.%1d: %-*s:", i, subi + 1, subw,
> > test_description(t, subi));
> > test_and_print(t, subi);
> > }
> > @@ -560,7 +560,7 @@ static int perf_test__list_shell(int argc, const char **argv, int i)
> > if (!perf_test__matches(t.desc, curr, argc, argv))
> > continue;
> >
> > - pr_info("%2d: %s\n", i, t.desc);
> > + pr_info("%3d: %s\n", i, t.desc);
> >
> > }
> >
> > @@ -582,14 +582,14 @@ static int perf_test__list(int argc, const char **argv)
> > if (!perf_test__matches(test_description(t, -1), curr, argc, argv))
> > continue;
> >
> > - pr_info("%2d: %s\n", i, test_description(t, -1));
> > + pr_info("%3d: %s\n", i, test_description(t, -1));
> >
> > if (has_subtests(t)) {
> > int subn = num_subtests(t);
> > int subi;
> >
> > for (subi = 0; subi < subn; subi++)
> > - pr_info("%2d:%1d: %s\n", i, subi + 1,
> > + pr_info("%3d:%1d: %s\n", i, subi + 1,
> > test_description(t, subi));
> > }
> > }
> > --
> > 2.32.0
> >

--

- Arnaldo

2022-01-03 07:07:10

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 05/12] perf test: Add coresight test to check all threads get some data logged

On Wed, Dec 15, 2021 at 04:03:56PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This adds a test and test scripts to check that all threads in the
> target binary end up logging some kind of coresight aux data and that
> they are not missing.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> .../coresight_thread_loop_check_tid_10.sh | 19 ++++
> .../coresight_thread_loop_check_tid_2.sh | 19 ++++
> .../coresight_thread_loop_check_tid_250.sh | 19 ++++
> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
> .../tools/coresight/thread_loop/Makefile | 29 +++++++
> .../tools/coresight/thread_loop/thread_loop.c | 86 +++++++++++++++++++
> 6 files changed, 174 insertions(+), 1 deletion(-)
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
> create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
>
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
> new file mode 100755
> index 000000000000..283ad9facdee
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
> @@ -0,0 +1,19 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 10 Threads - Check TID
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="10 2000"
> +DATV="check-tid-10th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +STDO="$DATD/perf-$TEST-$DATV.stdout"
> +
> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
> +
> +perf_dump_aux_tid_verify "$DATA" "$STDO"
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
> new file mode 100755
> index 000000000000..ce8ba534bba2
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
> @@ -0,0 +1,19 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 2 Threads - Check TID
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="2 4000"
> +DATV="check-tid-2th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +STDO="$DATD/perf-$TEST-$DATV.stdout"
> +
> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
> +
> +perf_dump_aux_tid_verify "$DATA" "$STDO"
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
> new file mode 100755
> index 000000000000..cb14581c1e68
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
> @@ -0,0 +1,19 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 250 Threads - Check TID
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="250 100"
> +DATV="check-tid-250th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +STDO="$DATD/perf-$TEST-$DATV.stdout"
> +
> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
> +
> +perf_dump_aux_tid_verify "$DATA" "$STDO"
> +
> +err=$?
> +exit $err

From this case I start to understand why the lib/coresight.sh sets
AUX buffer as 250MB, setting a large buffer size can capture trace
data for all threads, especially for big amount of threads.

Seems to me, if we test on server, this case can run for short time, but
I think (sorry if I am wrong) it might take much longer time to test on
the embedded system, which might cause testing failure by two factors:

- The resource (e.g. the required big memory size) is pressure for
embedded system;
- The execution time (IIRC, every test case should be finished within
5 minutes).

Do you think does it make sense for us to only use 32 threads or 64
threads for the testing and it can give us a good testing coverage,
and we don't need to maintain multiple cases for 2/10/250 threads?

Thanks,
Leo

> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> index 723006ea827c..1edab729db76 100644
> --- a/tools/perf/tests/shell/tools/coresight/Makefile
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -5,7 +5,8 @@ include ../../../../../../tools/scripts/Makefile.arch
> include ../../../../../../tools/scripts/utilities.mak
>
> SUBDIRS = \
> - asm_pure_loop
> + asm_pure_loop \
> + thread_loop
>
> all: $(SUBDIRS)
> $(SUBDIRS):
> diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
> new file mode 100644
> index 000000000000..424df4e8b0e6
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
> @@ -0,0 +1,29 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../Makefile.miniconfig
> +
> +BIN=thread_loop
> +LIB=-pthread
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).c
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
> new file mode 100644
> index 000000000000..c0158fac7d0b
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
> @@ -0,0 +1,86 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Carsten Haitzler <[email protected]>, 2021
> +
> +// define this for gettid()
> +#define _GNU_SOURCE
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <pthread.h>
> +#include <sys/syscall.h>
> +#ifndef SYS_gettid
> +// gettid is 178 on arm64
> +# define SYS_gettid 178
> +#endif
> +#define gettid() syscall(SYS_gettid)
> +
> +struct args {
> + unsigned int loops;
> + pthread_t th;
> + void *ret;
> +};
> +
> +static void *thrfn(void *arg)
> +{
> + struct args *a = arg;
> + int i = 0, len = a->loops;
> +
> + if (getenv("SHOW_TID")) {
> + unsigned long long tid = gettid();
> +
> + printf("%llu\n", tid);
> + }
> + asm volatile(
> + "loop:\n"
> + "add %[i], %[i], #1\n"
> + "cmp %[i], %[len]\n"
> + "blt loop\n"
> + : /* out */
> + : /* in */ [i] "r" (i), [len] "r" (len)
> + : /* clobber */
> + );
> + return (void *)(long)i;
> +}
> +
> +static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
> +{
> + pthread_t t;
> + pthread_attr_t attr;
> +
> + pthread_attr_init(&attr);
> + pthread_create(&t, &attr, fn, arg);
> + return t;
> +}
> +
> +int main(int argc, char **argv)
> +{
> + unsigned int i, len, thr;
> + pthread_t threads[256];
> + struct args args[256];
> +
> + if (argc < 3) {
> + printf("ERR: %s [numthreads] [numloops (millions)]\n", argv[0]);
> + exit(1);
> + }
> +
> + thr = atoi(argv[1]);
> + if ((thr < 1) || (thr > 256)) {
> + printf("ERR: threads 1-256\n");
> + exit(1);
> + }
> + len = atoi(argv[2]);
> + if ((len < 1) || (len > 4000)) {
> + printf("ERR: max loops 4000 (millions)\n");
> + exit(1);
> + }
> + len *= 1000000;
> + for (i = 0; i < thr; i++) {
> + args[i].loops = len;
> + args[i].th = new_thr(thrfn, &(args[i]));
> + }
> + for (i = 0; i < thr; i++)
> + pthread_join(args[i].th, &(args[i].ret));
> + return 0;
> +}
> --
> 2.32.0
>

2022-01-03 08:00:47

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 07/12] perf test: Add simple bubblesort test for coresight aux data

On Wed, Dec 15, 2021 at 04:03:58PM +0000, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This adds a simple bubblesort test that sorts small and large data
> sets to see if a sufficient mount of aux data is produced.

When review this patch set, I try to classify the testing cases into
below three types, and I hope a testing is designed to verify a specific
CoreSight feature and can fall into one of these three types:

- For the waypoint testing, e.g. the test case is used to test different
branch instructions (direct or indirect branch, exception, etc);
- The config testing, we can rely on CoreSight configFS to configure
the specific CoreSight working mode, e.g. using strobing mode for
audoFDO [1];
- Verify if CoreSight driver works correctly with perf event
framework, I think essentially the test case [2] is used for this
purpose.

I know the bubble sort testing can give us more confidence to validate
the CoreSight tracing data for a complex sort algorithm, on the other
hand, bubble sort testing is essentially to test the way points.

For this reason, I think the case asm_pure_loop.S has covered the
testing for branch instructions, and if we want to cover more complete
waypoint testing, you could consider to extend asm_pure_loop.S file.

Furthermore, I expect the bubble sort is to be used for testing the
CoreSight configuration, e.g. it can be used to test for the strobing
mode (and for validation AutoFDO).

How about you think for this?

Thanks,
Leo

[1] https://www.kernel.org/doc/html/latest/trace/coresight/coresight-config.html#coresight-system-configuration-manager
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/tests/shell/test_arm_coresight.sh

> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> .../shell/coresight_bubble_sort_random.sh | 20 +
> .../shell/coresight_bubble_sort_small.sh | 20 +
> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
> .../tools/coresight/bubble_sort/Makefile | 31 +
> .../tools/coresight/bubble_sort/bubble_sort.c | 89 +
> .../coresight/bubble_sort/random_array.txt | 1855 +++++++++++++++++
> .../coresight/bubble_sort/small_array.txt | 10 +
> 7 files changed, 2027 insertions(+), 1 deletion(-)
> create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_random.sh
> create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_small.sh
> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
>
> diff --git a/tools/perf/tests/shell/coresight_bubble_sort_random.sh b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
> new file mode 100755
> index 000000000000..63567f8c4f8b
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
> @@ -0,0 +1,20 @@
> +#!/bin/sh -e
> +# Coresight / Bubblesort Random Array
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="bubble_sort"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="$DIR/random_array.txt"
> +DATV="random"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +echo $ARGS
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 4188 1630 1630
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_bubble_sort_small.sh b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
> new file mode 100755
> index 000000000000..ac86d9973fba
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
> @@ -0,0 +1,20 @@
> +#!/bin/sh -e
> +# Coresight / Bubblesort Small Array
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="bubble_sort"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="$DIR/small_array.txt"
> +DATV="small"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +echo $ARGS
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 66 6 6
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> index 1edab729db76..49fa80d28df4 100644
> --- a/tools/perf/tests/shell/tools/coresight/Makefile
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -6,7 +6,8 @@ include ../../../../../../tools/scripts/utilities.mak
>
> SUBDIRS = \
> asm_pure_loop \
> - thread_loop
> + thread_loop \
> + bubble_sort
>
> all: $(SUBDIRS)
> $(SUBDIRS):
> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
> new file mode 100644
> index 000000000000..6b82854f9f2b
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
> @@ -0,0 +1,31 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../Makefile.miniconfig
> +
> +BIN=bubble_sort
> +LIB=
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).c
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'; \
> + $(INSTALL) random_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/random_array.txt'; \
> + $(INSTALL) small_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/small_array.txt'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
> new file mode 100644
> index 000000000000..07169e03a803
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Andrea Brunato <[email protected]>, 2021
> +// Example taken from: https://gcc.gnu.org/wiki/AutoFDO/Tutorial
> +
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <assert.h>
> +
> +int count_lines(FILE *fp)
> +{
> + int lines_n = 0;
> + char c;
> +
> + for (c = getc(fp); !feof(fp); c = getc(fp)) {
> + if (c == '\n')
> + lines_n = lines_n + 1;
> + }
> + fseek(fp, 0, SEEK_SET);
> +#ifdef DEBUG
> + printf("Number of lines: %d\n", lines_n);
> +#endif
> + return lines_n;
> +}
> +
> +#ifdef DEBUG
> +void print_array(int *arr, int size)
> +{
> + int i;
> +
> + assert(arr != NULL);
> + for (i = 0; i < size; i++)
> + printf("%d\n", arr[i]);
> +}
> +#endif
> +
> +void bubble_sort(int *a, int n)
> +{
> + int i, t, s = 1;
> +
> + while (s) {
> + s = 0;
> + for (i = 1; i < n; i++) {
> + if (a[i] < a[i - 1]) {
> + t = a[i];
> + a[i] = a[i - 1];
> + a[i - 1] = t;
> + s = 1;
> + }
> + }
> + }
> +}
> +
> +void init_array(int *arr, int size, FILE *fp)
> +{
> + int i;
> +
> + for (i = 0; i < size; i++)
> + fscanf(fp, "%d", &arr[i]);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + int lines_n = 0, *arr = NULL;
> + FILE *fp;
> +
> + assert((argc == 2) && "Please specify an input file\n");
> +
> + fp = fopen(argv[1], "r");
> + assert((fp != NULL) && "ERROR: Couldn't open the specified file\n");
> +
> + // Input file expected formar: one number per line
> + lines_n = count_lines(fp);
> +
> + arr = malloc(sizeof(int) * lines_n);
> + init_array(arr, lines_n, fp);
> +
> + bubble_sort(arr, lines_n);
> +
> +#ifdef DEBUG
> + print_array(arr, lines_n);
> +#endif
> +
> + free(arr);
> + fclose(fp);
> +
> + return 0;
> +}
> +
> +
> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
> new file mode 100644
> index 000000000000..d041cfb7a649
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
> @@ -0,0 +1,1855 @@
> +11637
> +3799
> +23116
> +15091
> +13022
> +15840
> +27029
> +27563
> +25641
> +28703
> +3017
> +29923
> +26998
> +18230
> +26864
> +9139
> +28431
> +18283
> +21315
> +28167
> +7700
> +14798
> +15512
> +20470
> +9237
> +29921
> +28395
> +15057
> +29819
> +26831
> +5926
> +26653
> +390
> +2976
> +21651
> +410
> +11429
> +1828
> +3534
> +31091
> +9141
> +30892
> +29619
> +5033
> +20585
> +15413
> +28673
> +32517
> +8875
> +7509
> +22159
> +1482
> +28926
> +2748
> +25246
> +23677
> +2712
> +20332
> +23615
> +2481
> +28581
> +29728
> +13726
> +26364
> +28074
> +23534
> +12120
> +4130
> +1307
> +20009
> +15225
> +17469
> +12076
> +11899
> +22886
> +2854
> +4667
> +11494
> +25057
> +18590
> +15010
> +9295
> +6603
> +12891
> +14441
> +5499
> +26880
> +21390
> +15932
> +3975
> +11242
> +19063
> +27555
> +28538
> +30148
> +14592
> +3360
> +21049
> +24923
> +29681
> +5157
> +15595
> +8863
> +19992
> +12588
> +32711
> +3077
> +22132
> +10031
> +21685
> +1634
> +22046
> +7323
> +17925
> +20453
> +3694
> +4502
> +13543
> +1959
> +9365
> +25814
> +29540
> +30414
> +551
> +32722
> +23697
> +32501
> +9890
> +13134
> +2408
> +21814
> +1692
> +8219
> +27175
> +19880
> +1971
> +17913
> +10985
> +75
> +6275
> +29139
> +7104
> +3241
> +24809
> +13310
> +17897
> +32684
> +7199
> +2015
> +31825
> +20985
> +30466
> +25403
> +28839
> +3939
> +30171
> +9223
> +27181
> +1302
> +7945
> +18902
> +22094
> +28959
> +28100
> +1874
> +29613
> +4804
> +23941
> +31981
> +1874
> +25476
> +10176
> +2004
> +16080
> +32404
> +24472
> +14217
> +9647
> +24917
> +15001
> +15559
> +23867
> +32520
> +2545
> +2233
> +28869
> +13685
> +26640
> +6548
> +27395
> +13590
> +2851
> +1008
> +10772
> +10417
> +17257
> +19706
> +21757
> +27627
> +13514
> +4631
> +19162
> +1138
> +6325
> +22136
> +12944
> +16124
> +12359
> +25197
> +13024
> +13459
> +31896
> +4661
> +12648
> +24619
> +29975
> +2417
> +30526
> +9880
> +32733
> +19252
> +25646
> +12851
> +25535
> +22792
> +21622
> +25256
> +9785
> +11252
> +23999
> +22965
> +10221
> +32537
> +754
> +6831
> +11892
> +4420
> +12472
> +20903
> +18420
> +14968
> +17626
> +25366
> +27811
> +6781
> +15767
> +19341
> +28487
> +28252
> +1225
> +31467
> +10531
> +29736
> +12770
> +11237
> +26065
> +9298
> +9389
> +4413
> +25708
> +4222
> +206
> +1952
> +16927
> +17411
> +19671
> +23966
> +21346
> +5232
> +26240
> +11465
> +24782
> +20600
> +18201
> +4713
> +32313
> +4899
> +14371
> +11307
> +5277
> +2022
> +14443
> +14631
> +28140
> +23499
> +3955
> +7565
> +18082
> +28583
> +26049
> +11652
> +27835
> +5415
> +29742
> +8307
> +8380
> +20582
> +5376
> +28696
> +762
> +6860
> +8829
> +3579
> +2620
> +14623
> +26606
> +31027
> +8334
> +5654
> +15247
> +25230
> +8096
> +1998
> +11131
> +25257
> +31275
> +18099
> +22294
> +9458
> +17779
> +22216
> +4149
> +22198
> +172
> +23793
> +30710
> +4351
> +9939
> +13985
> +11652
> +59
> +26587
> +9059
> +26071
> +20826
> +3493
> +32165
> +10983
> +29045
> +28704
> +29635
> +19259
> +15806
> +15124
> +18009
> +20333
> +17020
> +1086
> +13690
> +32368
> +14632
> +15249
> +31064
> +18941
> +9348
> +9006
> +31486
> +4229
> +26282
> +24749
> +11214
> +12670
> +5822
> +23520
> +7971
> +28458
> +28781
> +15391
> +28848
> +1629
> +30060
> +19100
> +27055
> +6999
> +7166
> +31382
> +12066
> +15730
> +23622
> +17211
> +30853
> +15946
> +7092
> +5278
> +14151
> +29985
> +2197
> +3038
> +17757
> +14821
> +11374
> +16227
> +7657
> +29476
> +7761
> +6718
> +5380
> +3255
> +28899
> +507
> +21354
> +8942
> +21928
> +17282
> +15106
> +8035
> +17251
> +28354
> +14675
> +16033
> +23012
> +10270
> +3609
> +12387
> +4083
> +22608
> +18438
> +10363
> +31842
> +25456
> +2993
> +12567
> +12285
> +10847
> +4036
> +25889
> +2263
> +7521
> +8246
> +27332
> +6281
> +5934
> +2057
> +24322
> +22014
> +18625
> +17420
> +11120
> +4933
> +18486
> +9201
> +22355
> +20027
> +14665
> +6106
> +16764
> +1955
> +2674
> +24517
> +23913
> +20392
> +16961
> +25273
> +5622
> +29187
> +20339
> +11895
> +10335
> +9094
> +20758
> +14115
> +44
> +29610
> +29161
> +14578
> +30088
> +22551
> +9064
> +19533
> +428
> +27047
> +210
> +7836
> +24192
> +18636
> +32533
> +4747
> +1086
> +23230
> +6341
> +31606
> +8201
> +29138
> +28172
> +11305
> +1387
> +25794
> +23095
> +2600
> +1452
> +8294
> +15374
> +31146
> +18513
> +11
> +7897
> +30819
> +31
> +11752
> +32591
> +27803
> +26885
> +7667
> +31592
> +10244
> +24349
> +17836
> +25237
> +21489
> +9578
> +6322
> +5457
> +15157
> +15541
> +19222
> +12621
> +21554
> +22651
> +12729
> +10582
> +10290
> +10887
> +23746
> +26686
> +1585
> +10165
> +31947
> +19779
> +15980
> +20878
> +28201
> +26455
> +10696
> +19505
> +29741
> +1935
> +2223
> +28124
> +17789
> +24280
> +25012
> +11103
> +6445
> +10182
> +22947
> +31249
> +12870
> +25620
> +9034
> +28337
> +17508
> +12857
> +32045
> +23453
> +18922
> +29958
> +13095
> +27482
> +1809
> +13962
> +15407
> +23537
> +28052
> +24819
> +7332
> +29319
> +11951
> +7396
> +0
> +24126
> +1573
> +15203
> +1194
> +31509
> +19366
> +23180
> +21698
> +24946
> +14946
> +8384
> +30229
> +10099
> +5060
> +23938
> +12575
> +7220
> +29396
> +25422
> +22865
> +3935
> +31126
> +14275
> +9741
> +25019
> +26108
> +8997
> +29459
> +5595
> +14307
> +22680
> +13453
> +23456
> +1218
> +889
> +11412
> +22111
> +15488
> +16512
> +24954
> +25449
> +14049
> +10795
> +6430
> +7939
> +23312
> +8849
> +4246
> +3910
> +3920
> +8279
> +29146
> +23176
> +29495
> +22478
> +22801
> +15464
> +1404
> +24320
> +9644
> +24047
> +6372
> +25831
> +10546
> +25452
> +162
> +12526
> +10816
> +2805
> +12098
> +18199
> +22284
> +2588
> +632
> +23869
> +9515
> +18597
> +5439
> +11016
> +19721
> +14495
> +5671
> +3879
> +9479
> +13968
> +25634
> +12409
> +8940
> +1133
> +25751
> +6666
> +19636
> +3114
> +18339
> +27366
> +24370
> +31234
> +24247
> +27662
> +16433
> +9814
> +13447
> +20513
> +18877
> +26999
> +18659
> +27305
> +15751
> +17192
> +11982
> +31198
> +11367
> +20537
> +6868
> +9125
> +26707
> +28962
> +4645
> +22880
> +29957
> +21981
> +29763
> +10879
> +15307
> +21373
> +652
> +471
> +6426
> +15176
> +11717
> +8774
> +21421
> +22152
> +11363
> +21204
> +8266
> +30627
> +3237
> +17767
> +9548
> +31154
> +26199
> +11867
> +2590
> +508
> +5685
> +9562
> +4680
> +3527
> +21332
> +29853
> +4331
> +26626
> +5804
> +8806
> +30680
> +11836
> +2053
> +13250
> +18750
> +12811
> +3459
> +18921
> +14531
> +11448
> +4381
> +19024
> +7032
> +10599
> +19932
> +23346
> +21110
> +31736
> +5792
> +10309
> +407
> +6914
> +19374
> +11265
> +15050
> +30440
> +14511
> +16243
> +19207
> +25865
> +3421
> +8436
> +17959
> +30839
> +28976
> +22855
> +1350
> +5242
> +4582
> +19248
> +4215
> +10734
> +29691
> +1157
> +5396
> +5088
> +30686
> +24674
> +29795
> +20935
> +12005
> +1845
> +20897
> +25337
> +27343
> +27057
> +11172
> +23295
> +28899
> +2790
> +15386
> +30010
> +3736
> +22563
> +13654
> +32418
> +3320
> +9260
> +4893
> +1352
> +897
> +24116
> +27410
> +7866
> +32310
> +19354
> +2760
> +3243
> +30622
> +26854
> +1810
> +28332
> +6230
> +2049
> +10362
> +12110
> +19718
> +1304
> +17994
> +19655
> +16923
> +9017
> +17840
> +19894
> +9328
> +22423
> +11185
> +18453
> +985
> +14984
> +31486
> +2702
> +7584
> +20132
> +5354
> +22683
> +27453
> +15499
> +8065
> +9823
> +29909
> +31059
> +23496
> +32412
> +31828
> +3667
> +13160
> +5790
> +11816
> +31151
> +6194
> +16912
> +20180
> +32485
> +10858
> +28523
> +9886
> +10689
> +1200
> +26441
> +2446
> +10208
> +4201
> +649
> +19694
> +21476
> +30880
> +8900
> +9817
> +19507
> +27582
> +16013
> +27193
> +4177
> +29851
> +5791
> +22262
> +28816
> +8540
> +23328
> +26992
> +28046
> +19652
> +2195
> +2694
> +5634
> +7430
> +6356
> +25759
> +17606
> +25591
> +9758
> +17330
> +7393
> +20057
> +31341
> +24765
> +29760
> +20556
> +31406
> +24439
> +16953
> +30044
> +8448
> +19044
> +15593
> +11764
> +10639
> +10535
> +7469
> +13865
> +1039
> +11436
> +1319
> +4999
> +17500
> +13796
> +24842
> +29723
> +24282
> +27361
> +30792
> +32410
> +23984
> +1667
> +8323
> +8491
> +13317
> +388
> +9755
> +28091
> +19517
> +29286
> +23245
> +4345
> +9550
> +18217
> +31425
> +17815
> +6570
> +7935
> +6310
> +550
> +11700
> +23011
> +25532
> +6854
> +103
> +6814
> +15256
> +6215
> +122
> +32352
> +10646
> +641
> +4857
> +16185
> +26396
> +6434
> +14595
> +6690
> +29538
> +25092
> +16330
> +15523
> +5603
> +8869
> +19911
> +4792
> +12133
> +27733
> +23723
> +32383
> +1051
> +10146
> +8913
> +6907
> +4710
> +6920
> +27069
> +15176
> +17705
> +13502
> +17262
> +7841
> +12984
> +29694
> +21297
> +2230
> +10199
> +24639
> +9762
> +9313
> +5847
> +18081
> +9873
> +14930
> +5548
> +953
> +4307
> +24255
> +3720
> +22293
> +18312
> +21097
> +15784
> +60
> +4343
> +2003
> +26727
> +26292
> +24345
> +6251
> +28117
> +25523
> +15836
> +31525
> +32079
> +8277
> +31309
> +8216
> +15472
> +9717
> +10462
> +10504
> +27278
> +12602
> +13757
> +11568
> +26986
> +22193
> +18985
> +334
> +11
> +675
> +23098
> +13090
> +10232
> +24131
> +24210
> +32671
> +23747
> +9766
> +13959
> +30837
> +8515
> +31295
> +2313
> +24877
> +10020
> +30433
> +22083
> +3478
> +7941
> +18436
> +14792
> +17040
> +12004
> +13669
> +15490
> +16678
> +23356
> +28066
> +26871
> +25077
> +23461
> +21786
> +27509
> +27367
> +14961
> +2380
> +1662
> +32487
> +19835
> +6455
> +15376
> +614
> +9477
> +10695
> +28054
> +28624
> +31433
> +17214
> +30103
> +22748
> +32392
> +26740
> +20452
> +19781
> +17204
> +18886
> +2597
> +16593
> +833
> +32064
> +17379
> +17717
> +25184
> +19581
> +19423
> +26962
> +23824
> +25178
> +12322
> +15802
> +17619
> +10654
> +32343
> +17037
> +25858
> +17284
> +20361
> +31406
> +28206
> +17839
> +8121
> +29850
> +28389
> +17970
> +11480
> +16044
> +27103
> +32676
> +9884
> +7189
> +18612
> +27375
> +13011
> +25248
> +8624
> +27167
> +16913
> +17033
> +28474
> +8431
> +28770
> +32216
> +18027
> +25686
> +1292
> +5509
> +6894
> +12620
> +21287
> +24917
> +26323
> +28448
> +23047
> +12968
> +24616
> +3809
> +29518
> +9663
> +24553
> +29202
> +14835
> +21220
> +6785
> +12761
> +21624
> +19053
> +25295
> +15607
> +15236
> +30405
> +13704
> +5130
> +29608
> +26410
> +15114
> +19041
> +21133
> +467
> +24536
> +10935
> +2035
> +14883
> +8947
> +22955
> +13146
> +9581
> +29738
> +19553
> +7607
> +125
> +25092
> +5985
> +7843
> +1713
> +10628
> +25470
> +10901
> +19348
> +14538
> +29719
> +15625
> +18293
> +1742
> +4258
> +18738
> +16429
> +3453
> +21625
> +30091
> +18119
> +32643
> +4672
> +27135
> +2571
> +3211
> +9096
> +24942
> +14666
> +21660
> +28962
> +8376
> +27399
> +15822
> +31049
> +24155
> +20515
> +1979
> +16109
> +4627
> +21804
> +30092
> +334
> +18524
> +11833
> +20560
> +28614
> +29904
> +21991
> +23488
> +20411
> +11622
> +15031
> +2605
> +21713
> +7213
> +7527
> +11539
> +27664
> +26088
> +569
> +4311
> +20104
> +28409
> +20140
> +19522
> +9077
> +10930
> +18157
> +16787
> +25216
> +31867
> +15602
> +23801
> +7375
> +126
> +9909
> +32501
> +19906
> +19960
> +7843
> +8081
> +9047
> +22998
> +5138
> +21896
> +32155
> +32038
> +291
> +26500
> +17796
> +3376
> +5274
> +17693
> +16263
> +1929
> +27670
> +17073
> +4405
> +31778
> +14877
> +27450
> +32036
> +32068
> +18642
> +30320
> +25415
> +9179
> +13420
> +22419
> +11277
> +9943
> +11543
> +2342
> +18245
> +21913
> +28469
> +14693
> +27338
> +15644
> +18322
> +2936
> +12075
> +26487
> +32264
> +7399
> +14240
> +15771
> +24509
> +18825
> +24192
> +31505
> +26939
> +30511
> +461
> +1128
> +112
> +24820
> +1294
> +11189
> +20272
> +8069
> +12934
> +9509
> +19741
> +29200
> +15054
> +28557
> +25545
> +16865
> +27595
> +9225
> +28484
> +31668
> +5411
> +23119
> +10962
> +27218
> +25619
> +29940
> +3622
> +1066
> +11964
> +31472
> +20788
> +23492
> +24322
> +8570
> +11716
> +22958
> +29473
> +16120
> +23711
> +6619
> +19457
> +29281
> +27719
> +244
> +23114
> +28056
> +26593
> +9480
> +27710
> +31837
> +32069
> +4026
> +9879
> +9042
> +32608
> +6795
> +27340
> +6852
> +883
> +20682
> +18656
> +7122
> +15695
> +13991
> +16284
> +29566
> +6121
> +6020
> +31946
> +29874
> +31744
> +1946
> +22451
> +25898
> +23162
> +9393
> +3941
> +3448
> +32753
> +22040
> +29576
> +14181
> +5697
> +22569
> +11246
> +21344
> +2891
> +13406
> +24146
> +390
> +10703
> +8579
> +25655
> +2793
> +4943
> +30009
> +9639
> +18977
> +24143
> +18134
> +19731
> +14156
> +1232
> +8084
> +383
> +30027
> +15069
> +9746
> +1381
> +778
> +25038
> +28997
> +11532
> +13229
> +23991
> +28602
> +28324
> +28633
> +21528
> +13926
> +7710
> +4674
> +28146
> +31878
> +30140
> +24761
> +26088
> +10278
> +9298
> +19222
> +26857
> +23429
> +19972
> +14196
> +27217
> +12954
> +30148
> +17750
> +19522
> +21466
> +21660
> +11011
> +32207
> +22585
> +14840
> +3521
> +10587
> +22146
> +4859
> +17064
> +31390
> +28883
> +23549
> +28312
> +116
> +5260
> +19196
> +6555
> +22381
> +29286
> +19461
> +9586
> +10974
> +5676
> +32061
> +26244
> +1874
> +19439
> +5705
> +20417
> +25687
> +23385
> +29016
> +3201
> +5790
> +15781
> +21509
> +19756
> +23127
> +23924
> +10464
> +22550
> +26144
> +29604
> +20089
> +11870
> +16496
> +20640
> +27227
> +22890
> +23413
> +7918
> +22186
> +30532
> +23574
> +1646
> +25828
> +315
> +31698
> +13637
> +31893
> +25564
> +13690
> +14596
> +32347
> +23953
> +1829
> +19971
> +23093
> +5300
> +29371
> +10063
> +1129
> +21488
> +22779
> +8333
> +24487
> +27310
> +30552
> +21547
> +723
> +10370
> +13546
> +4082
> +8682
> +13208
> +5546
> +31993
> +27919
> +16801
> +20501
> +20527
> +4578
> +20495
> +23257
> +5340
> +21509
> +26646
> +19661
> +26958
> +13559
> +419
> +11644
> +26349
> +32524
> +11124
> +31548
> +26106
> +15439
> +13550
> +17329
> +17758
> +19741
> +1020
> +17659
> +29331
> +18736
> +6154
> +26313
> +28267
> +2627
> +29486
> +29044
> +5708
> +5702
> +31775
> +7941
> +9466
> +30057
> +7336
> +2555
> +28935
> +12294
> +4047
> +13739
> +15228
> +30671
> +25563
> +4206
> +21361
> +22280
> +475
> +6302
> +20412
> +26433
> +952
> +26151
> +20481
> +19452
> +18371
> +8940
> +20951
> +17110
> +13156
> +4703
> +31059
> +25482
> +7312
> +3673
> +17124
> +18114
> +4580
> +17464
> +1390
> +20398
> +31910
> +10008
> +26001
> +27332
> +16160
> +4857
> +24098
> +13238
> +13060
> +3120
> +24159
> +29069
> +10728
> +28482
> +5384
> +3942
> +7447
> +6547
> +19071
> +3039
> +13274
> +20428
> +9912
> +18337
> +19645
> +22585
> +24266
> +16901
> +2802
> +14553
> +30885
> +30400
> +32399
> +6435
> +29473
> +20710
> +28030
> +8862
> +1808
> +27159
> +18300
> +31619
> +11378
> +7340
> +338
> +27066
> +27540
> +24851
> +23453
> +30335
> +11332
> +27409
> +25216
> +6464
> +3600
> +31313
> +6494
> +17896
> +19375
> +2169
> +30255
> +10571
> +22434
> +1402
> +12939
> +6410
> +1089
> +1078
> +14455
> +23491
> +3051
> +4024
> +6072
> +28925
> +19218
> +11802
> +23003
> +4122
> +23330
> +21650
> +1085
> +1812
> +31021
> +11195
> +17798
> +11999
> +23012
> +15104
> +10956
> +890
> +24979
> +9399
> +16561
> +432
> +7010
> +5096
> +5997
> +20666
> +10967
> +11989
> +24193
> +14253
> +28125
> +1741
> +11372
> +14820
> +1120
> +31350
> +11628
> +25363
> +17657
> +3996
> +2792
> +22729
> +7050
> +10487
> +10522
> +13410
> +17034
> +5294
> +26133
> +5995
> +20262
> +1747
> +18778
> +26293
> +17222
> +23151
> +28805
> +28665
> +4636
> +14509
> +11355
> +12011
> +7781
> +21985
> +29915
> +29324
> +6290
> +15154
> +29132
> +11290
> +522
> +5120
> +20375
> +25145
> +11202
> +29750
> +15947
> +26516
> +22990
> +7319
> +20231
> +10644
> +27608
> +21434
> +32345
> +18927
> +6568
> +9749
> +31987
> +23632
> +21696
> +9666
> +2040
> +2134
> +2242
> +5559
> +27430
> +20952
> +192
> +31554
> +18837
> +11816
> +30277
> +25451
> +21547
> +2541
> +25816
> +29475
> +16232
> +1700
> +19817
> +21906
> +14691
> +12591
> +18044
> +8909
> +25202
> +27953
> +23172
> +22914
> +6804
> +14234
> +12636
> +20760
> +21866
> +31846
> +17844
> +20014
> +21902
> +15389
> +24169
> +29553
> +14032
> +16076
> +5035
> +25992
> +25029
> +4317
> +16615
> +20427
> +24495
> +11357
> +12509
> +8751
> +24526
> +11103
> +6514
> +27064
> +23387
> +25860
> +7862
> +29519
> +32038
> +5185
> +30944
> +24886
> +17154
> +31396
> +30740
> +8150
> +27337
> +28106
> +8701
> +16534
> +32519
> +25090
> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
> new file mode 100644
> index 000000000000..d351c8437d0a
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
> @@ -0,0 +1,10 @@
> +11637
> +3799
> +23116
> +15091
> +13022
> +15840
> +27029
> +27563
> +25641
> +28703
> --
> 2.32.0
>

2022-01-04 15:01:55

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 05/12] perf test: Add coresight test to check all threads get some data logged



On 1/3/22 07:07, Leo Yan wrote:
> On Wed, Dec 15, 2021 at 04:03:56PM +0000, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds a test and test scripts to check that all threads in the
>> target binary end up logging some kind of coresight aux data and that
>> they are not missing.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>> ---
>> .../coresight_thread_loop_check_tid_10.sh | 19 ++++
>> .../coresight_thread_loop_check_tid_2.sh | 19 ++++
>> .../coresight_thread_loop_check_tid_250.sh | 19 ++++
>> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
>> .../tools/coresight/thread_loop/Makefile | 29 +++++++
>> .../tools/coresight/thread_loop/thread_loop.c | 86 +++++++++++++++++++
>> 6 files changed, 174 insertions(+), 1 deletion(-)
>> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
>> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
>> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
>> create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
>> create mode 100644 tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
>>
>> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
>> new file mode 100755
>> index 000000000000..283ad9facdee
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_10.sh
>> @@ -0,0 +1,19 @@
>> +#!/bin/sh -e
>> +# Coresight / Thread Loop 10 Threads - Check TID
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="thread_loop"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS="10 2000"
>> +DATV="check-tid-10th"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +STDO="$DATD/perf-$TEST-$DATV.stdout"
>> +
>> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
>> +
>> +perf_dump_aux_tid_verify "$DATA" "$STDO"
>> +
>> +err=$?
>> +exit $err
>> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
>> new file mode 100755
>> index 000000000000..ce8ba534bba2
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_2.sh
>> @@ -0,0 +1,19 @@
>> +#!/bin/sh -e
>> +# Coresight / Thread Loop 2 Threads - Check TID
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="thread_loop"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS="2 4000"
>> +DATV="check-tid-2th"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +STDO="$DATD/perf-$TEST-$DATV.stdout"
>> +
>> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
>> +
>> +perf_dump_aux_tid_verify "$DATA" "$STDO"
>> +
>> +err=$?
>> +exit $err
>> diff --git a/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
>> new file mode 100755
>> index 000000000000..cb14581c1e68
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_thread_loop_check_tid_250.sh
>> @@ -0,0 +1,19 @@
>> +#!/bin/sh -e
>> +# Coresight / Thread Loop 250 Threads - Check TID
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="thread_loop"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS="250 100"
>> +DATV="check-tid-250th"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +STDO="$DATD/perf-$TEST-$DATV.stdout"
>> +
>> +SHOW_TID=1 perf record -s $PERFRECOPT -o "$DATA" "$BIN" $ARGS > $STDO
>> +
>> +perf_dump_aux_tid_verify "$DATA" "$STDO"
>> +
>> +err=$?
>> +exit $err
>
> From this case I start to understand why the lib/coresight.sh sets
> AUX buffer as 250MB, setting a large buffer size can capture trace
> data for all threads, especially for big amount of threads.
>
> Seems to me, if we test on server, this case can run for short time, but
> I think (sorry if I am wrong) it might take much longer time to test on
> the embedded system, which might cause testing failure by two factors:
>
> - The resource (e.g. the required big memory size) is pressure for
> embedded system;
> - The execution time (IIRC, every test case should be finished within
> 5 minutes).
>
> Do you think does it make sense for us to only use 32 threads or 64
> threads for the testing and it can give us a good testing coverage,
> and we don't need to maintain multiple cases for 2/10/250 threads?

I actually tested on a dragonboard 845c dev board (with the RB3 - only
4gb RAM) and took this as a baseline for "embedded board testing" as
it's probably about normal for a modern dev board. I made sure my tests
din't run out of RAM on that and would complete in a "not forever"
timeframe. I can probably reduce the number of cases, but I did go for
good coverage for stress-testing. I was doing 250 threads for the many
many many core cases and want to ensure I keep all cores busy (or a very
large number of them) to stress things out. Dev boards commonly have 8
cores these days, but servers are pushing 256 cores already (or 64 x 4
way smt and now are beginning to see 128 real cores etc.). So wanted to
make sure I'm pushing both ends of the spectrum.

> Thanks,
> Leo
>
>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
>> index 723006ea827c..1edab729db76 100644
>> --- a/tools/perf/tests/shell/tools/coresight/Makefile
>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
>> @@ -5,7 +5,8 @@ include ../../../../../../tools/scripts/Makefile.arch
>> include ../../../../../../tools/scripts/utilities.mak
>>
>> SUBDIRS = \
>> - asm_pure_loop
>> + asm_pure_loop \
>> + thread_loop
>>
>> all: $(SUBDIRS)
>> $(SUBDIRS):
>> diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
>> new file mode 100644
>> index 000000000000..424df4e8b0e6
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/thread_loop/Makefile
>> @@ -0,0 +1,29 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +include ../Makefile.miniconfig
>> +
>> +BIN=thread_loop
>> +LIB=-pthread
>> +
>> +all: $(BIN)
>> +
>> +$(BIN): $(BIN).c
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
>> +endif
>> +endif
>> +
>> +install-tests: all
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(call QUIET_INSTALL, tests) \
>> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
>> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
>> +endif
>> +endif
>> +
>> +clean:
>> + $(Q)$(RM) -f $(BIN)
>> +
>> +.PHONY: all clean install-tests
>> diff --git a/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
>> new file mode 100644
>> index 000000000000..c0158fac7d0b
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/thread_loop/thread_loop.c
>> @@ -0,0 +1,86 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Carsten Haitzler <[email protected]>, 2021
>> +
>> +// define this for gettid()
>> +#define _GNU_SOURCE
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <unistd.h>
>> +#include <string.h>
>> +#include <pthread.h>
>> +#include <sys/syscall.h>
>> +#ifndef SYS_gettid
>> +// gettid is 178 on arm64
>> +# define SYS_gettid 178
>> +#endif
>> +#define gettid() syscall(SYS_gettid)
>> +
>> +struct args {
>> + unsigned int loops;
>> + pthread_t th;
>> + void *ret;
>> +};
>> +
>> +static void *thrfn(void *arg)
>> +{
>> + struct args *a = arg;
>> + int i = 0, len = a->loops;
>> +
>> + if (getenv("SHOW_TID")) {
>> + unsigned long long tid = gettid();
>> +
>> + printf("%llu\n", tid);
>> + }
>> + asm volatile(
>> + "loop:\n"
>> + "add %[i], %[i], #1\n"
>> + "cmp %[i], %[len]\n"
>> + "blt loop\n"
>> + : /* out */
>> + : /* in */ [i] "r" (i), [len] "r" (len)
>> + : /* clobber */
>> + );
>> + return (void *)(long)i;
>> +}
>> +
>> +static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
>> +{
>> + pthread_t t;
>> + pthread_attr_t attr;
>> +
>> + pthread_attr_init(&attr);
>> + pthread_create(&t, &attr, fn, arg);
>> + return t;
>> +}
>> +
>> +int main(int argc, char **argv)
>> +{
>> + unsigned int i, len, thr;
>> + pthread_t threads[256];
>> + struct args args[256];
>> +
>> + if (argc < 3) {
>> + printf("ERR: %s [numthreads] [numloops (millions)]\n", argv[0]);
>> + exit(1);
>> + }
>> +
>> + thr = atoi(argv[1]);
>> + if ((thr < 1) || (thr > 256)) {
>> + printf("ERR: threads 1-256\n");
>> + exit(1);
>> + }
>> + len = atoi(argv[2]);
>> + if ((len < 1) || (len > 4000)) {
>> + printf("ERR: max loops 4000 (millions)\n");
>> + exit(1);
>> + }
>> + len *= 1000000;
>> + for (i = 0; i < thr; i++) {
>> + args[i].loops = len;
>> + args[i].th = new_thr(thrfn, &(args[i]));
>> + }
>> + for (i = 0; i < thr; i++)
>> + pthread_join(args[i].th, &(args[i].ret));
>> + return 0;
>> +}
>> --
>> 2.32.0
>>

2022-01-04 15:13:12

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 07/12] perf test: Add simple bubblesort test for coresight aux data



On 1/3/22 08:00, Leo Yan wrote:
> On Wed, Dec 15, 2021 at 04:03:58PM +0000, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds a simple bubblesort test that sorts small and large data
>> sets to see if a sufficient mount of aux data is produced.
>
> When review this patch set, I try to classify the testing cases into
> below three types, and I hope a testing is designed to verify a specific
> CoreSight feature and can fall into one of these three types:
>
> - For the waypoint testing, e.g. the test case is used to test different
> branch instructions (direct or indirect branch, exception, etc);
> - The config testing, we can rely on CoreSight configFS to configure
> the specific CoreSight working mode, e.g. using strobing mode for
> audoFDO [1];
> - Verify if CoreSight driver works correctly with perf event
> framework, I think essentially the test case [2] is used for this
> purpose.
>
> I know the bubble sort testing can give us more confidence to validate
> the CoreSight tracing data for a complex sort algorithm, on the other
> hand, bubble sort testing is essentially to test the way points.
>
> For this reason, I think the case asm_pure_loop.S has covered the
> testing for branch instructions, and if we want to cover more complete
> waypoint testing, you could consider to extend asm_pure_loop.S file.
>
> Furthermore, I expect the bubble sort is to be used for testing the
> CoreSight configuration, e.g. it can be used to test for the strobing
> mode (and for validation AutoFDO).
>
> How about you think for this?

I actually didn't include any autofdo testing as this was mostly a
matter of tooling after you have collected a trace. Run through the
trace data and then build up a good image of the execution of the target
and that would probably belong in tooling outside of the kernel. The
idea here was to see if we do collect sufficient amounts of data and
that the data looks "sane". This is all about looking to see if we only
get a single block or only 2 or 3 blocks then it stops or no blocks and
then with various stresses on kernel (memory heavy, cpu heavy) to see if
anything will greatly affect this.

The bubble sort does allow a basis to build some fdo tests on, but
having a baseline of "does it collect data at all" to start with is a
good call. I had not tested the strobing yet as that was probably
another phase in this. Most of this was about getting the core
infrastructure in to be able to add lots of little test tools we can run
and the harnesses to run them and collect statistical data over time.

Just a side note - the asm loop is arm64 specific and thus it's good for
testing an exact result from, but bubble sort is portable. It would
allow us to use this for an Arm 64 platform like the Morello board.
I've been keeping in mind "be somewhat portable" for this reason.

The only downside of keeping this test I think is that the whole test
suite takes a bit longer to run. Is this sufficient a concern to remove
this test from the patchset given the above?

> Thanks,
> Leo
>
> [1] https://www.kernel.org/doc/html/latest/trace/coresight/coresight-config.html#coresight-system-configuration-manager
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/tests/shell/test_arm_coresight.sh
>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>> ---
>> .../shell/coresight_bubble_sort_random.sh | 20 +
>> .../shell/coresight_bubble_sort_small.sh | 20 +
>> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
>> .../tools/coresight/bubble_sort/Makefile | 31 +
>> .../tools/coresight/bubble_sort/bubble_sort.c | 89 +
>> .../coresight/bubble_sort/random_array.txt | 1855 +++++++++++++++++
>> .../coresight/bubble_sort/small_array.txt | 10 +
>> 7 files changed, 2027 insertions(+), 1 deletion(-)
>> create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_random.sh
>> create mode 100755 tools/perf/tests/shell/coresight_bubble_sort_small.sh
>> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
>> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
>> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
>> create mode 100644 tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
>>
>> diff --git a/tools/perf/tests/shell/coresight_bubble_sort_random.sh b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
>> new file mode 100755
>> index 000000000000..63567f8c4f8b
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_bubble_sort_random.sh
>> @@ -0,0 +1,20 @@
>> +#!/bin/sh -e
>> +# Coresight / Bubblesort Random Array
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="bubble_sort"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS="$DIR/random_array.txt"
>> +DATV="random"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +
>> +echo $ARGS
>> +
>> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
>> +
>> +perf_dump_aux_verify "$DATA" 4188 1630 1630
>> +
>> +err=$?
>> +exit $err
>> diff --git a/tools/perf/tests/shell/coresight_bubble_sort_small.sh b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
>> new file mode 100755
>> index 000000000000..ac86d9973fba
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_bubble_sort_small.sh
>> @@ -0,0 +1,20 @@
>> +#!/bin/sh -e
>> +# Coresight / Bubblesort Small Array
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="bubble_sort"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS="$DIR/small_array.txt"
>> +DATV="small"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +
>> +echo $ARGS
>> +
>> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
>> +
>> +perf_dump_aux_verify "$DATA" 66 6 6
>> +
>> +err=$?
>> +exit $err
>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
>> index 1edab729db76..49fa80d28df4 100644
>> --- a/tools/perf/tests/shell/tools/coresight/Makefile
>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
>> @@ -6,7 +6,8 @@ include ../../../../../../tools/scripts/utilities.mak
>>
>> SUBDIRS = \
>> asm_pure_loop \
>> - thread_loop
>> + thread_loop \
>> + bubble_sort
>>
>> all: $(SUBDIRS)
>> $(SUBDIRS):
>> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
>> new file mode 100644
>> index 000000000000..6b82854f9f2b
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/Makefile
>> @@ -0,0 +1,31 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +include ../Makefile.miniconfig
>> +
>> +BIN=bubble_sort
>> +LIB=
>> +
>> +all: $(BIN)
>> +
>> +$(BIN): $(BIN).c
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
>> +endif
>> +endif
>> +
>> +install-tests: all
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(call QUIET_INSTALL, tests) \
>> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
>> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'; \
>> + $(INSTALL) random_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/random_array.txt'; \
>> + $(INSTALL) small_array.txt '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/small_array.txt'
>> +endif
>> +endif
>> +
>> +clean:
>> + $(Q)$(RM) -f $(BIN)
>> +
>> +.PHONY: all clean install-tests
>> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
>> new file mode 100644
>> index 000000000000..07169e03a803
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/bubble_sort.c
>> @@ -0,0 +1,89 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +// Andrea Brunato <[email protected]>, 2021
>> +// Example taken from: https://gcc.gnu.org/wiki/AutoFDO/Tutorial
>> +
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +#include <assert.h>
>> +
>> +int count_lines(FILE *fp)
>> +{
>> + int lines_n = 0;
>> + char c;
>> +
>> + for (c = getc(fp); !feof(fp); c = getc(fp)) {
>> + if (c == '\n')
>> + lines_n = lines_n + 1;
>> + }
>> + fseek(fp, 0, SEEK_SET);
>> +#ifdef DEBUG
>> + printf("Number of lines: %d\n", lines_n);
>> +#endif
>> + return lines_n;
>> +}
>> +
>> +#ifdef DEBUG
>> +void print_array(int *arr, int size)
>> +{
>> + int i;
>> +
>> + assert(arr != NULL);
>> + for (i = 0; i < size; i++)
>> + printf("%d\n", arr[i]);
>> +}
>> +#endif
>> +
>> +void bubble_sort(int *a, int n)
>> +{
>> + int i, t, s = 1;
>> +
>> + while (s) {
>> + s = 0;
>> + for (i = 1; i < n; i++) {
>> + if (a[i] < a[i - 1]) {
>> + t = a[i];
>> + a[i] = a[i - 1];
>> + a[i - 1] = t;
>> + s = 1;
>> + }
>> + }
>> + }
>> +}
>> +
>> +void init_array(int *arr, int size, FILE *fp)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < size; i++)
>> + fscanf(fp, "%d", &arr[i]);
>> +}
>> +
>> +int main(int argc, char **argv)
>> +{
>> + int lines_n = 0, *arr = NULL;
>> + FILE *fp;
>> +
>> + assert((argc == 2) && "Please specify an input file\n");
>> +
>> + fp = fopen(argv[1], "r");
>> + assert((fp != NULL) && "ERROR: Couldn't open the specified file\n");
>> +
>> + // Input file expected formar: one number per line
>> + lines_n = count_lines(fp);
>> +
>> + arr = malloc(sizeof(int) * lines_n);
>> + init_array(arr, lines_n, fp);
>> +
>> + bubble_sort(arr, lines_n);
>> +
>> +#ifdef DEBUG
>> + print_array(arr, lines_n);
>> +#endif
>> +
>> + free(arr);
>> + fclose(fp);
>> +
>> + return 0;
>> +}
>> +
>> +
>> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
>> new file mode 100644
>> index 000000000000..d041cfb7a649
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/random_array.txt
>> @@ -0,0 +1,1855 @@
>> +11637
>> +3799
>> +23116
>> +15091
>> +13022
>> +15840
>> +27029
>> +27563
>> +25641
>> +28703
>> +3017
>> +29923
>> +26998
>> +18230
>> +26864
>> +9139
>> +28431
>> +18283
>> +21315
>> +28167
>> +7700
>> +14798
>> +15512
>> +20470
>> +9237
>> +29921
>> +28395
>> +15057
>> +29819
>> +26831
>> +5926
>> +26653
>> +390
>> +2976
>> +21651
>> +410
>> +11429
>> +1828
>> +3534
>> +31091
>> +9141
>> +30892
>> +29619
>> +5033
>> +20585
>> +15413
>> +28673
>> +32517
>> +8875
>> +7509
>> +22159
>> +1482
>> +28926
>> +2748
>> +25246
>> +23677
>> +2712
>> +20332
>> +23615
>> +2481
>> +28581
>> +29728
>> +13726
>> +26364
>> +28074
>> +23534
>> +12120
>> +4130
>> +1307
>> +20009
>> +15225
>> +17469
>> +12076
>> +11899
>> +22886
>> +2854
>> +4667
>> +11494
>> +25057
>> +18590
>> +15010
>> +9295
>> +6603
>> +12891
>> +14441
>> +5499
>> +26880
>> +21390
>> +15932
>> +3975
>> +11242
>> +19063
>> +27555
>> +28538
>> +30148
>> +14592
>> +3360
>> +21049
>> +24923
>> +29681
>> +5157
>> +15595
>> +8863
>> +19992
>> +12588
>> +32711
>> +3077
>> +22132
>> +10031
>> +21685
>> +1634
>> +22046
>> +7323
>> +17925
>> +20453
>> +3694
>> +4502
>> +13543
>> +1959
>> +9365
>> +25814
>> +29540
>> +30414
>> +551
>> +32722
>> +23697
>> +32501
>> +9890
>> +13134
>> +2408
>> +21814
>> +1692
>> +8219
>> +27175
>> +19880
>> +1971
>> +17913
>> +10985
>> +75
>> +6275
>> +29139
>> +7104
>> +3241
>> +24809
>> +13310
>> +17897
>> +32684
>> +7199
>> +2015
>> +31825
>> +20985
>> +30466
>> +25403
>> +28839
>> +3939
>> +30171
>> +9223
>> +27181
>> +1302
>> +7945
>> +18902
>> +22094
>> +28959
>> +28100
>> +1874
>> +29613
>> +4804
>> +23941
>> +31981
>> +1874
>> +25476
>> +10176
>> +2004
>> +16080
>> +32404
>> +24472
>> +14217
>> +9647
>> +24917
>> +15001
>> +15559
>> +23867
>> +32520
>> +2545
>> +2233
>> +28869
>> +13685
>> +26640
>> +6548
>> +27395
>> +13590
>> +2851
>> +1008
>> +10772
>> +10417
>> +17257
>> +19706
>> +21757
>> +27627
>> +13514
>> +4631
>> +19162
>> +1138
>> +6325
>> +22136
>> +12944
>> +16124
>> +12359
>> +25197
>> +13024
>> +13459
>> +31896
>> +4661
>> +12648
>> +24619
>> +29975
>> +2417
>> +30526
>> +9880
>> +32733
>> +19252
>> +25646
>> +12851
>> +25535
>> +22792
>> +21622
>> +25256
>> +9785
>> +11252
>> +23999
>> +22965
>> +10221
>> +32537
>> +754
>> +6831
>> +11892
>> +4420
>> +12472
>> +20903
>> +18420
>> +14968
>> +17626
>> +25366
>> +27811
>> +6781
>> +15767
>> +19341
>> +28487
>> +28252
>> +1225
>> +31467
>> +10531
>> +29736
>> +12770
>> +11237
>> +26065
>> +9298
>> +9389
>> +4413
>> +25708
>> +4222
>> +206
>> +1952
>> +16927
>> +17411
>> +19671
>> +23966
>> +21346
>> +5232
>> +26240
>> +11465
>> +24782
>> +20600
>> +18201
>> +4713
>> +32313
>> +4899
>> +14371
>> +11307
>> +5277
>> +2022
>> +14443
>> +14631
>> +28140
>> +23499
>> +3955
>> +7565
>> +18082
>> +28583
>> +26049
>> +11652
>> +27835
>> +5415
>> +29742
>> +8307
>> +8380
>> +20582
>> +5376
>> +28696
>> +762
>> +6860
>> +8829
>> +3579
>> +2620
>> +14623
>> +26606
>> +31027
>> +8334
>> +5654
>> +15247
>> +25230
>> +8096
>> +1998
>> +11131
>> +25257
>> +31275
>> +18099
>> +22294
>> +9458
>> +17779
>> +22216
>> +4149
>> +22198
>> +172
>> +23793
>> +30710
>> +4351
>> +9939
>> +13985
>> +11652
>> +59
>> +26587
>> +9059
>> +26071
>> +20826
>> +3493
>> +32165
>> +10983
>> +29045
>> +28704
>> +29635
>> +19259
>> +15806
>> +15124
>> +18009
>> +20333
>> +17020
>> +1086
>> +13690
>> +32368
>> +14632
>> +15249
>> +31064
>> +18941
>> +9348
>> +9006
>> +31486
>> +4229
>> +26282
>> +24749
>> +11214
>> +12670
>> +5822
>> +23520
>> +7971
>> +28458
>> +28781
>> +15391
>> +28848
>> +1629
>> +30060
>> +19100
>> +27055
>> +6999
>> +7166
>> +31382
>> +12066
>> +15730
>> +23622
>> +17211
>> +30853
>> +15946
>> +7092
>> +5278
>> +14151
>> +29985
>> +2197
>> +3038
>> +17757
>> +14821
>> +11374
>> +16227
>> +7657
>> +29476
>> +7761
>> +6718
>> +5380
>> +3255
>> +28899
>> +507
>> +21354
>> +8942
>> +21928
>> +17282
>> +15106
>> +8035
>> +17251
>> +28354
>> +14675
>> +16033
>> +23012
>> +10270
>> +3609
>> +12387
>> +4083
>> +22608
>> +18438
>> +10363
>> +31842
>> +25456
>> +2993
>> +12567
>> +12285
>> +10847
>> +4036
>> +25889
>> +2263
>> +7521
>> +8246
>> +27332
>> +6281
>> +5934
>> +2057
>> +24322
>> +22014
>> +18625
>> +17420
>> +11120
>> +4933
>> +18486
>> +9201
>> +22355
>> +20027
>> +14665
>> +6106
>> +16764
>> +1955
>> +2674
>> +24517
>> +23913
>> +20392
>> +16961
>> +25273
>> +5622
>> +29187
>> +20339
>> +11895
>> +10335
>> +9094
>> +20758
>> +14115
>> +44
>> +29610
>> +29161
>> +14578
>> +30088
>> +22551
>> +9064
>> +19533
>> +428
>> +27047
>> +210
>> +7836
>> +24192
>> +18636
>> +32533
>> +4747
>> +1086
>> +23230
>> +6341
>> +31606
>> +8201
>> +29138
>> +28172
>> +11305
>> +1387
>> +25794
>> +23095
>> +2600
>> +1452
>> +8294
>> +15374
>> +31146
>> +18513
>> +11
>> +7897
>> +30819
>> +31
>> +11752
>> +32591
>> +27803
>> +26885
>> +7667
>> +31592
>> +10244
>> +24349
>> +17836
>> +25237
>> +21489
>> +9578
>> +6322
>> +5457
>> +15157
>> +15541
>> +19222
>> +12621
>> +21554
>> +22651
>> +12729
>> +10582
>> +10290
>> +10887
>> +23746
>> +26686
>> +1585
>> +10165
>> +31947
>> +19779
>> +15980
>> +20878
>> +28201
>> +26455
>> +10696
>> +19505
>> +29741
>> +1935
>> +2223
>> +28124
>> +17789
>> +24280
>> +25012
>> +11103
>> +6445
>> +10182
>> +22947
>> +31249
>> +12870
>> +25620
>> +9034
>> +28337
>> +17508
>> +12857
>> +32045
>> +23453
>> +18922
>> +29958
>> +13095
>> +27482
>> +1809
>> +13962
>> +15407
>> +23537
>> +28052
>> +24819
>> +7332
>> +29319
>> +11951
>> +7396
>> +0
>> +24126
>> +1573
>> +15203
>> +1194
>> +31509
>> +19366
>> +23180
>> +21698
>> +24946
>> +14946
>> +8384
>> +30229
>> +10099
>> +5060
>> +23938
>> +12575
>> +7220
>> +29396
>> +25422
>> +22865
>> +3935
>> +31126
>> +14275
>> +9741
>> +25019
>> +26108
>> +8997
>> +29459
>> +5595
>> +14307
>> +22680
>> +13453
>> +23456
>> +1218
>> +889
>> +11412
>> +22111
>> +15488
>> +16512
>> +24954
>> +25449
>> +14049
>> +10795
>> +6430
>> +7939
>> +23312
>> +8849
>> +4246
>> +3910
>> +3920
>> +8279
>> +29146
>> +23176
>> +29495
>> +22478
>> +22801
>> +15464
>> +1404
>> +24320
>> +9644
>> +24047
>> +6372
>> +25831
>> +10546
>> +25452
>> +162
>> +12526
>> +10816
>> +2805
>> +12098
>> +18199
>> +22284
>> +2588
>> +632
>> +23869
>> +9515
>> +18597
>> +5439
>> +11016
>> +19721
>> +14495
>> +5671
>> +3879
>> +9479
>> +13968
>> +25634
>> +12409
>> +8940
>> +1133
>> +25751
>> +6666
>> +19636
>> +3114
>> +18339
>> +27366
>> +24370
>> +31234
>> +24247
>> +27662
>> +16433
>> +9814
>> +13447
>> +20513
>> +18877
>> +26999
>> +18659
>> +27305
>> +15751
>> +17192
>> +11982
>> +31198
>> +11367
>> +20537
>> +6868
>> +9125
>> +26707
>> +28962
>> +4645
>> +22880
>> +29957
>> +21981
>> +29763
>> +10879
>> +15307
>> +21373
>> +652
>> +471
>> +6426
>> +15176
>> +11717
>> +8774
>> +21421
>> +22152
>> +11363
>> +21204
>> +8266
>> +30627
>> +3237
>> +17767
>> +9548
>> +31154
>> +26199
>> +11867
>> +2590
>> +508
>> +5685
>> +9562
>> +4680
>> +3527
>> +21332
>> +29853
>> +4331
>> +26626
>> +5804
>> +8806
>> +30680
>> +11836
>> +2053
>> +13250
>> +18750
>> +12811
>> +3459
>> +18921
>> +14531
>> +11448
>> +4381
>> +19024
>> +7032
>> +10599
>> +19932
>> +23346
>> +21110
>> +31736
>> +5792
>> +10309
>> +407
>> +6914
>> +19374
>> +11265
>> +15050
>> +30440
>> +14511
>> +16243
>> +19207
>> +25865
>> +3421
>> +8436
>> +17959
>> +30839
>> +28976
>> +22855
>> +1350
>> +5242
>> +4582
>> +19248
>> +4215
>> +10734
>> +29691
>> +1157
>> +5396
>> +5088
>> +30686
>> +24674
>> +29795
>> +20935
>> +12005
>> +1845
>> +20897
>> +25337
>> +27343
>> +27057
>> +11172
>> +23295
>> +28899
>> +2790
>> +15386
>> +30010
>> +3736
>> +22563
>> +13654
>> +32418
>> +3320
>> +9260
>> +4893
>> +1352
>> +897
>> +24116
>> +27410
>> +7866
>> +32310
>> +19354
>> +2760
>> +3243
>> +30622
>> +26854
>> +1810
>> +28332
>> +6230
>> +2049
>> +10362
>> +12110
>> +19718
>> +1304
>> +17994
>> +19655
>> +16923
>> +9017
>> +17840
>> +19894
>> +9328
>> +22423
>> +11185
>> +18453
>> +985
>> +14984
>> +31486
>> +2702
>> +7584
>> +20132
>> +5354
>> +22683
>> +27453
>> +15499
>> +8065
>> +9823
>> +29909
>> +31059
>> +23496
>> +32412
>> +31828
>> +3667
>> +13160
>> +5790
>> +11816
>> +31151
>> +6194
>> +16912
>> +20180
>> +32485
>> +10858
>> +28523
>> +9886
>> +10689
>> +1200
>> +26441
>> +2446
>> +10208
>> +4201
>> +649
>> +19694
>> +21476
>> +30880
>> +8900
>> +9817
>> +19507
>> +27582
>> +16013
>> +27193
>> +4177
>> +29851
>> +5791
>> +22262
>> +28816
>> +8540
>> +23328
>> +26992
>> +28046
>> +19652
>> +2195
>> +2694
>> +5634
>> +7430
>> +6356
>> +25759
>> +17606
>> +25591
>> +9758
>> +17330
>> +7393
>> +20057
>> +31341
>> +24765
>> +29760
>> +20556
>> +31406
>> +24439
>> +16953
>> +30044
>> +8448
>> +19044
>> +15593
>> +11764
>> +10639
>> +10535
>> +7469
>> +13865
>> +1039
>> +11436
>> +1319
>> +4999
>> +17500
>> +13796
>> +24842
>> +29723
>> +24282
>> +27361
>> +30792
>> +32410
>> +23984
>> +1667
>> +8323
>> +8491
>> +13317
>> +388
>> +9755
>> +28091
>> +19517
>> +29286
>> +23245
>> +4345
>> +9550
>> +18217
>> +31425
>> +17815
>> +6570
>> +7935
>> +6310
>> +550
>> +11700
>> +23011
>> +25532
>> +6854
>> +103
>> +6814
>> +15256
>> +6215
>> +122
>> +32352
>> +10646
>> +641
>> +4857
>> +16185
>> +26396
>> +6434
>> +14595
>> +6690
>> +29538
>> +25092
>> +16330
>> +15523
>> +5603
>> +8869
>> +19911
>> +4792
>> +12133
>> +27733
>> +23723
>> +32383
>> +1051
>> +10146
>> +8913
>> +6907
>> +4710
>> +6920
>> +27069
>> +15176
>> +17705
>> +13502
>> +17262
>> +7841
>> +12984
>> +29694
>> +21297
>> +2230
>> +10199
>> +24639
>> +9762
>> +9313
>> +5847
>> +18081
>> +9873
>> +14930
>> +5548
>> +953
>> +4307
>> +24255
>> +3720
>> +22293
>> +18312
>> +21097
>> +15784
>> +60
>> +4343
>> +2003
>> +26727
>> +26292
>> +24345
>> +6251
>> +28117
>> +25523
>> +15836
>> +31525
>> +32079
>> +8277
>> +31309
>> +8216
>> +15472
>> +9717
>> +10462
>> +10504
>> +27278
>> +12602
>> +13757
>> +11568
>> +26986
>> +22193
>> +18985
>> +334
>> +11
>> +675
>> +23098
>> +13090
>> +10232
>> +24131
>> +24210
>> +32671
>> +23747
>> +9766
>> +13959
>> +30837
>> +8515
>> +31295
>> +2313
>> +24877
>> +10020
>> +30433
>> +22083
>> +3478
>> +7941
>> +18436
>> +14792
>> +17040
>> +12004
>> +13669
>> +15490
>> +16678
>> +23356
>> +28066
>> +26871
>> +25077
>> +23461
>> +21786
>> +27509
>> +27367
>> +14961
>> +2380
>> +1662
>> +32487
>> +19835
>> +6455
>> +15376
>> +614
>> +9477
>> +10695
>> +28054
>> +28624
>> +31433
>> +17214
>> +30103
>> +22748
>> +32392
>> +26740
>> +20452
>> +19781
>> +17204
>> +18886
>> +2597
>> +16593
>> +833
>> +32064
>> +17379
>> +17717
>> +25184
>> +19581
>> +19423
>> +26962
>> +23824
>> +25178
>> +12322
>> +15802
>> +17619
>> +10654
>> +32343
>> +17037
>> +25858
>> +17284
>> +20361
>> +31406
>> +28206
>> +17839
>> +8121
>> +29850
>> +28389
>> +17970
>> +11480
>> +16044
>> +27103
>> +32676
>> +9884
>> +7189
>> +18612
>> +27375
>> +13011
>> +25248
>> +8624
>> +27167
>> +16913
>> +17033
>> +28474
>> +8431
>> +28770
>> +32216
>> +18027
>> +25686
>> +1292
>> +5509
>> +6894
>> +12620
>> +21287
>> +24917
>> +26323
>> +28448
>> +23047
>> +12968
>> +24616
>> +3809
>> +29518
>> +9663
>> +24553
>> +29202
>> +14835
>> +21220
>> +6785
>> +12761
>> +21624
>> +19053
>> +25295
>> +15607
>> +15236
>> +30405
>> +13704
>> +5130
>> +29608
>> +26410
>> +15114
>> +19041
>> +21133
>> +467
>> +24536
>> +10935
>> +2035
>> +14883
>> +8947
>> +22955
>> +13146
>> +9581
>> +29738
>> +19553
>> +7607
>> +125
>> +25092
>> +5985
>> +7843
>> +1713
>> +10628
>> +25470
>> +10901
>> +19348
>> +14538
>> +29719
>> +15625
>> +18293
>> +1742
>> +4258
>> +18738
>> +16429
>> +3453
>> +21625
>> +30091
>> +18119
>> +32643
>> +4672
>> +27135
>> +2571
>> +3211
>> +9096
>> +24942
>> +14666
>> +21660
>> +28962
>> +8376
>> +27399
>> +15822
>> +31049
>> +24155
>> +20515
>> +1979
>> +16109
>> +4627
>> +21804
>> +30092
>> +334
>> +18524
>> +11833
>> +20560
>> +28614
>> +29904
>> +21991
>> +23488
>> +20411
>> +11622
>> +15031
>> +2605
>> +21713
>> +7213
>> +7527
>> +11539
>> +27664
>> +26088
>> +569
>> +4311
>> +20104
>> +28409
>> +20140
>> +19522
>> +9077
>> +10930
>> +18157
>> +16787
>> +25216
>> +31867
>> +15602
>> +23801
>> +7375
>> +126
>> +9909
>> +32501
>> +19906
>> +19960
>> +7843
>> +8081
>> +9047
>> +22998
>> +5138
>> +21896
>> +32155
>> +32038
>> +291
>> +26500
>> +17796
>> +3376
>> +5274
>> +17693
>> +16263
>> +1929
>> +27670
>> +17073
>> +4405
>> +31778
>> +14877
>> +27450
>> +32036
>> +32068
>> +18642
>> +30320
>> +25415
>> +9179
>> +13420
>> +22419
>> +11277
>> +9943
>> +11543
>> +2342
>> +18245
>> +21913
>> +28469
>> +14693
>> +27338
>> +15644
>> +18322
>> +2936
>> +12075
>> +26487
>> +32264
>> +7399
>> +14240
>> +15771
>> +24509
>> +18825
>> +24192
>> +31505
>> +26939
>> +30511
>> +461
>> +1128
>> +112
>> +24820
>> +1294
>> +11189
>> +20272
>> +8069
>> +12934
>> +9509
>> +19741
>> +29200
>> +15054
>> +28557
>> +25545
>> +16865
>> +27595
>> +9225
>> +28484
>> +31668
>> +5411
>> +23119
>> +10962
>> +27218
>> +25619
>> +29940
>> +3622
>> +1066
>> +11964
>> +31472
>> +20788
>> +23492
>> +24322
>> +8570
>> +11716
>> +22958
>> +29473
>> +16120
>> +23711
>> +6619
>> +19457
>> +29281
>> +27719
>> +244
>> +23114
>> +28056
>> +26593
>> +9480
>> +27710
>> +31837
>> +32069
>> +4026
>> +9879
>> +9042
>> +32608
>> +6795
>> +27340
>> +6852
>> +883
>> +20682
>> +18656
>> +7122
>> +15695
>> +13991
>> +16284
>> +29566
>> +6121
>> +6020
>> +31946
>> +29874
>> +31744
>> +1946
>> +22451
>> +25898
>> +23162
>> +9393
>> +3941
>> +3448
>> +32753
>> +22040
>> +29576
>> +14181
>> +5697
>> +22569
>> +11246
>> +21344
>> +2891
>> +13406
>> +24146
>> +390
>> +10703
>> +8579
>> +25655
>> +2793
>> +4943
>> +30009
>> +9639
>> +18977
>> +24143
>> +18134
>> +19731
>> +14156
>> +1232
>> +8084
>> +383
>> +30027
>> +15069
>> +9746
>> +1381
>> +778
>> +25038
>> +28997
>> +11532
>> +13229
>> +23991
>> +28602
>> +28324
>> +28633
>> +21528
>> +13926
>> +7710
>> +4674
>> +28146
>> +31878
>> +30140
>> +24761
>> +26088
>> +10278
>> +9298
>> +19222
>> +26857
>> +23429
>> +19972
>> +14196
>> +27217
>> +12954
>> +30148
>> +17750
>> +19522
>> +21466
>> +21660
>> +11011
>> +32207
>> +22585
>> +14840
>> +3521
>> +10587
>> +22146
>> +4859
>> +17064
>> +31390
>> +28883
>> +23549
>> +28312
>> +116
>> +5260
>> +19196
>> +6555
>> +22381
>> +29286
>> +19461
>> +9586
>> +10974
>> +5676
>> +32061
>> +26244
>> +1874
>> +19439
>> +5705
>> +20417
>> +25687
>> +23385
>> +29016
>> +3201
>> +5790
>> +15781
>> +21509
>> +19756
>> +23127
>> +23924
>> +10464
>> +22550
>> +26144
>> +29604
>> +20089
>> +11870
>> +16496
>> +20640
>> +27227
>> +22890
>> +23413
>> +7918
>> +22186
>> +30532
>> +23574
>> +1646
>> +25828
>> +315
>> +31698
>> +13637
>> +31893
>> +25564
>> +13690
>> +14596
>> +32347
>> +23953
>> +1829
>> +19971
>> +23093
>> +5300
>> +29371
>> +10063
>> +1129
>> +21488
>> +22779
>> +8333
>> +24487
>> +27310
>> +30552
>> +21547
>> +723
>> +10370
>> +13546
>> +4082
>> +8682
>> +13208
>> +5546
>> +31993
>> +27919
>> +16801
>> +20501
>> +20527
>> +4578
>> +20495
>> +23257
>> +5340
>> +21509
>> +26646
>> +19661
>> +26958
>> +13559
>> +419
>> +11644
>> +26349
>> +32524
>> +11124
>> +31548
>> +26106
>> +15439
>> +13550
>> +17329
>> +17758
>> +19741
>> +1020
>> +17659
>> +29331
>> +18736
>> +6154
>> +26313
>> +28267
>> +2627
>> +29486
>> +29044
>> +5708
>> +5702
>> +31775
>> +7941
>> +9466
>> +30057
>> +7336
>> +2555
>> +28935
>> +12294
>> +4047
>> +13739
>> +15228
>> +30671
>> +25563
>> +4206
>> +21361
>> +22280
>> +475
>> +6302
>> +20412
>> +26433
>> +952
>> +26151
>> +20481
>> +19452
>> +18371
>> +8940
>> +20951
>> +17110
>> +13156
>> +4703
>> +31059
>> +25482
>> +7312
>> +3673
>> +17124
>> +18114
>> +4580
>> +17464
>> +1390
>> +20398
>> +31910
>> +10008
>> +26001
>> +27332
>> +16160
>> +4857
>> +24098
>> +13238
>> +13060
>> +3120
>> +24159
>> +29069
>> +10728
>> +28482
>> +5384
>> +3942
>> +7447
>> +6547
>> +19071
>> +3039
>> +13274
>> +20428
>> +9912
>> +18337
>> +19645
>> +22585
>> +24266
>> +16901
>> +2802
>> +14553
>> +30885
>> +30400
>> +32399
>> +6435
>> +29473
>> +20710
>> +28030
>> +8862
>> +1808
>> +27159
>> +18300
>> +31619
>> +11378
>> +7340
>> +338
>> +27066
>> +27540
>> +24851
>> +23453
>> +30335
>> +11332
>> +27409
>> +25216
>> +6464
>> +3600
>> +31313
>> +6494
>> +17896
>> +19375
>> +2169
>> +30255
>> +10571
>> +22434
>> +1402
>> +12939
>> +6410
>> +1089
>> +1078
>> +14455
>> +23491
>> +3051
>> +4024
>> +6072
>> +28925
>> +19218
>> +11802
>> +23003
>> +4122
>> +23330
>> +21650
>> +1085
>> +1812
>> +31021
>> +11195
>> +17798
>> +11999
>> +23012
>> +15104
>> +10956
>> +890
>> +24979
>> +9399
>> +16561
>> +432
>> +7010
>> +5096
>> +5997
>> +20666
>> +10967
>> +11989
>> +24193
>> +14253
>> +28125
>> +1741
>> +11372
>> +14820
>> +1120
>> +31350
>> +11628
>> +25363
>> +17657
>> +3996
>> +2792
>> +22729
>> +7050
>> +10487
>> +10522
>> +13410
>> +17034
>> +5294
>> +26133
>> +5995
>> +20262
>> +1747
>> +18778
>> +26293
>> +17222
>> +23151
>> +28805
>> +28665
>> +4636
>> +14509
>> +11355
>> +12011
>> +7781
>> +21985
>> +29915
>> +29324
>> +6290
>> +15154
>> +29132
>> +11290
>> +522
>> +5120
>> +20375
>> +25145
>> +11202
>> +29750
>> +15947
>> +26516
>> +22990
>> +7319
>> +20231
>> +10644
>> +27608
>> +21434
>> +32345
>> +18927
>> +6568
>> +9749
>> +31987
>> +23632
>> +21696
>> +9666
>> +2040
>> +2134
>> +2242
>> +5559
>> +27430
>> +20952
>> +192
>> +31554
>> +18837
>> +11816
>> +30277
>> +25451
>> +21547
>> +2541
>> +25816
>> +29475
>> +16232
>> +1700
>> +19817
>> +21906
>> +14691
>> +12591
>> +18044
>> +8909
>> +25202
>> +27953
>> +23172
>> +22914
>> +6804
>> +14234
>> +12636
>> +20760
>> +21866
>> +31846
>> +17844
>> +20014
>> +21902
>> +15389
>> +24169
>> +29553
>> +14032
>> +16076
>> +5035
>> +25992
>> +25029
>> +4317
>> +16615
>> +20427
>> +24495
>> +11357
>> +12509
>> +8751
>> +24526
>> +11103
>> +6514
>> +27064
>> +23387
>> +25860
>> +7862
>> +29519
>> +32038
>> +5185
>> +30944
>> +24886
>> +17154
>> +31396
>> +30740
>> +8150
>> +27337
>> +28106
>> +8701
>> +16534
>> +32519
>> +25090
>> diff --git a/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
>> new file mode 100644
>> index 000000000000..d351c8437d0a
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/bubble_sort/small_array.txt
>> @@ -0,0 +1,10 @@
>> +11637
>> +3799
>> +23116
>> +15091
>> +13022
>> +15840
>> +27029
>> +27563
>> +25641
>> +28703
>> --
>> 2.32.0
>>

2022-01-04 15:14:20

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight



On 12/21/21 15:03, Leo Yan wrote:
> Hi Carsten,
>
> On Wed, Dec 15, 2021 at 04:03:55PM +0000, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds the initial test harness to run perf record and examine the
>> resuling output when coresight is enabled on arm64 and check the
>> resulting quality of the output as part of perf test.
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>> ---
>> MAINTAINERS | 3 +
>> tools/perf/Makefile.perf | 14 +-
>> .../tests/shell/coresight_asm_pure_loop.sh | 18 +++
>> tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
>> tools/perf/tests/shell/tools/Makefile | 26 ++++
>> .../perf/tests/shell/tools/coresight/Makefile | 27 ++++
>> .../shell/tools/coresight/Makefile.miniconfig | 23 ++++
>> .../tools/coresight/asm_pure_loop/Makefile | 30 ++++
>> .../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
>> 9 files changed, 297 insertions(+), 2 deletions(-)
>> create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
>> create mode 100644 tools/perf/tests/shell/lib/coresight.sh
>> create mode 100644 tools/perf/tests/shell/tools/Makefile
>> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
>> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>
> The folder naming is okay for me, but it is cyclic with the format:
> "tools/.../tools/". So I am wandering if below two pathes are better?
>
> tools/perf/tests/shell/prog/coresight/
> or
> tools/perf/tests/shell/coresight/
>
> I'd like to leave this question for Arnaldo / Jiri for the folder
> layout.

Personally - I'm not fussed. :) So whatever you think is best.

>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 13f9a84a617e..d46e8469c467 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
>> F: tools/perf/arch/arm/util/cs-etm.c
>> F: tools/perf/arch/arm/util/cs-etm.h
>> F: tools/perf/arch/arm/util/pmu.c
>> +F: tools/perf/tests/shell/coresight_*
>> +F: tools/perf/tests/shell/tools/Makefile
>> +F: tools/perf/tests/shell/tools/coresight/*
>> F: tools/perf/util/cs-etm-decoder/*
>> F: tools/perf/util/cs-etm.*
>>
>> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
>> index 80522bcfafe0..26467a2c71f4 100644
>> --- a/tools/perf/Makefile.perf
>> +++ b/tools/perf/Makefile.perf
>> @@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
>> $(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
>> $(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@
>>
>> -all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
>> +TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
>> +
>> +tests-tools-targets: FORCE
>> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
>> +
>> +tests-tools-targets-clean:
>> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
>> +
>> +all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets
>>
>> # Create python binding output directory if not already present
>> _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
>> @@ -1020,6 +1028,7 @@ install-tests: all install-gtk
>> $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
>> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
>> $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
>> + $(Q)$(MAKE) -C tests/shell/tools install-tests
>>
>> install-bin: install-tools install-tests install-traceevent-plugins
>>
>> @@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
>> bpf-skel-clean:
>> $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
>>
>> -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
>> +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
>> $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
>> $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
>> $(Q)$(RM) $(OUTPUT).config-detected
>> @@ -1155,5 +1164,6 @@ FORCE:
>> .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
>> .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
>> .PHONY: libtraceevent_plugins archheaders
>> +.PHONY: $(TESTS_TOOLS_TARGETS)
>>
>> endif # force_fixdep
>> diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
>> new file mode 100755
>> index 000000000000..542d4a37e349
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
>> @@ -0,0 +1,18 @@
>> +#!/bin/sh -e
>> +# Coresight / ASM Pure Loop
>> +
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +TEST="asm_pure_loop"
>> +. $(dirname $0)/lib/coresight.sh
>> +ARGS=""
>> +DATV="out"
>> +DATA="$DATD/perf-$TEST-$DATV.data"
>> +
>> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
>
> Is $ARGS redundant and can be removed?
>
>> +perf_dump_aux_verify "$DATA" 2601 334 334
>
> These three magic numbers "2601 334 334" would be hard to understand.
> One way is the code can dynamically calculate these values based on the
> loop times (the loop is is predefined in asm_pure_loop.S), or it's
> good to give explanation in comments for these values.
>
>> +
>> +err=$?
>> +exit $err
>> diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
>> new file mode 100644
>> index 000000000000..cd6c1283e6f5
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/lib/coresight.sh
>> @@ -0,0 +1,130 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +# This is sourced from a driver script so no need for #!/bin... etc. at the
>> +# top - the assumption below is that it runs as part of sourcing after the
>> +# test sets up some basic env vars to say what it is.
>> +
>> +# perf record options for the perf tests to use
>> +PERFRECMEM="-m ,128M"
>
> We must use 128Mb for the AUX trace buffer? The big buffer size is
> not friendly for embedded system.
>
>> +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
>> +
>> +# These tests need to be run as root or coresight won't allow large buffers
>> +# and will not collect proper data
>> +UID=`id -u`
>> +if test "$UID" -ne 0; then
>> + echo "Not running as root... skip"
>> + exit 2
>> +fi
>> +
>> +TOOLS=$(dirname $0)/tools
>> +DIR="$TOOLS/coresight/$TEST"
>> +BIN="$DIR/$TEST"
>> +# If the test tool/binary does not exist and is executable then skip the test
>> +if ! test -x "$BIN"; then exit 2; fi
>> +DATD="."
>
> It's blur to set DATD and STATD to ".". If the user doesn't specify
> the envs, it's not clear it will point to which folder.
>
>> +# If the data dir env is set then make the data dir use that instead of ./
>> +if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
>> + DATD="$PERF_TEST_CORESIGHT_DATADIR";
>> +fi
>> +# If the stat dir env is set then make the data dir use that instead of ./
>> +STATD="."
>> +if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
>> + STATD="$PERF_TEST_CORESIGHT_STATDIR";
>> +fi
>> +
>> +# Called if the test fails - error code 2
>> +err() {
>> + echo "$1"
>> + exit 1
>> +}
>> +
>> +# Check that some statistics from our perf
>> +check_val_min() {
>> + STATF="$4"
>> + if test "$2" -lt "$3"; then
>> + echo ", FAILED" >> "$STATF"
>> + err "Sanity check number of $1 is too low ($2 < $3)"
>> + fi
>> +}
>> +
>> +perf_dump_aux_verify() {
>> + # Some basic checking that the AUX chunk contains some sensible data
>> + # to see that we are recording something and at least a minimum
>> + # amount of it. We should almost always see F3 atoms in just about
>> + # anything but certainly we will see some trace info and async atom
>> + # chunks.
>> + DUMP="$DATD/perf-tmp-aux-dump.txt"
>> + perf report --stdio --dump -i "$1" | \
>> + grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
>> + # Simply count how many of these atoms we find to see that we are
>> + # producing a reasonable amount of data - exact checks are not sane
>> + # as this is a lossy process where we may lose some blocks and the
>> + # compiler may produce different code depending on the compiler and
>> + # optimization options, so this is rough just to see if we're
>> + # either missing almost all the data or all of it
>> + ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
>> + ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
>> + ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
>> + rm -f "$DUMP"
>> +
>> + # Arguments provide minimums for a pass
>> + CHECK_F3_MIN="$2"
>> + CHECK_ASYNC_MIN="$3"
>> + CHECK_TRACE_INFO_MIN="$4"
>> +
>> + # Write out statistics, so over time you can track results to see if
>> + # there is a pattern - for example we have less "noisy" results that
>> + # produce more consistent amounts of data each run, to see if over
>> + # time any techinques to minimize data loss are having an effect or
>> + # not
>> + STATF="$STATD/stats-$TEST-$DATV.csv"
>> + if ! test -f "$STATF"; then
>> + echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
>> + fi
>> + echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
>> +
>> + # Actually check to see if we passed or failed.
>> + check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
>> + check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
>> + check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
>> + echo ", Ok" >> "$STATF"
>> +}
>> +
>> +perf_dump_aux_tid_verify() {
>
> This function is not used in the test contained in this patch.
>
>> + # Specifically crafted test will produce a list of Tread ID's to
>> + # stdout that need to be checked to see that they have had trace
>> + # info collected in AUX blocks in the perf data. This will go
>> + # through all the TID's that are listed as CID=0xabcdef and see
>> + # that all the Thread IDs the test tool reports are in the perf
>> + # data AUX chunks
>> +
>> + # The TID test tools will print a TID per stdout line that are being
>> + # tested
>> + TIDS=`cat "$2"`
>> + # Scan the perf report to find the TIDs that are actually CID in hex
>> + # and build a list of the ones found
>> + FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
>> + grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
>> + uniq | sort | uniq`
>> +
>> + # Iterate over the list of TIDs that the test says it has and find
>> + # them in the TIDs found in the perf report
>> + MISSING=""
>> + for TID2 in $TIDS; do
>> + FOUND=""
>> + for TIDHEX in $FOUND_TIDS; do
>> + TID=`printf "%i" $TIDHEX`
>> + if test "$TID" -eq "$TID2"; then
>> + FOUND="y"
>> + break
>> + fi
>> + done
>> + if test -z "$FOUND"; then
>> + MISSING="$MISSING $TID"
>> + fi
>> + done
>> + if test -n "$MISSING"; then
>> + err "Thread IDs $MISSING not found in perf AUX data"
>> + fi
>> +}
>> diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
>> new file mode 100644
>> index 000000000000..c7ada20922fd
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/Makefile
>> @@ -0,0 +1,26 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +# Carsten Haitzler <[email protected]>, 2021
>> +include ../../../../../tools/scripts/Makefile.include
>> +include ../../../../../tools/scripts/Makefile.arch
>> +include ../../../../../tools/scripts/utilities.mak
>
> To be honest, I don't understand well for perf's build and config
> system. Seems to me, a good example for building program is jevents.
>
> Please take a look for the code:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Makefile.perf#n667
>
> If follow the same method with jevents for building test programs,
> I can see one benefit is we don't need to create a Makefile, on the
> other hand, we can reuse the perf's build system and simply create a
> Build file under the folder tools/perf/tests/shell/.../coresight/.
>
>> +
>> +SUBDIRS = \
>> + coresight
>> +
>> +all: $(SUBDIRS)
>> +$(SUBDIRS):
>> + $(Q)$(MAKE) -C $@
>> +
>> +INSTALLDIRS = $(SUBDIRS:%=install-%)
>> +
>> +install-tests: all $(INSTALLDIRS)
>> +$(INSTALLDIRS):
>> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
>> +
>> +CLEANDIRS = $(SUBDIRS:%=clean-%)
>> +
>> +clean: $(CLEANDIRS)
>> +$(CLEANDIRS):
>> + $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
>> +
>> +.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
>> new file mode 100644
>> index 000000000000..723006ea827c
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
>> @@ -0,0 +1,27 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +# Carsten Haitzler <[email protected]>, 2021
>> +include ../../../../../../tools/scripts/Makefile.include
>> +include ../../../../../../tools/scripts/Makefile.arch
>> +include ../../../../../../tools/scripts/utilities.mak
>> +
>> +SUBDIRS = \
>> + asm_pure_loop
>> +
>> +all: $(SUBDIRS)
>> +$(SUBDIRS):
>> + $(Q)$(MAKE) -C $@
>> +
>> +INSTALLDIRS = $(SUBDIRS:%=install-%)
>> +
>> +install-tests: $(INSTALLDIRS)
>> +$(INSTALLDIRS):
>> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
>> +
>> +CLEANDIRS = $(SUBDIRS:%=clean-%)
>> +
>> +clean: $(CLEANDIRS)
>> +$(CLEANDIRS):
>> + $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
>> +
>> +.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
>> +
>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>> new file mode 100644
>> index 000000000000..cedd26c6a0eb
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>> @@ -0,0 +1,23 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +ifndef DESTDIR
>> +prefix ?= $(HOME)
>> +endif
>> +
>> +DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
>> +perfexecdir = libexec/perf-core
>> +perfexec_instdir = $(perfexecdir)
>> +
>> +ifneq ($(filter /%,$(firstword $(perfexecdir))),)
>> +perfexec_instdir = $(perfexecdir)
>> +else
>> +perfexec_instdir = $(prefix)/$(perfexecdir)
>> +endif
>> +
>> +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
>> +INSTALL = install
>> +
>> +include ../../../../../../scripts/Makefile.include
>> +include ../../../../../../scripts/Makefile.arch
>> +include ../../../../../../scripts/utilities.mak
>
> As suggested above, if we refer the building method of jevent, I think
> this Makefile.miniconfig is not needed anymore.
>
>> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>> new file mode 100644
>> index 000000000000..10c5a60cb71c
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>> @@ -0,0 +1,30 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Carsten Haitzler <[email protected]>, 2021
>> +
>> +include ../Makefile.miniconfig
>> +
>> +BIN=asm_pure_loop
>> +LIB=
>> +
>> +all: $(BIN)
>> +
>> +$(BIN): $(BIN).S
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
>> +endif
>> +endif
>> +
>> +install-tests: all
>> +ifdef CORESIGHT
>> +ifeq ($(ARCH),arm64)
>> + $(call QUIET_INSTALL, tests) \
>> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
>> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
>> +endif
>> +endif
>> +
>> +clean:
>> + $(Q)$(RM) -f $(BIN)
>> +
>> +.PHONY: all clean install-tests
>> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>> new file mode 100644
>> index 000000000000..262876451021
>> --- /dev/null
>> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>> @@ -0,0 +1,28 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Tamas Zsoldos <[email protected]>, 2021 */
>> +
>> +.globl _start
>> +_start:
>> + mov x0, 0x000fffff
>> + mov x1, xzr
>> +loop:
>> + nop
>> + nop
>> + cbnz x1, noskip
>> + nop
>> + nop
>> + adrp x2, skip
>> + add x2, x2, :lo12:skip
>> + br x2
>> + nop
>> + nop
>> +noskip:
>> + nop
>> + nop
>> +skip:
>> + sub x0, x0, 1
>> + cbnz x0, loop
>> +
>> + mov x0, #0
>> + mov x8, #93 // __NR_exit syscall
>> + svc #0
>
> I verified this code on Arm64 machine and it works!
>
> I am a bit worry about the code for using the hard code number for
> system call. Another option is to use the inline assembly
> in C code, I think you have considered for this approach, this might
> introduce noise for extra branch instructions during the testing,
> but it can allow us to program standard C program (and don't worry
> about the program exiting).
>
> If you think using assembly code is better than inline assembly, it
> would be fine for me. Eventually, the system call number is very
> seldomly to be changed.
>
> Thanks,
> Leo

2022-01-04 15:15:34

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight



On 12/21/21 20:40, Arnaldo Carvalho de Melo wrote:
> Em Tue, Dec 21, 2021 at 11:03:49PM +0800, Leo Yan escreveu:
>> Hi Carsten,
>>
>> On Wed, Dec 15, 2021 at 04:03:55PM +0000, [email protected] wrote:
>>> From: Carsten Haitzler <[email protected]>
>>>
>>> This adds the initial test harness to run perf record and examine the
>>> resuling output when coresight is enabled on arm64 and check the
>>> resulting quality of the output as part of perf test.
>>>
>>> Signed-off-by: Carsten Haitzler <[email protected]>
>>> ---
>>> MAINTAINERS | 3 +
>>> tools/perf/Makefile.perf | 14 +-
>>> .../tests/shell/coresight_asm_pure_loop.sh | 18 +++
>>> tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
>>> tools/perf/tests/shell/tools/Makefile | 26 ++++
>>> .../perf/tests/shell/tools/coresight/Makefile | 27 ++++
>>> .../shell/tools/coresight/Makefile.miniconfig | 23 ++++
>>> .../tools/coresight/asm_pure_loop/Makefile | 30 ++++
>>> .../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
>>> 9 files changed, 297 insertions(+), 2 deletions(-)
>>> create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
>>> create mode 100644 tools/perf/tests/shell/lib/coresight.sh
>>> create mode 100644 tools/perf/tests/shell/tools/Makefile
>>> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
>>> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>>> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>>> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>>
>> The folder naming is okay for me, but it is cyclic with the format:
>> "tools/.../tools/". So I am wandering if below two pathes are better?
>>
>> tools/perf/tests/shell/prog/coresight/
>> or
>> tools/perf/tests/shell/coresight/
>
> The later, its descriptive enough, I think, and the shortest variant so
> far.

Sure - no problem. I can change that. Once no one has any more comments
and a few of the pending thnigs I've marked to resolve are solved, I'll
submit a new patch set.

> - Arnaldo
>
>> I'd like to leave this question for Arnaldo / Jiri for the folder
>> layout.
>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 13f9a84a617e..d46e8469c467 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
>>> F: tools/perf/arch/arm/util/cs-etm.c
>>> F: tools/perf/arch/arm/util/cs-etm.h
>>> F: tools/perf/arch/arm/util/pmu.c
>>> +F: tools/perf/tests/shell/coresight_*
>>> +F: tools/perf/tests/shell/tools/Makefile
>>> +F: tools/perf/tests/shell/tools/coresight/*
>>> F: tools/perf/util/cs-etm-decoder/*
>>> F: tools/perf/util/cs-etm.*
>>>
>>> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
>>> index 80522bcfafe0..26467a2c71f4 100644
>>> --- a/tools/perf/Makefile.perf
>>> +++ b/tools/perf/Makefile.perf
>>> @@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
>>> $(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
>>> $(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@
>>>
>>> -all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
>>> +TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
>>> +
>>> +tests-tools-targets: FORCE
>>> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
>>> +
>>> +tests-tools-targets-clean:
>>> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
>>> +
>>> +all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets
>>>
>>> # Create python binding output directory if not already present
>>> _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
>>> @@ -1020,6 +1028,7 @@ install-tests: all install-gtk
>>> $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
>>> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
>>> $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
>>> + $(Q)$(MAKE) -C tests/shell/tools install-tests
>>>
>>> install-bin: install-tools install-tests install-traceevent-plugins
>>>
>>> @@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
>>> bpf-skel-clean:
>>> $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
>>>
>>> -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
>>> +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
>>> $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
>>> $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
>>> $(Q)$(RM) $(OUTPUT).config-detected
>>> @@ -1155,5 +1164,6 @@ FORCE:
>>> .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
>>> .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
>>> .PHONY: libtraceevent_plugins archheaders
>>> +.PHONY: $(TESTS_TOOLS_TARGETS)
>>>
>>> endif # force_fixdep
>>> diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
>>> new file mode 100755
>>> index 000000000000..542d4a37e349
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
>>> @@ -0,0 +1,18 @@
>>> +#!/bin/sh -e
>>> +# Coresight / ASM Pure Loop
>>> +
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +
>>> +TEST="asm_pure_loop"
>>> +. $(dirname $0)/lib/coresight.sh
>>> +ARGS=""
>>> +DATV="out"
>>> +DATA="$DATD/perf-$TEST-$DATV.data"
>>> +
>>> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
>>
>> Is $ARGS redundant and can be removed?
>>
>>> +perf_dump_aux_verify "$DATA" 2601 334 334
>>
>> These three magic numbers "2601 334 334" would be hard to understand.
>> One way is the code can dynamically calculate these values based on the
>> loop times (the loop is is predefined in asm_pure_loop.S), or it's
>> good to give explanation in comments for these values.
>>
>>> +
>>> +err=$?
>>> +exit $err
>>> diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
>>> new file mode 100644
>>> index 000000000000..cd6c1283e6f5
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/lib/coresight.sh
>>> @@ -0,0 +1,130 @@
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +
>>> +# This is sourced from a driver script so no need for #!/bin... etc. at the
>>> +# top - the assumption below is that it runs as part of sourcing after the
>>> +# test sets up some basic env vars to say what it is.
>>> +
>>> +# perf record options for the perf tests to use
>>> +PERFRECMEM="-m ,128M"
>>
>> We must use 128Mb for the AUX trace buffer? The big buffer size is
>> not friendly for embedded system.
>>
>>> +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
>>> +
>>> +# These tests need to be run as root or coresight won't allow large buffers
>>> +# and will not collect proper data
>>> +UID=`id -u`
>>> +if test "$UID" -ne 0; then
>>> + echo "Not running as root... skip"
>>> + exit 2
>>> +fi
>>> +
>>> +TOOLS=$(dirname $0)/tools
>>> +DIR="$TOOLS/coresight/$TEST"
>>> +BIN="$DIR/$TEST"
>>> +# If the test tool/binary does not exist and is executable then skip the test
>>> +if ! test -x "$BIN"; then exit 2; fi
>>> +DATD="."
>>
>> It's blur to set DATD and STATD to ".". If the user doesn't specify
>> the envs, it's not clear it will point to which folder.
>>
>>> +# If the data dir env is set then make the data dir use that instead of ./
>>> +if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
>>> + DATD="$PERF_TEST_CORESIGHT_DATADIR";
>>> +fi
>>> +# If the stat dir env is set then make the data dir use that instead of ./
>>> +STATD="."
>>> +if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
>>> + STATD="$PERF_TEST_CORESIGHT_STATDIR";
>>> +fi
>>> +
>>> +# Called if the test fails - error code 2
>>> +err() {
>>> + echo "$1"
>>> + exit 1
>>> +}
>>> +
>>> +# Check that some statistics from our perf
>>> +check_val_min() {
>>> + STATF="$4"
>>> + if test "$2" -lt "$3"; then
>>> + echo ", FAILED" >> "$STATF"
>>> + err "Sanity check number of $1 is too low ($2 < $3)"
>>> + fi
>>> +}
>>> +
>>> +perf_dump_aux_verify() {
>>> + # Some basic checking that the AUX chunk contains some sensible data
>>> + # to see that we are recording something and at least a minimum
>>> + # amount of it. We should almost always see F3 atoms in just about
>>> + # anything but certainly we will see some trace info and async atom
>>> + # chunks.
>>> + DUMP="$DATD/perf-tmp-aux-dump.txt"
>>> + perf report --stdio --dump -i "$1" | \
>>> + grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
>>> + # Simply count how many of these atoms we find to see that we are
>>> + # producing a reasonable amount of data - exact checks are not sane
>>> + # as this is a lossy process where we may lose some blocks and the
>>> + # compiler may produce different code depending on the compiler and
>>> + # optimization options, so this is rough just to see if we're
>>> + # either missing almost all the data or all of it
>>> + ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
>>> + ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
>>> + ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
>>> + rm -f "$DUMP"
>>> +
>>> + # Arguments provide minimums for a pass
>>> + CHECK_F3_MIN="$2"
>>> + CHECK_ASYNC_MIN="$3"
>>> + CHECK_TRACE_INFO_MIN="$4"
>>> +
>>> + # Write out statistics, so over time you can track results to see if
>>> + # there is a pattern - for example we have less "noisy" results that
>>> + # produce more consistent amounts of data each run, to see if over
>>> + # time any techinques to minimize data loss are having an effect or
>>> + # not
>>> + STATF="$STATD/stats-$TEST-$DATV.csv"
>>> + if ! test -f "$STATF"; then
>>> + echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
>>> + fi
>>> + echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
>>> +
>>> + # Actually check to see if we passed or failed.
>>> + check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
>>> + check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
>>> + check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
>>> + echo ", Ok" >> "$STATF"
>>> +}
>>> +
>>> +perf_dump_aux_tid_verify() {
>>
>> This function is not used in the test contained in this patch.
>>
>>> + # Specifically crafted test will produce a list of Tread ID's to
>>> + # stdout that need to be checked to see that they have had trace
>>> + # info collected in AUX blocks in the perf data. This will go
>>> + # through all the TID's that are listed as CID=0xabcdef and see
>>> + # that all the Thread IDs the test tool reports are in the perf
>>> + # data AUX chunks
>>> +
>>> + # The TID test tools will print a TID per stdout line that are being
>>> + # tested
>>> + TIDS=`cat "$2"`
>>> + # Scan the perf report to find the TIDs that are actually CID in hex
>>> + # and build a list of the ones found
>>> + FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
>>> + grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
>>> + uniq | sort | uniq`
>>> +
>>> + # Iterate over the list of TIDs that the test says it has and find
>>> + # them in the TIDs found in the perf report
>>> + MISSING=""
>>> + for TID2 in $TIDS; do
>>> + FOUND=""
>>> + for TIDHEX in $FOUND_TIDS; do
>>> + TID=`printf "%i" $TIDHEX`
>>> + if test "$TID" -eq "$TID2"; then
>>> + FOUND="y"
>>> + break
>>> + fi
>>> + done
>>> + if test -z "$FOUND"; then
>>> + MISSING="$MISSING $TID"
>>> + fi
>>> + done
>>> + if test -n "$MISSING"; then
>>> + err "Thread IDs $MISSING not found in perf AUX data"
>>> + fi
>>> +}
>>> diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
>>> new file mode 100644
>>> index 000000000000..c7ada20922fd
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/tools/Makefile
>>> @@ -0,0 +1,26 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +include ../../../../../tools/scripts/Makefile.include
>>> +include ../../../../../tools/scripts/Makefile.arch
>>> +include ../../../../../tools/scripts/utilities.mak
>>
>> To be honest, I don't understand well for perf's build and config
>> system. Seems to me, a good example for building program is jevents.
>>
>> Please take a look for the code:
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/perf/Makefile.perf#n667
>>
>> If follow the same method with jevents for building test programs,
>> I can see one benefit is we don't need to create a Makefile, on the
>> other hand, we can reuse the perf's build system and simply create a
>> Build file under the folder tools/perf/tests/shell/.../coresight/.
>>
>>> +
>>> +SUBDIRS = \
>>> + coresight
>>> +
>>> +all: $(SUBDIRS)
>>> +$(SUBDIRS):
>>> + $(Q)$(MAKE) -C $@
>>> +
>>> +INSTALLDIRS = $(SUBDIRS:%=install-%)
>>> +
>>> +install-tests: all $(INSTALLDIRS)
>>> +$(INSTALLDIRS):
>>> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
>>> +
>>> +CLEANDIRS = $(SUBDIRS:%=clean-%)
>>> +
>>> +clean: $(CLEANDIRS)
>>> +$(CLEANDIRS):
>>> + $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
>>> +
>>> +.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
>>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
>>> new file mode 100644
>>> index 000000000000..723006ea827c
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
>>> @@ -0,0 +1,27 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +include ../../../../../../tools/scripts/Makefile.include
>>> +include ../../../../../../tools/scripts/Makefile.arch
>>> +include ../../../../../../tools/scripts/utilities.mak
>>> +
>>> +SUBDIRS = \
>>> + asm_pure_loop
>>> +
>>> +all: $(SUBDIRS)
>>> +$(SUBDIRS):
>>> + $(Q)$(MAKE) -C $@
>>> +
>>> +INSTALLDIRS = $(SUBDIRS:%=install-%)
>>> +
>>> +install-tests: $(INSTALLDIRS)
>>> +$(INSTALLDIRS):
>>> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
>>> +
>>> +CLEANDIRS = $(SUBDIRS:%=clean-%)
>>> +
>>> +clean: $(CLEANDIRS)
>>> +$(CLEANDIRS):
>>> + $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
>>> +
>>> +.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
>>> +
>>> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>>> new file mode 100644
>>> index 000000000000..cedd26c6a0eb
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
>>> @@ -0,0 +1,23 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +
>>> +ifndef DESTDIR
>>> +prefix ?= $(HOME)
>>> +endif
>>> +
>>> +DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
>>> +perfexecdir = libexec/perf-core
>>> +perfexec_instdir = $(perfexecdir)
>>> +
>>> +ifneq ($(filter /%,$(firstword $(perfexecdir))),)
>>> +perfexec_instdir = $(perfexecdir)
>>> +else
>>> +perfexec_instdir = $(prefix)/$(perfexecdir)
>>> +endif
>>> +
>>> +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
>>> +INSTALL = install
>>> +
>>> +include ../../../../../../scripts/Makefile.include
>>> +include ../../../../../../scripts/Makefile.arch
>>> +include ../../../../../../scripts/utilities.mak
>>
>> As suggested above, if we refer the building method of jevent, I think
>> this Makefile.miniconfig is not needed anymore.
>>
>>> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>>> new file mode 100644
>>> index 000000000000..10c5a60cb71c
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
>>> @@ -0,0 +1,30 @@
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# Carsten Haitzler <[email protected]>, 2021
>>> +
>>> +include ../Makefile.miniconfig
>>> +
>>> +BIN=asm_pure_loop
>>> +LIB=
>>> +
>>> +all: $(BIN)
>>> +
>>> +$(BIN): $(BIN).S
>>> +ifdef CORESIGHT
>>> +ifeq ($(ARCH),arm64)
>>> + $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
>>> +endif
>>> +endif
>>> +
>>> +install-tests: all
>>> +ifdef CORESIGHT
>>> +ifeq ($(ARCH),arm64)
>>> + $(call QUIET_INSTALL, tests) \
>>> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
>>> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
>>> +endif
>>> +endif
>>> +
>>> +clean:
>>> + $(Q)$(RM) -f $(BIN)
>>> +
>>> +.PHONY: all clean install-tests
>>> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>>> new file mode 100644
>>> index 000000000000..262876451021
>>> --- /dev/null
>>> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>>> @@ -0,0 +1,28 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/* Tamas Zsoldos <[email protected]>, 2021 */
>>> +
>>> +.globl _start
>>> +_start:
>>> + mov x0, 0x000fffff
>>> + mov x1, xzr
>>> +loop:
>>> + nop
>>> + nop
>>> + cbnz x1, noskip
>>> + nop
>>> + nop
>>> + adrp x2, skip
>>> + add x2, x2, :lo12:skip
>>> + br x2
>>> + nop
>>> + nop
>>> +noskip:
>>> + nop
>>> + nop
>>> +skip:
>>> + sub x0, x0, 1
>>> + cbnz x0, loop
>>> +
>>> + mov x0, #0
>>> + mov x8, #93 // __NR_exit syscall
>>> + svc #0
>>
>> I verified this code on Arm64 machine and it works!
>>
>> I am a bit worry about the code for using the hard code number for
>> system call. Another option is to use the inline assembly
>> in C code, I think you have considered for this approach, this might
>> introduce noise for extra branch instructions during the testing,
>> but it can allow us to program standard C program (and don't worry
>> about the program exiting).
>>
>> If you think using assembly code is better than inline assembly, it
>> would be fine for me. Eventually, the system call number is very
>> seldomly to be changed.
>>
>> Thanks,
>> Leo
>

2022-01-12 09:54:20

by Leo Yan

[permalink] [raw]
Subject: Re: [PATCH 07/12] perf test: Add simple bubblesort test for coresight aux data

Hi Carsten,

On Tue, Jan 04, 2022 at 03:13:08PM +0000, Carsten Haitzler wrote:
> On 1/3/22 08:00, Leo Yan wrote:

[...]

> > Furthermore, I expect the bubble sort is to be used for testing the
> > CoreSight configuration, e.g. it can be used to test for the strobing
> > mode (and for validation AutoFDO).
> >
> > How about you think for this?
>
> I actually didn't include any autofdo testing as this was mostly a matter of
> tooling after you have collected a trace. Run through the trace data and
> then build up a good image of the execution of the target and that would
> probably belong in tooling outside of the kernel. The idea here was to see
> if we do collect sufficient amounts of data and that the data looks "sane".

Yeah, this is consistent with what Suzuki told me that the main target
of this patch set is to verify the CoreSight trace data quality.

> This is all about looking to see if we only get a single block or only 2 or
> 3 blocks then it stops or no blocks and then with various stresses on kernel
> (memory heavy, cpu heavy) to see if anything will greatly affect this.
>
> The bubble sort does allow a basis to build some fdo tests on, but having a
> baseline of "does it collect data at all" to start with is a good call. I
> had not tested the strobing yet as that was probably another phase in this.
> Most of this was about getting the core infrastructure in to be able to add
> lots of little test tools we can run and the harnesses to run them and
> collect statistical data over time.
>
> Just a side note - the asm loop is arm64 specific and thus it's good for
> testing an exact result from, but bubble sort is portable. It would allow us
> to use this for an Arm 64 platform like the Morello board. I've been
> keeping in mind "be somewhat portable" for this reason.
>
> The only downside of keeping this test I think is that the whole test suite
> takes a bit longer to run. Is this sufficient a concern to remove this test
> from the patchset given the above?

So my essential purpose is to condense test cases as possible :)

For example, although the Arm64 asm loop case and the bubble sort case
have different execution flows, both of them actually are to verify
verify a complete process with CoreSight trace data recording and
reporting (so covers CoreSight driver, perf tool and OpenCSD lib).
Since we can pass different loop number to a test program, e.g. we
already have one case to test very small trace data with Arm64 asm
loop, why we still need the test case of bubble soring with small
array? Seems to me that more cases are not bad thing, but if both
case work on the same integration flow, I personally think these two
cases cannot give us significant benefit rather than single case.


Throughout the whole patch set, my another concern is some test cases
are platform dependent. E.g. if mainline kernel contains these test
cases and later a developer reports a test case failure, it's difficult
for us to figure out whether the failure is caused by the platform
factors (e.g. memory usage, timeout, etc), or it's a good exposing for
any issue in software components.

So for a test case requiring very small resources, we can set a strict
criteria, for a test case with big chunk trace data, we can report a
percentage value as the profiling quality metrics (e.g. we expect 1000
branch samples, but the result only contains 100 branch samples, so we
can output the quality metrics as 100 / 1000 = 10%). This can allow us
to easily conclude that the underlying mechanism works well, but the
profiling quality is bad caused by losing tracing data. In other
word, we can convert the quality result from binary format to a
range value [0% .. 100%].

Thanks,
Leo

2022-01-21 19:50:06

by James Clark

[permalink] [raw]
Subject: Re: [PATCH 12/12] perf test: Add docs for coresight and related tests



On 15/12/2021 16:04, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This adds documentation about the coresight specific tests as part of
> perf test
>
> Signed-off-by: Carsten Haitzler <[email protected]>

I will use this commit to comment on the set as a whole. The other comments about
specific issues I have left inline.

I ran the tests twice on N1SDP (kernel version perf/core 48ffaedf017ad) and had two
different sets of failures, indicating some flakyness, which is one reason to not have
tests with magic numbers as Leo has raised. Are you able to give a complete list of
where you have run these so far? I know we can't check everywhere, but at least all
of Arm's own reference platforms should be passing.

First run:

92: Coresight / Thread Loop 25 Threads : FAILED!
94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
97: Coresight / Unroll Loop Thread 1 : FAILED!
99: Coresight / Unroll Loop Thread 2 : FAILED!

Second run:

92: Coresight / Thread Loop 25 Threads : FAILED!
94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
97: Coresight / Unroll Loop Thread 1 : FAILED!

I have pasted the verbose output of two of these at the very end.

The major problem I have with the tests is the time that they take to run. Now
a full test run takes 31m+ on N1SDP, where previously it took 1m 9s. There are
quite a few reasons why this isn't a good idea. It will take extra cycles on
anyone's CI and that means it will now take longer for anyone to make any changes
if they run the tests, slowing down all Perf work from now onward. Even if you
want to run just the Coresight tests, it doesn't really help as that is 90% of
the time taken, so personally for me I'm not likely to run them while working on
Coresight changes. The longer the tests take the more likely it is that they are
skipped, reducing the benefits of the tests. Also if anyone has timeouts set on
CI these are likely going to have to be adjusted now.

Is it possible to get the run time of each test down to 5-10 seconds? This will
make it much nicer for us to work with going forwards.

I'd also have liked to have had a discussion on the mailing list about what the test
methodology should be in general before starting. For example for this patch set it
looks like the coverage is quite wide because of the number of tests and time it
takes to run, but actually they all use "cs_etm//u -- <process>" as the run command.
This only tests per-process userspace mode resulting in very narrow coverage.
And there is no mention in a cover letter about how this expands on or interacts
with the existing test_arm_coresight.sh test which I don't think can be ignored.
For example it iterates over sinks. Could that same iteration not be applied to
these tests? They seem to exist in isolation and it's not clear which one we should
be adding to going forwards.

I'd like to see a much more exploration of the different modes and flags to justify
such a high run time:

* per-CPU
* per-thread
* with and without timestamps
* strobing

If this is supposed to be just an initial implementation covering one case, then
by the "test one thing" ethos, there should only be one test case. Each case
should be testing one thing with minimal overlapping. But it looks like tests like
"Thread loop 10" and "thread loop 250" just test the same thing, and I don't see
the value in maintaining that. Also "bubblesort" and "memcpy" don't have comments
explaining why running on those two different test programs actually makes a
difference. Obviously this comment is partially related to the run time, if it was
shorter perhaps it would be less important how many variations we ran.

It's also not clear what failure modes the tests are looking for. There are
comments like "We should almost always see F3 atoms", but it's not clear how
F3 atoms are a signal of a high quality trace. And there are numbers like:

perf_dump_aux_verify "$DATA" 66 6 6
perf_dump_aux_verify "$DATA" 4188 1630 1630

but there are no comments to say how 66 or 4188 were judged to be "high quality" vs
any other number. This means that anyone encountering a failure is just going to
change the number until it passes, undoing any value that the test added. If the tests
are looking for complete loss of data, then > 1 or > 2 would be sufficient. But if
someone makes a mistake in the driver to produce less data, then these tests aren't
going to catch that anyway, since there is a chance that it falls within the allowed
thresholds.

In my opinion a much better measure of quality would be to look at the coverage of
fully decoded trace, for example if you have 10 functions called from a loop across
multiple DSOs, do each of those functions show up in synthesised instruction samples.

Which brings me to my next point, the tests only seem to look at the raw trace, rather
than the synthesised samples. To me this seems like it's validating what comes out of
the CPU more than looking at what the driver or userspace Perf are doing. I think this
isn't the right place for these tests to live and would be better suited to run on bare
metal. This is because a user isn't going to be interested in how many F3 atoms there are,
that's just an implementation detail. What's much more valuable is what samples are
synthesised. We're also skipping most of the code in Perf by only looking at the raw
trace, which makes it harder to justify putting the tests in the Perf code base.

In short I think it would be much better if we had the following:

* Much shorter run time
* Run each test program only once (for example it doesn't add value to run memcpy with different sizes)
* Only one test for each thing/failure mode
* Much less overlapping test code (for example F3 atoms only need to be counted for one test, not all of them)
* Concrete descriptions of failure modes and what each test is looking for
* Small magic numbers which are easy to justify (like "samples < 1, check for complete loss of data")
* Run through the full Perf pipeline and look at the synthesised samples rather than raw trace
* Some thought about how this fits in with test_arm_coresight.sh

Thanks
James



Test failure outputs:
---

94: Coresight / Thread Loop 10 Threads - Check TID :
--- start ---
test child forked, pid 5821
Couldn't synthesize bpf events.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 128.106 MB ./perf-thread_loop-check-tid-10th.data ]



Warning:
AUX data lost 1 times out of 1!

Thread IDs not found in perf AUX data
test child finished with -1
---- end ----
Coresight / Thread Loop 10 Threads - Check TID: FAILED!

========================================================


92: Coresight / Thread Loop 25 Threads :
--- start ---
test child forked, pid 5871
Couldn't synthesize bpf events.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 28.849 MB ./perf-thread_loop-25th.data ]
Sanity check number of ATOM_F3 is too low (92062 < 388121)
test child finished with -1
---- end ----
Coresight / Thread Loop 25 Threads: FAILED!


> ---
> MAINTAINERS | 1 +
> tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
> 2 files changed, 141 insertions(+)
> create mode 100644 tools/perf/Documentation/arm-coresight.txt
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d46e8469c467..1a93977a0132 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
> F: drivers/hwtracing/coresight/*
> F: include/dt-bindings/arm/coresight-cti-dt.h
> F: include/linux/coresight*
> +F: tools/perf/Documentation/arm-coresight.txt
> F: tools/perf/arch/arm/util/auxtrace.c
> F: tools/perf/arch/arm/util/cs-etm.c
> F: tools/perf/arch/arm/util/cs-etm.h
> diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
> new file mode 100644
> index 000000000000..3a9e6c573c58
> --- /dev/null
> +++ b/tools/perf/Documentation/arm-coresight.txt
> @@ -0,0 +1,140 @@
> +Arm Coresight Support
> +=====================
> +
> +Coresight is a feature of some Arm based processors that allows for
> +debugging. One of the things it can do is trace every instruction
> +executed and remotely expose that information in a hardware compressed
> +stream. Perf is able to locally access that stream and store it to the
> +output perf data files. This stream can then be later decoded to give the
> +instructions that were traced for debugging or profiling purposes. You
> +can log such data with a perf record command like:
> +
> + perf record -e cs_etm//u testbinary
> +
> +This would run some test binary (testbinary) until it exits and record
> +a perf.data trace file. That file would have AUX sections if coresight
> +is working correctly. You can dump the content of this file as
> +readable text with a command like:
> +
> + perf report --stdio --dump -i perf.data
> +
> +You should find some sections of this file have AUX data blocks like:
> +
> + 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
> +
> + . ... CoreSight ETM Trace data: size 73168 bytes
> + Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
> + Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
> + Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
> + Idx:26; ID:10; I_TRACE_ON : Trace On.
> + Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
> + Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> + Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> + Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> + Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
> + ...
> +
> +If you see these above, then your system is tracing coresight data
> +correctly.
> +
> +To compile perf with coresight support in the perf directory do
> +
> + make CORESIGHT=1
> +
> +This will compile the perf tool with coresight support as well as
> +build some small test binaries for perf test. This requires you also
> +be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
> +perf coresight tracing are in tests/shell/tools/coresight.
> +
> +You will also want coresight support enabled in your kernel config.
> +Ensure it is enabled with:
> +
> + CONFIG_CORESIGHT=y
> +
> +There are various other coresight options you probably also want
> +enabled like:
> +
> + CONFIG_CORESIGHT_LINKS_AND_SINKS=y
> + CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
> + CONFIG_CORESIGHT_CATU=y
> + CONFIG_CORESIGHT_SINK_TPIU=y
> + CONFIG_CORESIGHT_SINK_ETBV10=y
> + CONFIG_CORESIGHT_SOURCE_ETM4X=y
> + CONFIG_CORESIGHT_STM=y
> + CONFIG_CORESIGHT_CPU_DEBUG=y
> + CONFIG_CORESIGHT_CTI=y
> + CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
> +
> +Please refer to the kernel configuration help for more information.
> +
> +Perf test - Verify kernel and userspace perf coresight work
> +===========================================================
> +
> +When you run perf test, it will do a lot of self tests. Some of those
> +tests will cover Coresight (only if enabled and on ARM64). You
> +generally would run perf test from the tools/perf directory in the
> +kernel tree. Some tests will check some internal perf support like:
> +
> + Check Arm CoreSight trace data recording and synthesized samples
> +
> +Some others will actually use perf record and some test binaries that
> +are in tests/shell/tools/coresight and will collect traces to ensure a
> +minimum level of functionality is met. The scripts that launch these
> +tests are in tests/shell. These will all look like:
> +
> + Coresight / Memcpy 1M 25 Threads
> + Coresight / Unroll Loop Thread 2
> + ...
> +
> +These perf record tests will not run if the tool binaries do not exist
> +in tests/shell/tools/coresight/*/ and will be skipped. If you do not
> +have coresight support in hardware then either do not build perf with
> +coresight support or remove these binaries in order to not have these
> +tests fail and have them skip instead.
> +
> +These tests will log historical results in the current working
> +directory (e.g. tools/perf) and will be named stats-*.csv like:
> +
> + stats-asm_pure_loop-out.csv
> + stats-bubble_sort-random.csv
> + ...
> +
> +These statistic files log some aspects of the AUX data sections in
> +the perf data output counting some numbers of certain encodings (a
> +good way to know that it's working in a very simple way). One problem
> +with coresight is that given a large enough amount of data needing to
> +be logged, some of it can be lost due to the processor not waking up
> +in time to read out all the data from buffers etc.. You will notice
> +that the amount of data collected can vary a lot per run of perf test.
> +If you wish to see how this changes over time, simply run perf test
> +multiple times and all these csv files will have more and more data
> +appended to it that you can later examine, graph and otherwise use to
> +figure out if things have become worse or better.
> +
> +Be aware that amny of these tests take quite a while to run, specifically
> +in processing the perf data file and dumping contents to then examine what
> +is inside.
> +
> +You can change where these csv logs are stored by setting the
> +PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
> +test like:
> +
> + export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
> + perf test
> +
> +They will also store resulting perf output data in the current
> +directory for later inspection like:
> +
> + perf-memcpy-1m.data
> + perf-thread_loop-2th.data
> + ...
> +
> +You can alter where the perf data files are stored by setting the
> +PERF_TEST_CORESIGHT_DATADIR environment variable such as:
> +
> + PERF_TEST_CORESIGHT_DATADIR=/var/tmp
> + perf test
> +
> +You may wish to set these above environment variables if you which to
> +keep the output of tests outside of the current working directory for
> +longer term storage and examination.
>

2022-01-21 19:52:08

by James Clark

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight



On 15/12/2021 16:03, [email protected] wrote:
> From: Carsten Haitzler <[email protected]>
>
> This adds the initial test harness to run perf record and examine the
> resuling output when coresight is enabled on arm64 and check the
> resulting quality of the output as part of perf test.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
[...]
> diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> new file mode 100755
> index 000000000000..542d4a37e349
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / ASM Pure Loop
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="asm_pure_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS=""
> +DATV="out"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 2601 334 334
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
> new file mode 100644
> index 000000000000..cd6c1283e6f5
> --- /dev/null
> +++ b/tools/perf/tests/shell/lib/coresight.sh
> @@ -0,0 +1,130 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +# This is sourced from a driver script so no need for #!/bin... etc. at the
> +# top - the assumption below is that it runs as part of sourcing after the
> +# test sets up some basic env vars to say what it is.
> +
> +# perf record options for the perf tests to use
> +PERFRECMEM="-m ,128M"
> +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
> +
> +# These tests need to be run as root or coresight won't allow large buffers
> +# and will not collect proper data

I've somewhat fixed this with the change 7cc9680c4be. Can you re-test that it
works without sudo? I think it's best to avoid it unless necessary and the
cs_etm//u seems to suggest that it's not necessary.

If 'proper data' can't be collected without root then it seems more like the
tests have found a real issue to fix rather than something to be worked around.

James

2022-02-01 20:48:06

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 12/12] perf test: Add docs for coresight and related tests

Hi James

You've found indeed that the tests are for checking if we're even
exporting any kind of sane data from the system into perf data files.
The point of this was not to test all of the openocd decoding path and
to see if, given a perf trace of sufficient completeness, that we can do
something sensible (autofdo, coverage etc.). These involve much more
complex decoding on the other end of "we have a perf.data file... let's
use it". This is all about checking we get perf data files that contain
somewhat sane content. Does our ""sandwich" have bread at either end and
some kind of filling in the middle?"

It does appear that we have bugs. These tests seem to show it. We
regularly fail the TID checks where we provide ZERO blocks of data for
some threads that run for an extended period of time. This repeats
itself across various other tests.

I chose 3 specific things to probe for in the test data - the sync
"headers" which we get every now and again in the stream to see we're
producing some data at all. Trace info will tell us more - like what
thread/pid and we should get at least enough of these to cover every
thread we might run if we have long-lived threads running for a while.
Perf data is a lossy matter here - we can't guarantee we always collect
everything. This is why the tests also store the numbers they collect
over multiple runs in csv files so it is possible over the long term to
track the quality of data statistically. The documentation I added in
the patch set covers this. The F3 atoms were simply the filling in the
sandwich - is there content other than the "structure" of info/sync. I
could have picked any ATOM_Fx there. As long as there is something
there, we're collecting some amount of actual execution content.

The idea is that over time when these issues are fixed, we will see more
of these tests pass more often and the csv data they collect should show
a jump (on average in the long run) of data collected. Yes - the numbers
in the tests are a bit "magical" but they can't be derived or calculated
exactly as they will depend on the instructions a compiler may product
for a binary as well as other system factors (races). The numbers I
chose were a result of actually running the tests and collecting data
and e.g. deciding "if we collect at least 20% of the lowest numbers I
see, then we're got a pass". It's the same idea in any qualitative test
- you decide that some value is a passing grade. Of course I could be
very lenient and just have all the numbers be "1" (at least get one of
each) and that is about the only derivable value we could agree on is a
true minimum.

Coverage will suffer the same problem - it will sometimes happen you
will get no coverage. Eg.g the thread tests above. IF I formulated them
with a different function per thread and used coverage to figure out
which threads reported no data - we'd then need to have the coverage be
100% to pass and we'd be failing right now.

You are right that perhaps I added too many tests to cover different
paths (it's unusual that people are unhappy with too many tests and want
fewer :)), but I see the point of "it takes too long to run" and I can
certainly trim the tests down.

I've been running on my dragonboard 845 and they don't all pass for me
either - as above. 95%+ of the test time is spent dumping the perf.data
file and parsing out the coresight traces. It's not that fast. I did
quickly look into running perf on perf (seeing if there were some
blindingly obvious hotspots somewhere to fix) but didn't see anything
jump out at me. Collecting less data of course speeds it up and that's
easy to tweak. I could definitely speed things up if I had the checker
stop parsing the dump output once we had "enough of item X" (I_ASYNC,
I_TRACE_INFO) which would certainly speed things up. Lowering those
numbers to bare minimums would make it a lot faster but it would
probably have issues with the TID checks as I'd like to give the system
enough time to plausibly collect some data on every thread.

The multiple tests with different threads were there to ensure even on
many-core system we can saturate all cores to see we are context
switching between threads and then still capturing data on all cores.
The point of these tests is to stress-test and not just "bare minimum -
do we get something" and they certainly seem to find problems in the
process. I built them so it'd be easy to just drop more tests and tools
into directories and expand on over time to improve quality of things
covered. The bubble sort tests were ones that were being used for perf
quality tests already internally in their own separate git repo, so I
included them. I can remove them of course as they probably don't
provide any value over other simpler tests.

Testing the pipeline AFTER collecting some sensible data to see if we
can decode it and e.g. apply it to fdo or coverage is a separate set of
tests which this was not meant to address (at this stage). Those tests
certainly do not fit the same pattern as these which follow a simple
design patter of build N test tools, run those test tools and collect
data, check the data is semi-sane and seemingly collecting what it should.

So I can:

* Trim the number of tests down
* Fewer versions of the same one
* Drop the sorts
* Optimize time spent checking data (bail early when minimum reached)

On 1/19/22 16:43, James Clark wrote:
>
>
> On 15/12/2021 16:04, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds documentation about the coresight specific tests as part of
>> perf test
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>
> I will use this commit to comment on the set as a whole. The other comments about
> specific issues I have left inline.
>
> I ran the tests twice on N1SDP (kernel version perf/core 48ffaedf017ad) and had two
> different sets of failures, indicating some flakyness, which is one reason to not have
> tests with magic numbers as Leo has raised. Are you able to give a complete list of
> where you have run these so far? I know we can't check everywhere, but at least all
> of Arm's own reference platforms should be passing.
>
> First run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!
> 99: Coresight / Unroll Loop Thread 2 : FAILED!
>
> Second run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!
>
> I have pasted the verbose output of two of these at the very end.
>
> The major problem I have with the tests is the time that they take to run. Now
> a full test run takes 31m+ on N1SDP, where previously it took 1m 9s. There are
> quite a few reasons why this isn't a good idea. It will take extra cycles on
> anyone's CI and that means it will now take longer for anyone to make any changes
> if they run the tests, slowing down all Perf work from now onward. Even if you
> want to run just the Coresight tests, it doesn't really help as that is 90% of
> the time taken, so personally for me I'm not likely to run them while working on
> Coresight changes. The longer the tests take the more likely it is that they are
> skipped, reducing the benefits of the tests. Also if anyone has timeouts set on
> CI these are likely going to have to be adjusted now.
>
> Is it possible to get the run time of each test down to 5-10 seconds? This will
> make it much nicer for us to work with going forwards.
>
> I'd also have liked to have had a discussion on the mailing list about what the test
> methodology should be in general before starting. For example for this patch set it
> looks like the coverage is quite wide because of the number of tests and time it
> takes to run, but actually they all use "cs_etm//u -- <process>" as the run command.
> This only tests per-process userspace mode resulting in very narrow coverage.
> And there is no mention in a cover letter about how this expands on or interacts
> with the existing test_arm_coresight.sh test which I don't think can be ignored.
> For example it iterates over sinks. Could that same iteration not be applied to
> these tests? They seem to exist in isolation and it's not clear which one we should
> be adding to going forwards.
>
> I'd like to see a much more exploration of the different modes and flags to justify
> such a high run time:
>
> * per-CPU
> * per-thread
> * with and without timestamps
> * strobing
>
> If this is supposed to be just an initial implementation covering one case, then
> by the "test one thing" ethos, there should only be one test case. Each case
> should be testing one thing with minimal overlapping. But it looks like tests like
> "Thread loop 10" and "thread loop 250" just test the same thing, and I don't see
> the value in maintaining that. Also "bubblesort" and "memcpy" don't have comments
> explaining why running on those two different test programs actually makes a
> difference. Obviously this comment is partially related to the run time, if it was
> shorter perhaps it would be less important how many variations we ran.
>
> It's also not clear what failure modes the tests are looking for. There are
> comments like "We should almost always see F3 atoms", but it's not clear how
> F3 atoms are a signal of a high quality trace. And there are numbers like:
>
> perf_dump_aux_verify "$DATA" 66 6 6
> perf_dump_aux_verify "$DATA" 4188 1630 1630
>
> but there are no comments to say how 66 or 4188 were judged to be "high quality" vs
> any other number. This means that anyone encountering a failure is just going to
> change the number until it passes, undoing any value that the test added. If the tests
> are looking for complete loss of data, then > 1 or > 2 would be sufficient. But if
> someone makes a mistake in the driver to produce less data, then these tests aren't
> going to catch that anyway, since there is a chance that it falls within the allowed
> thresholds.
>
> In my opinion a much better measure of quality would be to look at the coverage of
> fully decoded trace, for example if you have 10 functions called from a loop across
> multiple DSOs, do each of those functions show up in synthesised instruction samples.
>
> Which brings me to my next point, the tests only seem to look at the raw trace, rather
> than the synthesised samples. To me this seems like it's validating what comes out of
> the CPU more than looking at what the driver or userspace Perf are doing. I think this
> isn't the right place for these tests to live and would be better suited to run on bare
> metal. This is because a user isn't going to be interested in how many F3 atoms there are,
> that's just an implementation detail. What's much more valuable is what samples are
> synthesised. We're also skipping most of the code in Perf by only looking at the raw
> trace, which makes it harder to justify putting the tests in the Perf code base.
>
> In short I think it would be much better if we had the following:
>
> * Much shorter run time
> * Run each test program only once (for example it doesn't add value to run memcpy with different sizes)
> * Only one test for each thing/failure mode
> * Much less overlapping test code (for example F3 atoms only need to be counted for one test, not all of them)
> * Concrete descriptions of failure modes and what each test is looking for
> * Small magic numbers which are easy to justify (like "samples < 1, check for complete loss of data")
> * Run through the full Perf pipeline and look at the synthesised samples rather than raw trace
> * Some thought about how this fits in with test_arm_coresight.sh
>
> Thanks
> James
>
>
>
> Test failure outputs:
> ---
>
> 94: Coresight / Thread Loop 10 Threads - Check TID :
> --- start ---
> test child forked, pid 5821
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 128.106 MB ./perf-thread_loop-check-tid-10th.data ]
>
>
>
> Warning:
> AUX data lost 1 times out of 1!
>
> Thread IDs not found in perf AUX data
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 10 Threads - Check TID: FAILED!
>
> ========================================================
>
>
> 92: Coresight / Thread Loop 25 Threads :
> --- start ---
> test child forked, pid 5871
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 28.849 MB ./perf-thread_loop-25th.data ]
> Sanity check number of ATOM_F3 is too low (92062 < 388121)
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 25 Threads: FAILED!
>
>
>> ---
>> MAINTAINERS | 1 +
>> tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
>> 2 files changed, 141 insertions(+)
>> create mode 100644 tools/perf/Documentation/arm-coresight.txt
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d46e8469c467..1a93977a0132 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
>> F: drivers/hwtracing/coresight/*
>> F: include/dt-bindings/arm/coresight-cti-dt.h
>> F: include/linux/coresight*
>> +F: tools/perf/Documentation/arm-coresight.txt
>> F: tools/perf/arch/arm/util/auxtrace.c
>> F: tools/perf/arch/arm/util/cs-etm.c
>> F: tools/perf/arch/arm/util/cs-etm.h
>> diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
>> new file mode 100644
>> index 000000000000..3a9e6c573c58
>> --- /dev/null
>> +++ b/tools/perf/Documentation/arm-coresight.txt
>> @@ -0,0 +1,140 @@
>> +Arm Coresight Support
>> +=====================
>> +
>> +Coresight is a feature of some Arm based processors that allows for
>> +debugging. One of the things it can do is trace every instruction
>> +executed and remotely expose that information in a hardware compressed
>> +stream. Perf is able to locally access that stream and store it to the
>> +output perf data files. This stream can then be later decoded to give the
>> +instructions that were traced for debugging or profiling purposes. You
>> +can log such data with a perf record command like:
>> +
>> + perf record -e cs_etm//u testbinary
>> +
>> +This would run some test binary (testbinary) until it exits and record
>> +a perf.data trace file. That file would have AUX sections if coresight
>> +is working correctly. You can dump the content of this file as
>> +readable text with a command like:
>> +
>> + perf report --stdio --dump -i perf.data
>> +
>> +You should find some sections of this file have AUX data blocks like:
>> +
>> + 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
>> +
>> + . ... CoreSight ETM Trace data: size 73168 bytes
>> + Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
>> + Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
>> + Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
>> + Idx:26; ID:10; I_TRACE_ON : Trace On.
>> + Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
>> + Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
>> + ...
>> +
>> +If you see these above, then your system is tracing coresight data
>> +correctly.
>> +
>> +To compile perf with coresight support in the perf directory do
>> +
>> + make CORESIGHT=1
>> +
>> +This will compile the perf tool with coresight support as well as
>> +build some small test binaries for perf test. This requires you also
>> +be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
>> +perf coresight tracing are in tests/shell/tools/coresight.
>> +
>> +You will also want coresight support enabled in your kernel config.
>> +Ensure it is enabled with:
>> +
>> + CONFIG_CORESIGHT=y
>> +
>> +There are various other coresight options you probably also want
>> +enabled like:
>> +
>> + CONFIG_CORESIGHT_LINKS_AND_SINKS=y
>> + CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
>> + CONFIG_CORESIGHT_CATU=y
>> + CONFIG_CORESIGHT_SINK_TPIU=y
>> + CONFIG_CORESIGHT_SINK_ETBV10=y
>> + CONFIG_CORESIGHT_SOURCE_ETM4X=y
>> + CONFIG_CORESIGHT_STM=y
>> + CONFIG_CORESIGHT_CPU_DEBUG=y
>> + CONFIG_CORESIGHT_CTI=y
>> + CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
>> +
>> +Please refer to the kernel configuration help for more information.
>> +
>> +Perf test - Verify kernel and userspace perf coresight work
>> +===========================================================
>> +
>> +When you run perf test, it will do a lot of self tests. Some of those
>> +tests will cover Coresight (only if enabled and on ARM64). You
>> +generally would run perf test from the tools/perf directory in the
>> +kernel tree. Some tests will check some internal perf support like:
>> +
>> + Check Arm CoreSight trace data recording and synthesized samples
>> +
>> +Some others will actually use perf record and some test binaries that
>> +are in tests/shell/tools/coresight and will collect traces to ensure a
>> +minimum level of functionality is met. The scripts that launch these
>> +tests are in tests/shell. These will all look like:
>> +
>> + Coresight / Memcpy 1M 25 Threads
>> + Coresight / Unroll Loop Thread 2
>> + ...
>> +
>> +These perf record tests will not run if the tool binaries do not exist
>> +in tests/shell/tools/coresight/*/ and will be skipped. If you do not
>> +have coresight support in hardware then either do not build perf with
>> +coresight support or remove these binaries in order to not have these
>> +tests fail and have them skip instead.
>> +
>> +These tests will log historical results in the current working
>> +directory (e.g. tools/perf) and will be named stats-*.csv like:
>> +
>> + stats-asm_pure_loop-out.csv
>> + stats-bubble_sort-random.csv
>> + ...
>> +
>> +These statistic files log some aspects of the AUX data sections in
>> +the perf data output counting some numbers of certain encodings (a
>> +good way to know that it's working in a very simple way). One problem
>> +with coresight is that given a large enough amount of data needing to
>> +be logged, some of it can be lost due to the processor not waking up
>> +in time to read out all the data from buffers etc.. You will notice
>> +that the amount of data collected can vary a lot per run of perf test.
>> +If you wish to see how this changes over time, simply run perf test
>> +multiple times and all these csv files will have more and more data
>> +appended to it that you can later examine, graph and otherwise use to
>> +figure out if things have become worse or better.
>> +
>> +Be aware that amny of these tests take quite a while to run, specifically
>> +in processing the perf data file and dumping contents to then examine what
>> +is inside.
>> +
>> +You can change where these csv logs are stored by setting the
>> +PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
>> +test like:
>> +
>> + export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
>> + perf test
>> +
>> +They will also store resulting perf output data in the current
>> +directory for later inspection like:
>> +
>> + perf-memcpy-1m.data
>> + perf-thread_loop-2th.data
>> + ...
>> +
>> +You can alter where the perf data files are stored by setting the
>> +PERF_TEST_CORESIGHT_DATADIR environment variable such as:
>> +
>> + PERF_TEST_CORESIGHT_DATADIR=/var/tmp
>> + perf test
>> +
>> +You may wish to set these above environment variables if you which to
>> +keep the output of tests outside of the current working directory for
>> +longer term storage and examination.
>>

2022-02-04 11:57:57

by Mike Leach

[permalink] [raw]
Subject: Re: [PATCH 09/12] perf test: Add add memcpy test for coresight quality checking

Hi Carsten

From a trace ouput perspective, this test doesn't really add coverage
on top of what has gone before.
We only have instruction trace - so the data operations of the memcpy
do not result in any trace output.
From a trace perspective, memcpy is a tight loop - probably resulting
in a single atom element for each iteration, and nothing in between.

For this reason, I think this test, and the threaded memcpy test in
the next patch can be dropped.

Regards

Mike

On Wed, 15 Dec 2021 at 16:04, <[email protected]> wrote:
>
> From: Carsten Haitzler <[email protected]>
>
> This adds memory bound tests for quality checking perf's aux data
> recording.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> tools/perf/tests/shell/coresight_memcpy_1m.sh | 18 +++++++++
> .../perf/tests/shell/coresight_memcpy_32m.sh | 18 +++++++++
> .../perf/tests/shell/coresight_memcpy_64k.sh | 18 +++++++++
> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
> .../shell/tools/coresight/memcpy/Makefile | 29 ++++++++++++++
> .../shell/tools/coresight/memcpy/memcpy.c | 40 +++++++++++++++++++
> 6 files changed, 125 insertions(+), 1 deletion(-)
> create mode 100755 tools/perf/tests/shell/coresight_memcpy_1m.sh
> create mode 100755 tools/perf/tests/shell/coresight_memcpy_32m.sh
> create mode 100755 tools/perf/tests/shell/coresight_memcpy_64k.sh
> create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c
>
> diff --git a/tools/perf/tests/shell/coresight_memcpy_1m.sh b/tools/perf/tests/shell/coresight_memcpy_1m.sh
> new file mode 100755
> index 000000000000..fa1c28d73b66
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_memcpy_1m.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Memcpy 1M
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="memcpy"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="1024 2"
> +DATV="1m"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 39 766 766
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_memcpy_32m.sh b/tools/perf/tests/shell/coresight_memcpy_32m.sh
> new file mode 100755
> index 000000000000..4ab5459e3824
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_memcpy_32m.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Memcpy 32M
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="memcpy"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="32768 1"
> +DATV="32m"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 39 7804 7804
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_memcpy_64k.sh b/tools/perf/tests/shell/coresight_memcpy_64k.sh
> new file mode 100755
> index 000000000000..5b6ba2a6d394
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_memcpy_64k.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Memcpy 64K
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="memcpy"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="64 40"
> +DATV="64k"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 40 934 934
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> index a1a752f45c46..99030c889b04 100644
> --- a/tools/perf/tests/shell/tools/coresight/Makefile
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -8,7 +8,8 @@ SUBDIRS = \
> asm_pure_loop \
> thread_loop \
> bubble_sort \
> - bubble_sort_thread
> + bubble_sort_thread \
> + memcpy
>
> all: $(SUBDIRS)
> $(SUBDIRS):
> diff --git a/tools/perf/tests/shell/tools/coresight/memcpy/Makefile b/tools/perf/tests/shell/tools/coresight/memcpy/Makefile
> new file mode 100644
> index 000000000000..7c31fe4ec399
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/memcpy/Makefile
> @@ -0,0 +1,29 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../Makefile.miniconfig
> +
> +BIN=memcpy
> +LIB=
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).c
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c b/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c
> new file mode 100644
> index 000000000000..1aa0617448ad
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/memcpy/memcpy.c
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Carsten Haitzler <[email protected]>, 2021
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +
> +int main(int argc, char **argv)
> +{
> + unsigned long i, len, size;
> + unsigned char *src, *dst;
> + long long v;
> +
> + if (argc < 3) {
> + printf("ERR: %s [copysize Kb] [numloops (hundreds)]\n", argv[0]);
> + exit(1);
> + }
> +
> + v = atoll(argv[1]);
> + if ((v < 1) || (v > (1024 * 1024))) {
> + printf("ERR: max memory 1GB (1048576 KB)\n");
> + exit(1);
> + }
> + size = v;
> + v = atoll(argv[2]);
> + if ((v < 1) || (v > 40000000000ll)) {
> + printf("ERR: loops 1-40000000000 (hundreds)\n");
> + exit(1);
> + }
> + len = v * 100;
> + src = malloc(size * 1024);
> + dst = malloc(size * 1024);
> + if ((!src) || (!dst)) {
> + printf("ERR: Can't allocate memory\n");
> + exit(1);
> + }
> + for (i = 0; i < len; i++)
> + memcpy(dst, src, size * 1024);
> + return 0;
> +}
> --
> 2.32.0
>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

2022-02-04 16:19:05

by Mike Leach

[permalink] [raw]
Subject: Re: [PATCH 06/12] perf test: Add tests to re-use the thread loop test to check aux data

Hi Carsten,

On Wed, 15 Dec 2021 at 16:04, <[email protected]> wrote:
>
> From: Carsten Haitzler <[email protected]>
>
> This checks to see that the thread_loop tests produces sensible
> amounts of aux coresight data.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> .../tests/shell/coresight_thread_loop_2.sh | 18 ++++++++++++++++++
> .../tests/shell/coresight_thread_loop_25.sh | 18 ++++++++++++++++++
> .../tests/shell/coresight_thread_loop_250.sh | 18 ++++++++++++++++++
> 3 files changed, 54 insertions(+)
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_2.sh
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_25.sh
> create mode 100755 tools/perf/tests/shell/coresight_thread_loop_250.sh
>
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_2.sh b/tools/perf/tests/shell/coresight_thread_loop_2.sh
> new file mode 100755
> index 000000000000..6d790b870a67
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_2.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 2 Threads
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="2 20"
> +DATV="2th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 724 11 11
> +

The only difference I can see between this test and the set of tests
in patch 05 is the verification script run on the output file.
Is there some reason that both scripts cannot be run on the same
output file, rather than rerun perf ?

Regards

Mike


> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_25.sh b/tools/perf/tests/shell/coresight_thread_loop_25.sh
> new file mode 100755
> index 000000000000..cce74202e4db
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_25.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 25 Threads
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="25 2"
> +DATV="25th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 388121 1255 1255
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_thread_loop_250.sh b/tools/perf/tests/shell/coresight_thread_loop_250.sh
> new file mode 100755
> index 000000000000..55f271462a4d
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_thread_loop_250.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Thread Loop 250 Threads
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="thread_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="250 1"
> +DATV="250th"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 724 11 11
> +
> +err=$?
> +exit $err
> --
> 2.32.0
>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

2022-02-04 22:16:51

by Mike Leach

[permalink] [raw]
Subject: Re: [PATCH 11/12] perf test: Add unrolled loop tests for coresight aux data

Hi Carsten,

Same comment here as for the memcpy tests - the unrolled loop will not
result in extra coverage. Irrespective of there being 1 add
instruction in the loop, or 100000 add instructions in the loop, the
output will be a single atom element at the end of the loop as a
result of the for() statement.

This test could also be dropped.

Regards

Mike

On Wed, 15 Dec 2021 at 16:04, <[email protected]> wrote:
>
> From: Carsten Haitzler <[email protected]>
>
> These tests have large batches of code manually unrolled with macros
> to ensure that the processor has to walk through a lot of instructions
> and memory for those instructions to generate the coresight aux data.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> .../shell/coresight_unroll_loop_thread_1.sh | 18 +++++
> .../shell/coresight_unroll_loop_thread_10.sh | 18 +++++
> .../shell/coresight_unroll_loop_thread_2.sh | 18 +++++
> .../shell/coresight_unroll_loop_thread_25.sh | 18 +++++
> .../shell/coresight_unroll_loop_thread_250.sh | 18 +++++
> .../perf/tests/shell/tools/coresight/Makefile | 3 +-
> .../coresight/unroll_loop_thread/Makefile | 29 ++++++++
> .../unroll_loop_thread/unroll_loop_thread.c | 74 +++++++++++++++++++
> 8 files changed, 195 insertions(+), 1 deletion(-)
> create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
> create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
> create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
> create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
> create mode 100755 tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
> create mode 100644 tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c
>
> diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
> new file mode 100755
> index 000000000000..9175ec532bd8
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_1.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Unroll Loop Thread 1
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="unroll_loop_thread"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="1"
> +DATV="1"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 118 14 14
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
> new file mode 100755
> index 000000000000..66cf0245294e
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_10.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Unroll Loop Thread 10
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="unroll_loop_thread"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="10"
> +DATV="10"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 127 17 17
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
> new file mode 100755
> index 000000000000..ff2e293699b0
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_2.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Unroll Loop Thread 2
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="unroll_loop_thread"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="2"
> +DATV="2"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 65 6 6
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
> new file mode 100755
> index 000000000000..7d7669a797ab
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_25.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Unroll Loop Thread 25
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="unroll_loop_thread"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="25"
> +DATV="25"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 72 26 25
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh b/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
> new file mode 100755
> index 000000000000..7a0e23aff0dc
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_unroll_loop_thread_250.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / Unroll Loop Thread 250
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="unroll_loop_thread"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS="250"
> +DATV="250"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 544 2417 2417
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> index be671aac06b8..b9cdeff1149b 100644
> --- a/tools/perf/tests/shell/tools/coresight/Makefile
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -10,7 +10,8 @@ SUBDIRS = \
> bubble_sort \
> bubble_sort_thread \
> memcpy \
> - memcpy_thread
> + memcpy_thread \
> + unroll_loop_thread
>
> all: $(SUBDIRS)
> $(SUBDIRS):
> diff --git a/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
> new file mode 100644
> index 000000000000..45ab2be8be92
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/Makefile
> @@ -0,0 +1,29 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../Makefile.miniconfig
> +
> +BIN=unroll_loop_thread
> +LIB=-pthread
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).c
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).c -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c
> new file mode 100644
> index 000000000000..cb9d22c7dfb9
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/unroll_loop_thread/unroll_loop_thread.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Carsten Haitzler <[email protected]>, 2021
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <pthread.h>
> +
> +struct args {
> + pthread_t th;
> + unsigned int in, out;
> + void *ret;
> +};
> +
> +static void *thrfn(void *arg)
> +{
> + struct args *a = arg;
> + unsigned int i, in = a->in;
> +
> + for (i = 0; i < 10000; i++) {
> + asm volatile (
> +// force an unroll of thia add instruction so we can test long runs of code
> +#define SNIP1 "add %[in], %[in], #1\n"
> +// 10
> +#define SNIP2 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1 SNIP1
> +// 100
> +#define SNIP3 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2 SNIP2
> +// 1000
> +#define SNIP4 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3 SNIP3
> +// 10000
> +#define SNIP5 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4 SNIP4
> +// 100000
> + SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5 SNIP5
> + : /* out */
> + : /* in */ [in] "r" (in)
> + : /* clobber */
> + );
> + }
> +}
> +
> +static pthread_t new_thr(void *(*fn) (void *arg), void *arg)
> +{
> + pthread_t t;
> + pthread_attr_t attr;
> +
> + pthread_attr_init(&attr);
> + pthread_create(&t, &attr, fn, arg);
> + return t;
> +}
> +
> +int main(int argc, char **argv)
> +{
> + unsigned int i, thr;
> + pthread_t threads[256];
> + struct args args[256];
> +
> + if (argc < 2) {
> + printf("ERR: %s [numthreads]\n", argv[0]);
> + exit(1);
> + }
> +
> + thr = atoi(argv[1]);
> + if ((thr > 256) || (thr < 1)) {
> + printf("ERR: threads 1-256\n");
> + exit(1);
> + }
> + for (i = 0; i < thr; i++) {
> + args[i].in = rand();
> + args[i].th = new_thr(thrfn, &(args[i]));
> + }
> + for (i = 0; i < thr; i++)
> + pthread_join(args[i].th, &(args[i].ret));
> + return 0;
> +}
> --
> 2.32.0
>


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

2022-02-07 07:20:51

by Mike Leach

[permalink] [raw]
Subject: Re: [PATCH 04/12] perf test: Add beginning of test infra + test to exercise coresight

Hi Carsten

I've been looking at these tests from a trace decode perspective and
have a few comments to make.

On Wed, 15 Dec 2021 at 16:04, <[email protected]> wrote:
>
> From: Carsten Haitzler <[email protected]>
>
> This adds the initial test harness to run perf record and examine the
> resuling output when coresight is enabled on arm64 and check the
> resulting quality of the output as part of perf test.
>
> Signed-off-by: Carsten Haitzler <[email protected]>
> ---
> MAINTAINERS | 3 +
> tools/perf/Makefile.perf | 14 +-
> .../tests/shell/coresight_asm_pure_loop.sh | 18 +++
> tools/perf/tests/shell/lib/coresight.sh | 130 ++++++++++++++++++
> tools/perf/tests/shell/tools/Makefile | 26 ++++
> .../perf/tests/shell/tools/coresight/Makefile | 27 ++++
> .../shell/tools/coresight/Makefile.miniconfig | 23 ++++
> .../tools/coresight/asm_pure_loop/Makefile | 30 ++++
> .../coresight/asm_pure_loop/asm_pure_loop.S | 28 ++++
> 9 files changed, 297 insertions(+), 2 deletions(-)
> create mode 100755 tools/perf/tests/shell/coresight_asm_pure_loop.sh
> create mode 100644 tools/perf/tests/shell/lib/coresight.sh
> create mode 100644 tools/perf/tests/shell/tools/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> create mode 100644 tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 13f9a84a617e..d46e8469c467 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1894,6 +1894,9 @@ F: tools/perf/arch/arm/util/auxtrace.c
> F: tools/perf/arch/arm/util/cs-etm.c
> F: tools/perf/arch/arm/util/cs-etm.h
> F: tools/perf/arch/arm/util/pmu.c
> +F: tools/perf/tests/shell/coresight_*
> +F: tools/perf/tests/shell/tools/Makefile
> +F: tools/perf/tests/shell/tools/coresight/*
> F: tools/perf/util/cs-etm-decoder/*
> F: tools/perf/util/cs-etm.*
>
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 80522bcfafe0..26467a2c71f4 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -630,7 +630,15 @@ sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
> $(sync_file_range_arrays): $(linux_uapi_dir)/fs.h $(sync_file_range_tbls)
> $(Q)$(SHELL) '$(sync_file_range_tbls)' $(linux_uapi_dir) > $@
>
> -all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
> +TESTS_TOOLS_DIR := $(srctree)/tools/perf/tests/shell/tools
> +
> +tests-tools-targets: FORCE
> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR)
> +
> +tests-tools-targets-clean:
> + $(Q)$(MAKE) -C $(TESTS_TOOLS_DIR) clean
> +
> +all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) tests-tools-targets
>
> # Create python binding output directory if not already present
> _dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
> @@ -1020,6 +1028,7 @@ install-tests: all install-gtk
> $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
> $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
> + $(Q)$(MAKE) -C tests/shell/tools install-tests
>
> install-bin: install-tools install-tests install-traceevent-plugins
>
> @@ -1088,7 +1097,7 @@ endif # BUILD_BPF_SKEL
> bpf-skel-clean:
> $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS)
>
> -clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean
> +clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean fixdep-clean python-clean bpf-skel-clean tests-tools-targets-clean
> $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(OUTPUT)perf-iostat $(LANG_BINDINGS)
> $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
> $(Q)$(RM) $(OUTPUT).config-detected
> @@ -1155,5 +1164,6 @@ FORCE:
> .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
> .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope FORCE prepare
> .PHONY: libtraceevent_plugins archheaders
> +.PHONY: $(TESTS_TOOLS_TARGETS)
>
> endif # force_fixdep
> diff --git a/tools/perf/tests/shell/coresight_asm_pure_loop.sh b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> new file mode 100755
> index 000000000000..542d4a37e349
> --- /dev/null
> +++ b/tools/perf/tests/shell/coresight_asm_pure_loop.sh
> @@ -0,0 +1,18 @@
> +#!/bin/sh -e
> +# Coresight / ASM Pure Loop
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +TEST="asm_pure_loop"
> +. $(dirname $0)/lib/coresight.sh
> +ARGS=""
> +DATV="out"
> +DATA="$DATD/perf-$TEST-$DATV.data"
> +
> +perf record $PERFRECOPT -o "$DATA" "$BIN" $ARGS
> +
> +perf_dump_aux_verify "$DATA" 2601 334 334
> +
> +err=$?
> +exit $err
> diff --git a/tools/perf/tests/shell/lib/coresight.sh b/tools/perf/tests/shell/lib/coresight.sh
> new file mode 100644
> index 000000000000..cd6c1283e6f5
> --- /dev/null
> +++ b/tools/perf/tests/shell/lib/coresight.sh
> @@ -0,0 +1,130 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +# This is sourced from a driver script so no need for #!/bin... etc. at the
> +# top - the assumption below is that it runs as part of sourcing after the
> +# test sets up some basic env vars to say what it is.
> +
> +# perf record options for the perf tests to use
> +PERFRECMEM="-m ,128M"
> +PERFRECOPT="$PERFRECMEM -e cs_etm//u"
> +
> +# These tests need to be run as root or coresight won't allow large buffers
> +# and will not collect proper data
> +UID=`id -u`
> +if test "$UID" -ne 0; then
> + echo "Not running as root... skip"
> + exit 2
> +fi
> +
> +TOOLS=$(dirname $0)/tools
> +DIR="$TOOLS/coresight/$TEST"
> +BIN="$DIR/$TEST"
> +# If the test tool/binary does not exist and is executable then skip the test
> +if ! test -x "$BIN"; then exit 2; fi
> +DATD="."
> +# If the data dir env is set then make the data dir use that instead of ./
> +if test -n "$PERF_TEST_CORESIGHT_DATADIR"; then
> + DATD="$PERF_TEST_CORESIGHT_DATADIR";
> +fi
> +# If the stat dir env is set then make the data dir use that instead of ./
> +STATD="."
> +if test -n "$PERF_TEST_CORESIGHT_STATDIR"; then
> + STATD="$PERF_TEST_CORESIGHT_STATDIR";
> +fi
> +
> +# Called if the test fails - error code 2
> +err() {
> + echo "$1"
> + exit 1
> +}
> +
> +# Check that some statistics from our perf
> +check_val_min() {
> + STATF="$4"
> + if test "$2" -lt "$3"; then
> + echo ", FAILED" >> "$STATF"
> + err "Sanity check number of $1 is too low ($2 < $3)"
> + fi
> +}
> +
> +perf_dump_aux_verify() {
> + # Some basic checking that the AUX chunk contains some sensible data
> + # to see that we are recording something and at least a minimum
> + # amount of it. We should almost always see F3 atoms in just about
> + # anything but certainly we will see some trace info and async atom
> + # chunks.
> + DUMP="$DATD/perf-tmp-aux-dump.txt"
> + perf report --stdio --dump -i "$1" | \
> + grep -o -e I_ATOM_F3 -e I_ASYNC -e I_TRACE_INFO > "$DUMP"
> + # Simply count how many of these atoms we find to see that we are
> + # producing a reasonable amount of data - exact checks are not sane
> + # as this is a lossy process where we may lose some blocks and the
> + # compiler may produce different code depending on the compiler and
> + # optimization options, so this is rough just to see if we're
> + # either missing almost all the data or all of it
> + ATOM_F3_NUM=`grep I_ATOM_F3 "$DUMP" | wc -l`
> + ATOM_ASYNC_NUM=`grep I_ASYNC "$DUMP" | wc -l`
> + ATOM_TRACE_INFO_NUM=`grep I_TRACE_INFO "$DUMP" | wc -l`
> + rm -f "$DUMP"
> +

Terminology - an ATOM packet is one that contains branch taken / not
take atoms - E / N. These come in 6 different formats F1 .. F6.

So here we shoud drop the ATOM_ prefix from TRACE_INFO and ASYNC



> + # Arguments provide minimums for a pass
> + CHECK_F3_MIN="$2"
> + CHECK_ASYNC_MIN="$3"
> + CHECK_TRACE_INFO_MIN="$4"
> +
> + # Write out statistics, so over time you can track results to see if
> + # there is a pattern - for example we have less "noisy" results that
> + # produce more consistent amounts of data each run, to see if over
> + # time any techinques to minimize data loss are having an effect or
> + # not
> + STATF="$STATD/stats-$TEST-$DATV.csv"
> + if ! test -f "$STATF"; then
> + echo "ATOM F3 Count, Minimum, ATOM ASYNC Count, Minimum, TRACE INFO Count, Minimum" > "$STATF"
> + fi
> + echo -n "$ATOM_F3_NUM, $CHECK_F3_MIN, $ATOM_ASYNC_NUM, $CHECK_ASYNC_MIN, $ATOM_TRACE_INFO_NUM, $CHECK_TRACE_INFO_MIN" >> "$STATF"
> +
> + # Actually check to see if we passed or failed.
> + check_val_min "ATOM_F3" "$ATOM_F3_NUM" "$CHECK_F3_MIN" "$STATF"
> + check_val_min "ASYNC" "$ATOM_ASYNC_NUM" "$CHECK_ASYNC_MIN" "$STATF"
> + check_val_min "TRACE_INFO" "$ATOM_TRACE_INFO_NUM" "$CHECK_TRACE_INFO_MIN" "$STATF"
> + echo ", Ok" >> "$STATF"
> +}
> +
> +perf_dump_aux_tid_verify() {
> + # Specifically crafted test will produce a list of Tread ID's to
> + # stdout that need to be checked to see that they have had trace
> + # info collected in AUX blocks in the perf data. This will go
> + # through all the TID's that are listed as CID=0xabcdef and see
> + # that all the Thread IDs the test tool reports are in the perf
> + # data AUX chunks
> +
> + # The TID test tools will print a TID per stdout line that are being
> + # tested
> + TIDS=`cat "$2"`
> + # Scan the perf report to find the TIDs that are actually CID in hex
> + # and build a list of the ones found
> + FOUND_TIDS=`perf report --stdio --dump -i "$1" | \
> + grep -o "CID=0x[0-9a-z]\+" | sed 's/CID=//g' | \
> + uniq | sort | uniq`
> +
> + # Iterate over the list of TIDs that the test says it has and find
> + # them in the TIDs found in the perf report
> + MISSING=""
> + for TID2 in $TIDS; do
> + FOUND=""
> + for TIDHEX in $FOUND_TIDS; do
> + TID=`printf "%i" $TIDHEX`
> + if test "$TID" -eq "$TID2"; then
> + FOUND="y"
> + break
> + fi
> + done
> + if test -z "$FOUND"; then
> + MISSING="$MISSING $TID"
> + fi
> + done
> + if test -n "$MISSING"; then
> + err "Thread IDs $MISSING not found in perf AUX data"
> + fi
> +}
> diff --git a/tools/perf/tests/shell/tools/Makefile b/tools/perf/tests/shell/tools/Makefile
> new file mode 100644
> index 000000000000..c7ada20922fd
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/Makefile
> @@ -0,0 +1,26 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../../../../../tools/scripts/Makefile.include
> +include ../../../../../tools/scripts/Makefile.arch
> +include ../../../../../tools/scripts/utilities.mak
> +
> +SUBDIRS = \
> + coresight
> +
> +all: $(SUBDIRS)
> +$(SUBDIRS):
> + $(Q)$(MAKE) -C $@
> +
> +INSTALLDIRS = $(SUBDIRS:%=install-%)
> +
> +install-tests: all $(INSTALLDIRS)
> +$(INSTALLDIRS):
> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> +
> +CLEANDIRS = $(SUBDIRS:%=clean-%)
> +
> +clean: $(CLEANDIRS)
> +$(CLEANDIRS):
> + $(Q)$(MAKE) -C $(@:clean-%=%) O=$(OUTPUT) clean >/dev/null
> +
> +.PHONY: all clean install-tests $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile b/tools/perf/tests/shell/tools/coresight/Makefile
> new file mode 100644
> index 000000000000..723006ea827c
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +include ../../../../../../tools/scripts/Makefile.include
> +include ../../../../../../tools/scripts/Makefile.arch
> +include ../../../../../../tools/scripts/utilities.mak
> +
> +SUBDIRS = \
> + asm_pure_loop
> +
> +all: $(SUBDIRS)
> +$(SUBDIRS):
> + $(Q)$(MAKE) -C $@
> +
> +INSTALLDIRS = $(SUBDIRS:%=install-%)
> +
> +install-tests: $(INSTALLDIRS)
> +$(INSTALLDIRS):
> + $(Q)$(MAKE) -C $(@:install-%=%) install-tests
> +
> +CLEANDIRS = $(SUBDIRS:%=clean-%)
> +
> +clean: $(CLEANDIRS)
> +$(CLEANDIRS):
> + $(Q)$(MAKE) -C $(@:clean-%=%) clean >/dev/null
> +
> +.PHONY: all clean $(SUBDIRS) $(CLEANDIRS) $(INSTALLDIRS)
> +
> diff --git a/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> new file mode 100644
> index 000000000000..cedd26c6a0eb
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/Makefile.miniconfig
> @@ -0,0 +1,23 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +ifndef DESTDIR
> +prefix ?= $(HOME)
> +endif
> +
> +DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
> +perfexecdir = libexec/perf-core
> +perfexec_instdir = $(perfexecdir)
> +
> +ifneq ($(filter /%,$(firstword $(perfexecdir))),)
> +perfexec_instdir = $(perfexecdir)
> +else
> +perfexec_instdir = $(prefix)/$(perfexecdir)
> +endif
> +
> +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
> +INSTALL = install
> +
> +include ../../../../../../scripts/Makefile.include
> +include ../../../../../../scripts/Makefile.arch
> +include ../../../../../../scripts/utilities.mak
> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> new file mode 100644
> index 000000000000..10c5a60cb71c
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/Makefile
> @@ -0,0 +1,30 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Carsten Haitzler <[email protected]>, 2021
> +
> +include ../Makefile.miniconfig
> +
> +BIN=asm_pure_loop
> +LIB=
> +
> +all: $(BIN)
> +
> +$(BIN): $(BIN).S
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(Q)$(CC) $(BIN).S -nostdlib -static -o $(BIN) $(LIB)
> +endif
> +endif
> +
> +install-tests: all
> +ifdef CORESIGHT
> +ifeq ($(ARCH),arm64)
> + $(call QUIET_INSTALL, tests) \
> + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)'; \
> + $(INSTALL) $(BIN) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/tools/$(BIN)/$(BIN)'
> +endif
> +endif
> +
> +clean:
> + $(Q)$(RM) -f $(BIN)
> +
> +.PHONY: all clean install-tests
> diff --git a/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> new file mode 100644
> index 000000000000..262876451021
> --- /dev/null
> +++ b/tools/perf/tests/shell/tools/coresight/asm_pure_loop/asm_pure_loop.S
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Tamas Zsoldos <[email protected]>, 2021 */
> +
> +.globl _start
> +_start:
> + mov x0, 0x000fffff
> + mov x1, xzr
> +loop:
> + nop
> + nop
> + cbnz x1, noskip
> + nop
> + nop
> + adrp x2, skip
> + add x2, x2, :lo12:skip
> + br x2
> + nop
> + nop
> +noskip:
> + nop
> + nop
> +skip:
> + sub x0, x0, 1
> + cbnz x0, loop
> +
> + mov x0, #0
> + mov x8, #93 // __NR_exit syscall
> + svc #0
> --
> 2.32.0
>

Bear in mind too that the general principle of ETM4 trace is to trace
"waypoint" instructions - these are typically branches - which could
potentially cause a change in program flow.
The rest are deduced from the program image.

The test program above is a good start - there are three waypoint
instructions - looking at the code, each iteration of the look will
generate a NEE atom element pattern. (cbnz x1 is never taken as x1 is
always 0, br x2 is unconditional and always taken, cbnz x0, loop is
always taken - except for the final time on loop exit).

Which fits nicely into the ATOM_F3 packet you are counting.

However - there is nothing in the ETM architecture that says an
implementation has to use this packet. Depending on timings and
implementation details the same trace on a different platform could be
output as
consecutive ATOM_F2 packets NE EN EE etc, etc.

Both cases will decode correctly. Counting a particular ATOM packet
type is therefore not a portable test.
For a given bounded trace run*, you shoul always see the same number
of atom elements. Helpfully ATOM_F1 packets contain 1 atom, _F2 2
atoms. up to F5 with 5 atoms. Less helpfully F6 contains between 4 and
24 atoms.

For ASYNC / TRACE INFO these are programmed to appear at every 4k
bytes of trace. This allows synchronisation to be established if the
hardware buffer has wrapped. They will also appear at start of trace
and other locations defined in the ETM4 architecture spec. However,
both are emitted as a pair due to a synchronisation request - the
ASYNC allows the packet processor to start interpreting the bytes
stream into a set of packets. TRACEINFO is used by the trace decoder
to turn the set of packets into decoded trace. For the purposes of the
perf report --dump you are using, it is only necessary to count the
ASYNCs. TRACEINFO does not add a great deal.

One additional caveat here - while most implementations provide the
register that allows the programming of ASYNC frequency, it is
possible for an implementation to set this register as RO and use a
single fixed frequency - which might not be 4k bytes.


Regards

Mike

*by bounded trace run - I mean one that has completed without the
buffer wrapping - i.e. where perf does not report loss of trace.


--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

2022-02-08 17:19:58

by Mike Leach

[permalink] [raw]
Subject: Re: [PATCH 12/12] perf test: Add docs for coresight and related tests

Hi Carsten,

I'll put a few more general comments in here as it seems to be the
place to do it!


On Mon, 31 Jan 2022 at 18:05, Carsten Haitzler
<[email protected]> wrote:
>
> Hi James
>
> You've found indeed that the tests are for checking if we're even
> exporting any kind of sane data from the system into perf data files.
> The point of this was not to test all of the openocd decoding path and
> to see if, given a perf trace of sufficient completeness, that we can do
> something sensible (autofdo, coverage etc.). These involve much more
> complex decoding on the other end of "we have a perf.data file... let's
> use it". This is all about checking we get perf data files that contain
> somewhat sane content. Does our ""sandwich" have bread at either end and
> some kind of filling in the middle?"
>
> It does appear that we have bugs. These tests seem to show it. We
> regularly fail the TID checks where we provide ZERO blocks of data for
> some threads that run for an extended period of time. This repeats
> itself across various other tests.
>

I am not sure that this is what the tests are showing us.

We know that the current coresight model of multiple cores running
ETMs into a single ETR has limitations.
We cannot trigger an interrrupt when the ETR is full (other than in a
very per platform specific way, using CTIs and even then we would have
to stop every core that was tracing into the buffer - which is why we
have not attempted to solve this problem yet - if it can indeed be
solved)
The amount of trace captured is sensitive to when the user side of
perf is woken up to copy the data from the ETR. This can lead to long
trace runs wrapping the buffer - consequently trace is lost.

Things get a lot better when we have ETE + TRBE, which can interrupt
on full, and uses a 1 buffer per core model.

So these tests need to answer the question - is the trace I have
collected sensible - bearing in mind platform limitations that not all
trace may have been collected.
If the question is yes - the trace is sensible - then the tests should
pass, not fail on occasion as we are seeing now.

There is a difference between "is the trace I am capturing valid" and
"am I capturing all possible trace"


> I chose 3 specific things to probe for in the test data - the sync
> "headers" which we get every now and again in the stream to see we're
> producing some data at all. Trace info will tell us more - like what
> thread/pid and we should get at least enough of these to cover every
> thread we might run if we have long-lived threads running for a while.

There is no relationship between TRACE_INFO and PIDs.
PIDs live in the ADDR_CTXT packets - perhaps a metric on these would
be useful. While you always get ADDR_CTXT after TRACE_INFO, ADDR_CTXT
or CTXT only will appear in other places - as often as necessary to
track ContextID / PID.

> Perf data is a lossy matter here - we can't guarantee we always collect
> everything. This is why the tests also store the numbers they collect
> over multiple runs in csv files so it is possible over the long term to
> track the quality of data statistically.

Certainly there is value to this - however this should be separate
from the checks for validity of trace.
Perhaps with the TID example we could have a pass with X% of TIDs
spotted - where pass is a low number, but we record the % to track
improvements to the system - or indeed regressions.

> The documentation I added in
> the patch set covers this. The F3 atoms were simply the filling in the
> sandwich - is there content other than the "structure" of info/sync. I
> could have picked any ATOM_Fx there. As long as there is something
> there, we're collecting some amount of actual execution content.
>

As mentioned in the other patches - the amount of these can vary on a
per platform basis. Number of atoms rather than number of specific
atom packets is a better metric.



> The idea is that over time when these issues are fixed, we will see more
> of these tests pass more often and the csv data they collect should show
> a jump (on average in the long run) of data collected. Yes - the numbers
> in the tests are a bit "magical" but they can't be derived or calculated
> exactly as they will depend on the instructions a compiler may product
> for a binary as well as other system factors (races). The numbers I
> chose were a result of actually running the tests and collecting data
> and e.g. deciding "if we collect at least 20% of the lowest numbers I
> see, then we're got a pass". It's the same idea in any qualitative test
> - you decide that some value is a passing grade. Of course I could be
> very lenient and just have all the numbers be "1" (at least get one of
> each) and that is about the only derivable value we could agree on is a
> true minimum.
>
> Coverage will suffer the same problem - it will sometimes happen you
> will get no coverage. Eg.g the thread tests above. IF I formulated them
> with a different function per thread and used coverage to figure out
> which threads reported no data - we'd then need to have the coverage be
> 100% to pass and we'd be failing right now.
>
> You are right that perhaps I added too many tests to cover different
> paths (it's unusual that people are unhappy with too many tests and want
> fewer :)), but I see the point of "it takes too long to run" and I can
> certainly trim the tests down.
>
> I've been running on my dragonboard 845 and they don't all pass for me
> either - as above. 95%+ of the test time is spent dumping the perf.data
> file and parsing out the coresight traces. It's not that fast. I did
> quickly look into running perf on perf (seeing if there were some
> blindingly obvious hotspots somewhere to fix) but didn't see anything
> jump out at me. Collecting less data of course speeds it up and that's
> easy to tweak. I could definitely speed things up if I had the checker
> stop parsing the dump output once we had "enough of item X" (I_ASYNC,
> I_TRACE_INFO) which would certainly speed things up. Lowering those
> numbers to bare minimums would make it a lot faster but it would
> probably have issues with the TID checks as I'd like to give the system
> enough time to plausibly collect some data on every thread.
>
> The multiple tests with different threads were there to ensure even on
> many-core system we can saturate all cores to see we are context
> switching between threads and then still capturing data on all cores.
> The point of these tests is to stress-test and not just "bare minimum -
> do we get something" and they certainly seem to find problems in the
> process. I built them so it'd be easy to just drop more tests and tools
> into directories and expand on over time to improve quality of things
> covered. The bubble sort tests were ones that were being used for perf
> quality tests already internally in their own separate git repo, so I
> included them. I can remove them of course as they probably don't
> provide any value over other simpler tests.
>

I have no issue with the bubble sort. This will tend to generate
differing branch patterns as the sort progresses, so is a good example
for trace.

> Testing the pipeline AFTER collecting some sensible data to see if we
> can decode it and e.g. apply it to fdo or coverage is a separate set of
> tests which this was not meant to address (at this stage). Those tests
> certainly do not fit the same pattern as these which follow a simple
> design patter of build N test tools, run those test tools and collect
> data, check the data is semi-sane and seemingly collecting what it should.
>
> So I can:
>
> * Trim the number of tests down
> * Fewer versions of the same one
> * Drop the sorts
> * Optimize time spent checking data (bail early when minimum reached)
>

I would say prefer short trace runs for the majority of tests to check
quality of trace - but at least 1 long run to stress the
infrastructure

Quality of trace needs to look at other issues - are there invalid
packets in the dump. Does the decoder lose sync during the decode
process (you will see NO_SYNC packets after the first SYNC packet in
this case.)

The latest versions of the decoder offer up statistics on number of
bytes decoded compared to number of bytes processed. These can be a
measure of the quality of trace too. I think a patch to perf has been
created to dump these.


> On 1/19/22 16:43, James Clark wrote:
> >
> >
> > On 15/12/2021 16:04, [email protected] wrote:
> >> From: Carsten Haitzler <[email protected]>
> >>
> >> This adds documentation about the coresight specific tests as part of
> >> perf test
> >>
> >> Signed-off-by: Carsten Haitzler <[email protected]>
> >
> > I will use this commit to comment on the set as a whole. The other comments about
> > specific issues I have left inline.
> >
> > I ran the tests twice on N1SDP (kernel version perf/core 48ffaedf017ad) and had two
> > different sets of failures, indicating some flakyness, which is one reason to not have
> > tests with magic numbers as Leo has raised. Are you able to give a complete list of
> > where you have run these so far? I know we can't check everywhere, but at least all
> > of Arm's own reference platforms should be passing.
> >
> > First run:
> >
> > 92: Coresight / Thread Loop 25 Threads : FAILED!
> > 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> > 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> > 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> > 97: Coresight / Unroll Loop Thread 1 : FAILED!
> > 99: Coresight / Unroll Loop Thread 2 : FAILED!
> >
> > Second run:
> >
> > 92: Coresight / Thread Loop 25 Threads : FAILED!
> > 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> > 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> > 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> > 97: Coresight / Unroll Loop Thread 1 : FAILED!
> >
> > I have pasted the verbose output of two of these at the very end.
> >
> > The major problem I have with the tests is the time that they take to run. Now
> > a full test run takes 31m+ on N1SDP, where previously it took 1m 9s. There are
> > quite a few reasons why this isn't a good idea. It will take extra cycles on
> > anyone's CI and that means it will now take longer for anyone to make any changes
> > if they run the tests, slowing down all Perf work from now onward. Even if you
> > want to run just the Coresight tests, it doesn't really help as that is 90% of
> > the time taken, so personally for me I'm not likely to run them while working on
> > Coresight changes. The longer the tests take the more likely it is that they are
> > skipped, reducing the benefits of the tests. Also if anyone has timeouts set on
> > CI these are likely going to have to be adjusted now.
> >
> > Is it possible to get the run time of each test down to 5-10 seconds? This will
> > make it much nicer for us to work with going forwards.
> >
> > I'd also have liked to have had a discussion on the mailing list about what the test
> > methodology should be in general before starting. For example for this patch set it
> > looks like the coverage is quite wide because of the number of tests and time it
> > takes to run, but actually they all use "cs_etm//u -- <process>" as the run command.
> > This only tests per-process userspace mode resulting in very narrow coverage.
> > And there is no mention in a cover letter about how this expands on or interacts
> > with the existing test_arm_coresight.sh test which I don't think can be ignored.
> > For example it iterates over sinks. Could that same iteration not be applied to
> > these tests? They seem to exist in isolation and it's not clear which one we should
> > be adding to going forwards.
> >
> > I'd like to see a much more exploration of the different modes and flags to justify
> > such a high run time:
> >
> > * per-CPU
> > * per-thread
> > * with and without timestamps
> > * strobing
> >
> > If this is supposed to be just an initial implementation covering one case, then
> > by the "test one thing" ethos, there should only be one test case. Each case
> > should be testing one thing with minimal overlapping. But it looks like tests like
> > "Thread loop 10" and "thread loop 250" just test the same thing, and I don't see
> > the value in maintaining that. Also "bubblesort" and "memcpy" don't have comments
> > explaining why running on those two different test programs actually makes a
> > difference. Obviously this comment is partially related to the run time, if it was
> > shorter perhaps it would be less important how many variations we ran.
> >
> > It's also not clear what failure modes the tests are looking for. There are
> > comments like "We should almost always see F3 atoms", but it's not clear how
> > F3 atoms are a signal of a high quality trace. And there are numbers like:
> >
> > perf_dump_aux_verify "$DATA" 66 6 6
> > perf_dump_aux_verify "$DATA" 4188 1630 1630
> >
> > but there are no comments to say how 66 or 4188 were judged to be "high quality" vs
> > any other number. This means that anyone encountering a failure is just going to
> > change the number until it passes, undoing any value that the test added. If the tests
> > are looking for complete loss of data, then > 1 or > 2 would be sufficient. But if
> > someone makes a mistake in the driver to produce less data, then these tests aren't
> > going to catch that anyway, since there is a chance that it falls within the allowed
> > thresholds.
> >
> > In my opinion a much better measure of quality would be to look at the coverage of
> > fully decoded trace, for example if you have 10 functions called from a loop across
> > multiple DSOs, do each of those functions show up in synthesised instruction samples.
> >
> > Which brings me to my next point, the tests only seem to look at the raw trace, rather
> > than the synthesised samples. To me this seems like it's validating what comes out of
> > the CPU more than looking at what the driver or userspace Perf are doing. I think this
> > isn't the right place for these tests to live and would be better suited to run on bare
> > metal. This is because a user isn't going to be interested in how many F3 atoms there are,
> > that's just an implementation detail. What's much more valuable is what samples are
> > synthesised. We're also skipping most of the code in Perf by only looking at the raw
> > trace, which makes it harder to justify putting the tests in the Perf code base.
> >
> > In short I think it would be much better if we had the following:
> >
> > * Much shorter run time
> > * Run each test program only once (for example it doesn't add value to run memcpy with different sizes)
> > * Only one test for each thing/failure mode
> > * Much less overlapping test code (for example F3 atoms only need to be counted for one test, not all of them)
> > * Concrete descriptions of failure modes and what each test is looking for
> > * Small magic numbers which are easy to justify (like "samples < 1, check for complete loss of data")
> > * Run through the full Perf pipeline and look at the synthesised samples rather than raw trace
> > * Some thought about how this fits in with test_arm_coresight.sh
> >
> > Thanks
> > James
> >
> >
> >
> > Test failure outputs:
> > ---
> >
> > 94: Coresight / Thread Loop 10 Threads - Check TID :
> > --- start ---
> > test child forked, pid 5821
> > Couldn't synthesize bpf events.
> > [ perf record: Woken up 1 times to write data ]
> > [ perf record: Captured and wrote 128.106 MB ./perf-thread_loop-check-tid-10th.data ]
> >
> >
> >
> > Warning:
> > AUX data lost 1 times out of 1!
> >
> > Thread IDs not found in perf AUX data

Should this not be a list of which TIDs are missing?

> > test child finished with -1
> > ---- end ----
> > Coresight / Thread Loop 10 Threads - Check TID: FAILED!
> >
> > ========================================================
> >
> >
> > 92: Coresight / Thread Loop 25 Threads :
> > --- start ---
> > test child forked, pid 5871
> > Couldn't synthesize bpf events.
> > [ perf record: Woken up 1 times to write data ]
> > [ perf record: Captured and wrote 28.849 MB ./perf-thread_loop-25th.data ]
> > Sanity check number of ATOM_F3 is too low (92062 < 388121)

This may well be an example of what I referred to in my comments on
patch 1 - there is no guarantee that the same ATOM packets will be
used in the same way across different platforms.

Regards

Mike

> > test child finished with -1
> > ---- end ----
> > Coresight / Thread Loop 25 Threads: FAILED!
> >
> >
> >> ---
> >> MAINTAINERS | 1 +
> >> tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
> >> 2 files changed, 141 insertions(+)
> >> create mode 100644 tools/perf/Documentation/arm-coresight.txt
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index d46e8469c467..1a93977a0132 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
> >> F: drivers/hwtracing/coresight/*
> >> F: include/dt-bindings/arm/coresight-cti-dt.h
> >> F: include/linux/coresight*
> >> +F: tools/perf/Documentation/arm-coresight.txt
> >> F: tools/perf/arch/arm/util/auxtrace.c
> >> F: tools/perf/arch/arm/util/cs-etm.c
> >> F: tools/perf/arch/arm/util/cs-etm.h
> >> diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
> >> new file mode 100644
> >> index 000000000000..3a9e6c573c58
> >> --- /dev/null
> >> +++ b/tools/perf/Documentation/arm-coresight.txt
> >> @@ -0,0 +1,140 @@
> >> +Arm Coresight Support
> >> +=====================
> >> +
> >> +Coresight is a feature of some Arm based processors that allows for
> >> +debugging. One of the things it can do is trace every instruction
> >> +executed and remotely expose that information in a hardware compressed
> >> +stream. Perf is able to locally access that stream and store it to the
> >> +output perf data files. This stream can then be later decoded to give the
> >> +instructions that were traced for debugging or profiling purposes. You
> >> +can log such data with a perf record command like:
> >> +
> >> + perf record -e cs_etm//u testbinary
> >> +
> >> +This would run some test binary (testbinary) until it exits and record
> >> +a perf.data trace file. That file would have AUX sections if coresight
> >> +is working correctly. You can dump the content of this file as
> >> +readable text with a command like:
> >> +
> >> + perf report --stdio --dump -i perf.data
> >> +
> >> +You should find some sections of this file have AUX data blocks like:
> >> +
> >> + 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
> >> +
> >> + . ... CoreSight ETM Trace data: size 73168 bytes
> >> + Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
> >> + Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
> >> + Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
> >> + Idx:26; ID:10; I_TRACE_ON : Trace On.
> >> + Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
> >> + Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> >> + Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> >> + Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
> >> + Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
> >> + ...
> >> +
> >> +If you see these above, then your system is tracing coresight data
> >> +correctly.
> >> +
> >> +To compile perf with coresight support in the perf directory do
> >> +
> >> + make CORESIGHT=1
> >> +
> >> +This will compile the perf tool with coresight support as well as
> >> +build some small test binaries for perf test. This requires you also
> >> +be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
> >> +perf coresight tracing are in tests/shell/tools/coresight.
> >> +
> >> +You will also want coresight support enabled in your kernel config.
> >> +Ensure it is enabled with:
> >> +
> >> + CONFIG_CORESIGHT=y
> >> +
> >> +There are various other coresight options you probably also want
> >> +enabled like:
> >> +
> >> + CONFIG_CORESIGHT_LINKS_AND_SINKS=y
> >> + CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
> >> + CONFIG_CORESIGHT_CATU=y
> >> + CONFIG_CORESIGHT_SINK_TPIU=y
> >> + CONFIG_CORESIGHT_SINK_ETBV10=y
> >> + CONFIG_CORESIGHT_SOURCE_ETM4X=y
> >> + CONFIG_CORESIGHT_STM=y
> >> + CONFIG_CORESIGHT_CPU_DEBUG=y
> >> + CONFIG_CORESIGHT_CTI=y
> >> + CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
> >> +
> >> +Please refer to the kernel configuration help for more information.
> >> +
> >> +Perf test - Verify kernel and userspace perf coresight work
> >> +===========================================================
> >> +
> >> +When you run perf test, it will do a lot of self tests. Some of those
> >> +tests will cover Coresight (only if enabled and on ARM64). You
> >> +generally would run perf test from the tools/perf directory in the
> >> +kernel tree. Some tests will check some internal perf support like:
> >> +
> >> + Check Arm CoreSight trace data recording and synthesized samples
> >> +
> >> +Some others will actually use perf record and some test binaries that
> >> +are in tests/shell/tools/coresight and will collect traces to ensure a
> >> +minimum level of functionality is met. The scripts that launch these
> >> +tests are in tests/shell. These will all look like:
> >> +
> >> + Coresight / Memcpy 1M 25 Threads
> >> + Coresight / Unroll Loop Thread 2
> >> + ...
> >> +
> >> +These perf record tests will not run if the tool binaries do not exist
> >> +in tests/shell/tools/coresight/*/ and will be skipped. If you do not
> >> +have coresight support in hardware then either do not build perf with
> >> +coresight support or remove these binaries in order to not have these
> >> +tests fail and have them skip instead.
> >> +
> >> +These tests will log historical results in the current working
> >> +directory (e.g. tools/perf) and will be named stats-*.csv like:
> >> +
> >> + stats-asm_pure_loop-out.csv
> >> + stats-bubble_sort-random.csv
> >> + ...
> >> +
> >> +These statistic files log some aspects of the AUX data sections in
> >> +the perf data output counting some numbers of certain encodings (a
> >> +good way to know that it's working in a very simple way). One problem
> >> +with coresight is that given a large enough amount of data needing to
> >> +be logged, some of it can be lost due to the processor not waking up
> >> +in time to read out all the data from buffers etc.. You will notice
> >> +that the amount of data collected can vary a lot per run of perf test.
> >> +If you wish to see how this changes over time, simply run perf test
> >> +multiple times and all these csv files will have more and more data
> >> +appended to it that you can later examine, graph and otherwise use to
> >> +figure out if things have become worse or better.
> >> +
> >> +Be aware that amny of these tests take quite a while to run, specifically
> >> +in processing the perf data file and dumping contents to then examine what
> >> +is inside.
> >> +
> >> +You can change where these csv logs are stored by setting the
> >> +PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
> >> +test like:
> >> +
> >> + export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
> >> + perf test
> >> +
> >> +They will also store resulting perf output data in the current
> >> +directory for later inspection like:
> >> +
> >> + perf-memcpy-1m.data
> >> + perf-thread_loop-2th.data
> >> + ...
> >> +
> >> +You can alter where the perf data files are stored by setting the
> >> +PERF_TEST_CORESIGHT_DATADIR environment variable such as:
> >> +
> >> + PERF_TEST_CORESIGHT_DATADIR=/var/tmp
> >> + perf test
> >> +
> >> +You may wish to set these above environment variables if you which to
> >> +keep the output of tests outside of the current working directory for
> >> +longer term storage and examination.
> >>



--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK

2022-03-09 12:50:58

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 12/12] perf test: Add docs for coresight and related tests

I have an updated patch set queued to send out, so responding now. I've
addressed various things. See below.

On 1/19/22 16:43, James Clark wrote:
>
>
> On 15/12/2021 16:04, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds documentation about the coresight specific tests as part of
>> perf test
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>
> I will use this commit to comment on the set as a whole. The other comments about
> specific issues I have left inline.
>
> I ran the tests twice on N1SDP (kernel version perf/core 48ffaedf017ad) and had two
> different sets of failures, indicating some flakyness, which is one reason to not have
> tests with magic numbers as Leo has raised. Are you able to give a complete list of
> where you have run these so far? I know we can't check everywhere, but at least all
> of Arm's own reference platforms should be passing.
>
> First run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!
> 99: Coresight / Unroll Loop Thread 2 : FAILED!
>
> Second run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!

Yes. There is actual problems at the data production end of the
pipeline. Let me just focus on one of the type of examples. The Check
TID examples look for some thread data for each thread that runs in the
sample. If they do not get at least one such context id that matches a
thread ID (as that is what the contextid does map to) then it will fail.
We're missing that. It's not reliable. The tests show this. They don't
fix it, but the point of these tests is to find issues so we know what
issues exist before any data is decoded.

> I have pasted the verbose output of two of these at the very end.
>
> The major problem I have with the tests is the time that they take to run. Now
> a full test run takes 31m+ on N1SDP, where previously it took 1m 9s. There are
> quite a few reasons why this isn't a good idea. It will take extra cycles on
> anyone's CI and that means it will now take longer for anyone to make any changes
> if they run the tests, slowing down all Perf work from now onward. Even if you
> want to run just the Coresight tests, it doesn't really help as that is 90% of
> the time taken, so personally for me I'm not likely to run them while working on
> Coresight changes. The longer the tests take the more likely it is that they are
> skipped, reducing the benefits of the tests. Also if anyone has timeouts set on > CI these are likely going to have to be adjusted now.

In my new patch set I've removed a lot of the tests and kept only a
smaller set. In my tests it now takes about 3-8 mins to run instead of
about 1 min (It's variable because the amount of data collected can be
highly variable and 99% of the time in these tests is spend dumping the
perf data to see what is in there and this is time consuming. If the
test produces 2x the data vs last run it takes a lot longer to dump and
this actually happens).

> Is it possible to get the run time of each test down to 5-10 seconds? This will
> make it much nicer for us to work with going forwards.

Unfortunately I can't get it down to that. As above. The TID tests are
fairly short but sometimes produce 20m perf data files, sometimes 80m
sometimes 130m... it's indeterminate even if the actual test itself is
constant (runs the same identical workload). I can cut down the number
of tests and squeeze down the loop runs etc. which I have now done, but
we still have the above problem.

> I'd also have liked to have had a discussion on the mailing list about what the test
> methodology should be in general before starting. For example for this patch set it
> looks like the coverage is quite wide because of the number of tests and time it
> takes to run, but actually they all use "cs_etm//u -- <process>" as the run command.
> This only tests per-process userspace mode resulting in very narrow coverage.
> And there is no mention in a cover letter about how this expands on or interacts
> with the existing test_arm_coresight.sh test which I don't think can be ignored.
> For example it iterates over sinks. Could that same iteration not be applied to
> these tests? They seem to exist in isolation and it's not clear which one we should
> be adding to going forwards.

It's a more "extensible harness" to just drop many varieties of tests
into - e.g. the TID example s- do we collect thread data from every
thread? They also store "quality" of data over time in CSV files. You
can clearly see the high variability coming out of the tests there. They
include actual test tools/source (don't just run some existing binary
like touch) thus control what is being recorded. I built them to be
easily expanded over time with more specific case tests by just dropping
in a new directory with a new tool and.or a new script in the tests dir
to use that tool or an existing one and re-use shared functions etc.

And yes - it tests only userspace (for now). Rome was not built in a
day. It's testing userspace as that is what is being controlled (by the
test tools). Tracing kernel code is another problem and thing to test. I
was hoping this is a start and that's why it's built as a more extensive
harness to be re-used and expanded on.

> I'd like to see a much more exploration of the different modes and flags to justify
> such a high run time:
>
> * per-CPU
> * per-thread
> * with and without timestamps
> * strobing

All future problems to solve.

> If this is supposed to be just an initial implementation covering one case, then
> by the "test one thing" ethos, there should only be one test case. Each case
> should be testing one thing with minimal overlapping. But it looks like tests like

Different workloads. Provide something that should have a large amount
of instructions to trace across lots of memory as opposed to small tight
loops. What do we collect then? Do we collect data across multiple
threads? If we keep every core busy, then what? Due to the way data is
collected (buffers/interrupts), it's a lossy exercise and Having
different workloads to see where we might not collect as much data as
we'd like is useful. That's why there are multiple tests.

> "Thread loop 10" and "thread loop 250" just test the same thing, and I don't see
> the value in maintaining that. Also "bubblesort" and "memcpy" don't have comments
> explaining why running on those two different test programs actually makes a
> difference. Obviously this comment is partially related to the run time, if it was
> shorter perhaps it would be less important how many variations we ran.

Those were existing tests being used in test_etm (out of kernel tree)
already so I put them in as they were seemingly good enough there so
perf test would become a superset of the above and add more.

The runtime is almost entirely due to perf dump. I spent a little time
profiling perf dump and didn't see any obvious hotspots to quickly pick
low hanging fruit from.

> It's also not clear what failure modes the tests are looking for. There are
> comments like "We should almost always see F3 atoms", but it's not clear how
> F3 atoms are a signal of a high quality trace. And there are numbers like:
>
> perf_dump_aux_verify "$DATA" 66 6 6
> perf_dump_aux_verify "$DATA" 4188 1630 1630

Think of it measuring the body - seeing some amount as opposed to none
or only 1 ... yes- this is measuring the compressed encoding but it's
one of the very common ones so it was a quick way to do this as opposed
to completely decoding the data and then checking that (which would be
more costly and make tests take longer). I did have high-ish numbers but
they were actually a result of going "well on most runs we tend to get X
in real life so if we get X/10 we should have enough". Yes - 1 or 2 or
10 could also be sensible as it is lossy and we should collect SOME
data, but preferably we should be collecting more. If we would not have
a lossy process that collected everything we should get a stable amount
of data collected... that would be the goal eventually.

> but there are no comments to say how 66 or 4188 were judged to be "high quality" vs
> any other number. This means that anyone encountering a failure is just going to
> change the number until it passes, undoing any value that the test added. If the tests
> are looking for complete loss of data, then > 1 or > 2 would be sufficient. But if
> someone makes a mistake in the driver to produce less data, then these tests aren't
> going to catch that anyway, since there is a chance that it falls within the allowed
> thresholds.

That's actually the point. Imagine someone makes a change in the driver
that now loses 60% of the trace data. If we just assume any amount of
loss is just fine - we'd never know unless we have tests measuring this
until eventually some time later someone wonders why their profile data
is so variable... this is exactly why the tests store the data they
collect over time in csv files so you can see trends or points where
suddenly data took a hit or jumped up to collect more.

> In my opinion a much better measure of quality would be to look at the coverage of
> fully decoded trace, for example if you have 10 functions called from a loop across
> multiple DSOs, do each of those functions show up in synthesised instruction samples.

That would be more expensive to do (and make the tests take longer)
which goes against some of your desires above. This would be another
stage in the tests beyond what they do (Rome was not built in a day :)).
Coverage would then tell us if we cover the function at least once. How
many times do we cover it? If it runs 10000 times do we get trace data
for all of its 10000 executions? or only 100 of them? or 10? or 1? This
is certainly much more involved and an evolution of tests to do more.
I'm not sure I should sit and make the test do everything possible and
test everything from day 1. Start with a base that is intended to expand
cleanly and in a "modular" way and then build from there. I've learned
over the years to always build things in steps and get your groundwork
good before going the next step. I'm doing this here. Groundwork with
some exercising of it.

> Which brings me to my next point, the tests only seem to look at the raw trace, rather
> than the synthesised samples. To me this seems like it's validating what comes out of
> the CPU more than looking at what the driver or userspace Perf are doing. I think this

100% correct. Or more looking at what comes out of the kernel perf
driver into perf data files. It's focusing on this part of the pipeline
- not the "decode that data and do something useful with it" part. I
specifically focused on this part as this is a source of data loss and
quality of data. You can have the best decoding on the planet - if your
input data is poor ... you will have poor results. I also understood
that you were working on the other end of the pipeline (the decode/do
something with it end) and thus thought I'd fill in the part you were
not working on rather than conflict with the stuff you are doing.

> isn't the right place for these tests to live and would be better suited to run on bare
> metal. This is because a user isn't going to be interested in how many F3 atoms there are,
> that's just an implementation detail. What's much more valuable is what samples are
> synthesised. We're also skipping most of the code in Perf by only looking at the raw
> trace, which makes it harder to justify putting the tests in the Perf code base.

Then then we would have our tests fragmented. Testing kernel output
won't have tests in the kernel tree for the data/subsystem that is
reading/collecting/writinf that data...

> In short I think it would be much better if we had the following:
>
> * Much shorter run time

Done. Patches coming.

> * Run each test program only once (for example it doesn't add value to run memcpy with different sizes)

Done mostly as above (except the TID test where I'm down to 2 tests).

> * Only one test for each thing/failure mode

Done - mostly, as above.

> * Much less overlapping test code (for example F3 atoms only need to be counted for one test, not all of them)

It's measuring if we have test "body". I could do this in more expensive
ways in addition to the metadata blocks (async and trace info).

> * Concrete descriptions of failure modes and what each test is looking for

I haven't done this yet - let me send a new patch set which is smaller
and we'll go from there.

> * Small magic numbers which are easy to justify (like "samples < 1, check for complete loss of data")

Done.

> * Run through the full Perf pipeline and look at the synthesised samples rather than raw trace

I thought you were dealing with this end?

> * Some thought about how this fits in with test_arm_coresight.sh

As above - more of an extended harness to add to over time rather than a
single test that fails or succeeds - its broken down into many tests so
you know which succeed or fail. I've dealt with tests units that merge
dozens or even 100+ tests into a single case and then just report fail
or succeed and it's very annoying as you don't get an isolated result to
tell you what you broke. If this single shell script keeps getting more
and more things to test then .. which one broke when all you see is a
single fail? It's a time sink to go digging every time. Broken cleanly
into multiple tests is far better.

> Thanks
> James
>
>
>
> Test failure outputs:
> ---
>
> 94: Coresight / Thread Loop 10 Threads - Check TID :
> --- start ---
> test child forked, pid 5821
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 128.106 MB ./perf-thread_loop-check-tid-10th.data ]
>
>
>
> Warning:
> AUX data lost 1 times out of 1!
>
> Thread IDs not found in perf AUX data
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 10 Threads - Check TID: FAILED!
>
> ========================================================
>
>
> 92: Coresight / Thread Loop 25 Threads :
> --- start ---
> test child forked, pid 5871
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 28.849 MB ./perf-thread_loop-25th.data ]
> Sanity check number of ATOM_F3 is too low (92062 < 388121)
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 25 Threads: FAILED!
>
>
>> ---
>> MAINTAINERS | 1 +
>> tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
>> 2 files changed, 141 insertions(+)
>> create mode 100644 tools/perf/Documentation/arm-coresight.txt
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d46e8469c467..1a93977a0132 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
>> F: drivers/hwtracing/coresight/*
>> F: include/dt-bindings/arm/coresight-cti-dt.h
>> F: include/linux/coresight*
>> +F: tools/perf/Documentation/arm-coresight.txt
>> F: tools/perf/arch/arm/util/auxtrace.c
>> F: tools/perf/arch/arm/util/cs-etm.c
>> F: tools/perf/arch/arm/util/cs-etm.h
>> diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
>> new file mode 100644
>> index 000000000000..3a9e6c573c58
>> --- /dev/null
>> +++ b/tools/perf/Documentation/arm-coresight.txt
>> @@ -0,0 +1,140 @@
>> +Arm Coresight Support
>> +=====================
>> +
>> +Coresight is a feature of some Arm based processors that allows for
>> +debugging. One of the things it can do is trace every instruction
>> +executed and remotely expose that information in a hardware compressed
>> +stream. Perf is able to locally access that stream and store it to the
>> +output perf data files. This stream can then be later decoded to give the
>> +instructions that were traced for debugging or profiling purposes. You
>> +can log such data with a perf record command like:
>> +
>> + perf record -e cs_etm//u testbinary
>> +
>> +This would run some test binary (testbinary) until it exits and record
>> +a perf.data trace file. That file would have AUX sections if coresight
>> +is working correctly. You can dump the content of this file as
>> +readable text with a command like:
>> +
>> + perf report --stdio --dump -i perf.data
>> +
>> +You should find some sections of this file have AUX data blocks like:
>> +
>> + 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
>> +
>> + . ... CoreSight ETM Trace data: size 73168 bytes
>> + Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
>> + Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
>> + Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
>> + Idx:26; ID:10; I_TRACE_ON : Trace On.
>> + Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
>> + Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
>> + ...
>> +
>> +If you see these above, then your system is tracing coresight data
>> +correctly.
>> +
>> +To compile perf with coresight support in the perf directory do
>> +
>> + make CORESIGHT=1
>> +
>> +This will compile the perf tool with coresight support as well as
>> +build some small test binaries for perf test. This requires you also
>> +be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
>> +perf coresight tracing are in tests/shell/tools/coresight.
>> +
>> +You will also want coresight support enabled in your kernel config.
>> +Ensure it is enabled with:
>> +
>> + CONFIG_CORESIGHT=y
>> +
>> +There are various other coresight options you probably also want
>> +enabled like:
>> +
>> + CONFIG_CORESIGHT_LINKS_AND_SINKS=y
>> + CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
>> + CONFIG_CORESIGHT_CATU=y
>> + CONFIG_CORESIGHT_SINK_TPIU=y
>> + CONFIG_CORESIGHT_SINK_ETBV10=y
>> + CONFIG_CORESIGHT_SOURCE_ETM4X=y
>> + CONFIG_CORESIGHT_STM=y
>> + CONFIG_CORESIGHT_CPU_DEBUG=y
>> + CONFIG_CORESIGHT_CTI=y
>> + CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
>> +
>> +Please refer to the kernel configuration help for more information.
>> +
>> +Perf test - Verify kernel and userspace perf coresight work
>> +===========================================================
>> +
>> +When you run perf test, it will do a lot of self tests. Some of those
>> +tests will cover Coresight (only if enabled and on ARM64). You
>> +generally would run perf test from the tools/perf directory in the
>> +kernel tree. Some tests will check some internal perf support like:
>> +
>> + Check Arm CoreSight trace data recording and synthesized samples
>> +
>> +Some others will actually use perf record and some test binaries that
>> +are in tests/shell/tools/coresight and will collect traces to ensure a
>> +minimum level of functionality is met. The scripts that launch these
>> +tests are in tests/shell. These will all look like:
>> +
>> + Coresight / Memcpy 1M 25 Threads
>> + Coresight / Unroll Loop Thread 2
>> + ...
>> +
>> +These perf record tests will not run if the tool binaries do not exist
>> +in tests/shell/tools/coresight/*/ and will be skipped. If you do not
>> +have coresight support in hardware then either do not build perf with
>> +coresight support or remove these binaries in order to not have these
>> +tests fail and have them skip instead.
>> +
>> +These tests will log historical results in the current working
>> +directory (e.g. tools/perf) and will be named stats-*.csv like:
>> +
>> + stats-asm_pure_loop-out.csv
>> + stats-bubble_sort-random.csv
>> + ...
>> +
>> +These statistic files log some aspects of the AUX data sections in
>> +the perf data output counting some numbers of certain encodings (a
>> +good way to know that it's working in a very simple way). One problem
>> +with coresight is that given a large enough amount of data needing to
>> +be logged, some of it can be lost due to the processor not waking up
>> +in time to read out all the data from buffers etc.. You will notice
>> +that the amount of data collected can vary a lot per run of perf test.
>> +If you wish to see how this changes over time, simply run perf test
>> +multiple times and all these csv files will have more and more data
>> +appended to it that you can later examine, graph and otherwise use to
>> +figure out if things have become worse or better.
>> +
>> +Be aware that amny of these tests take quite a while to run, specifically
>> +in processing the perf data file and dumping contents to then examine what
>> +is inside.
>> +
>> +You can change where these csv logs are stored by setting the
>> +PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
>> +test like:
>> +
>> + export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
>> + perf test
>> +
>> +They will also store resulting perf output data in the current
>> +directory for later inspection like:
>> +
>> + perf-memcpy-1m.data
>> + perf-thread_loop-2th.data
>> + ...
>> +
>> +You can alter where the perf data files are stored by setting the
>> +PERF_TEST_CORESIGHT_DATADIR environment variable such as:
>> +
>> + PERF_TEST_CORESIGHT_DATADIR=/var/tmp
>> + perf test
>> +
>> +You may wish to set these above environment variables if you which to
>> +keep the output of tests outside of the current working directory for
>> +longer term storage and examination.
>>

2022-03-11 22:35:15

by Carsten Haitzler

[permalink] [raw]
Subject: Re: [PATCH 12/12] perf test: Add docs for coresight and related tests

I have an updated patch set queued to send out, so responding now. I've
addressed various things. See below.

On 1/19/22 16:43, James Clark wrote:
>
>
> On 15/12/2021 16:04, [email protected] wrote:
>> From: Carsten Haitzler <[email protected]>
>>
>> This adds documentation about the coresight specific tests as part of
>> perf test
>>
>> Signed-off-by: Carsten Haitzler <[email protected]>
>
> I will use this commit to comment on the set as a whole. The other comments about
> specific issues I have left inline.
>
> I ran the tests twice on N1SDP (kernel version perf/core 48ffaedf017ad) and had two
> different sets of failures, indicating some flakyness, which is one reason to not have
> tests with magic numbers as Leo has raised. Are you able to give a complete list of
> where you have run these so far? I know we can't check everywhere, but at least all
> of Arm's own reference platforms should be passing.
>
> First run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!
> 99: Coresight / Unroll Loop Thread 2 : FAILED!
>
> Second run:
>
> 92: Coresight / Thread Loop 25 Threads : FAILED!
> 94: Coresight / Thread Loop 10 Threads - Check TID : FAILED!
> 95: Coresight / Thread Loop 2 Threads - Check TID : FAILED!
> 96: Coresight / Thread Loop 250 Threads - Check TID : FAILED!
> 97: Coresight / Unroll Loop Thread 1 : FAILED!

Yes. There is actual problems at the data production end of the
pipeline. Let me just focus on one of the type of examples. The Check
TID examples look for some thread data for each thread that runs in the
sample. If they do not get at least one such context id that matches a
thread ID (as that is what the contextid does map to) then it will fail.
We're missing that. It's not reliable. The tests show this. They don't
fix it, but the point of these tests is to find issues so we know what
issues exist before any data is decoded.

> I have pasted the verbose output of two of these at the very end.
>
> The major problem I have with the tests is the time that they take to run. Now
> a full test run takes 31m+ on N1SDP, where previously it took 1m 9s. There are
> quite a few reasons why this isn't a good idea. It will take extra cycles on
> anyone's CI and that means it will now take longer for anyone to make any changes
> if they run the tests, slowing down all Perf work from now onward. Even if you
> want to run just the Coresight tests, it doesn't really help as that is 90% of
> the time taken, so personally for me I'm not likely to run them while working on
> Coresight changes. The longer the tests take the more likely it is that they are
> skipped, reducing the benefits of the tests. Also if anyone has timeouts set on > CI these are likely going to have to be adjusted now.

In my new patch set I've removed a lot of the tests and kept only a
smaller set. In my tests it now takes about 3-8 mins to run instead of
about 1 min (It's variable because the amount of data collected can be
highly variable and 99% of the time in these tests is spend dumping the
perf data to see what is in there and this is time consuming. If the
test produces 2x the data vs last run it takes a lot longer to dump and
this actually happens).

> Is it possible to get the run time of each test down to 5-10 seconds? This will
> make it much nicer for us to work with going forwards.

Unfortunately I can't get it down to that. As above. The TID tests are
fairly short but sometimes produce 20m perf data files, sometimes 80m
sometimes 130m... it's indeterminate even if the actual test itself is
constant (runs the same identical workload). I can cut down the number
of tests and squeeze down the loop runs etc. which I have now done, but
we still have the above problem.

> I'd also have liked to have had a discussion on the mailing list about what the test
> methodology should be in general before starting. For example for this patch set it
> looks like the coverage is quite wide because of the number of tests and time it
> takes to run, but actually they all use "cs_etm//u -- <process>" as the run command.
> This only tests per-process userspace mode resulting in very narrow coverage.
> And there is no mention in a cover letter about how this expands on or interacts
> with the existing test_arm_coresight.sh test which I don't think can be ignored.
> For example it iterates over sinks. Could that same iteration not be applied to
> these tests? They seem to exist in isolation and it's not clear which one we should
> be adding to going forwards.

It's a more "extensible harness" to just drop many varieties of tests
into - e.g. the TID example s- do we collect thread data from every
thread? They also store "quality" of data over time in CSV files. You
can clearly see the high variability coming out of the tests there. They
include actual test tools/source (don't just run some existing binary
like touch) thus control what is being recorded. I built them to be
easily expanded over time with more specific case tests by just dropping
in a new directory with a new tool and.or a new script in the tests dir
to use that tool or an existing one and re-use shared functions etc.

And yes - it tests only userspace (for now). Rome was not built in a
day. It's testing userspace as that is what is being controlled (by the
test tools). Tracing kernel code is another problem and thing to test. I
was hoping this is a start and that's why it's built as a more extensive
harness to be re-used and expanded on.

> I'd like to see a much more exploration of the different modes and flags to justify
> such a high run time:
>
> * per-CPU
> * per-thread
> * with and without timestamps
> * strobing

All future problems to solve.

> If this is supposed to be just an initial implementation covering one case, then
> by the "test one thing" ethos, there should only be one test case. Each case
> should be testing one thing with minimal overlapping. But it looks like tests like

Different workloads. Provide something that should have a large amount
of instructions to trace across lots of memory as opposed to small tight
loops. What do we collect then? Do we collect data across multiple
threads? If we keep every core busy, then what? Due to the way data is
collected (buffers/interrupts), it's a lossy exercise and Having
different workloads to see where we might not collect as much data as
we'd like is useful. That's why there are multiple tests.

> "Thread loop 10" and "thread loop 250" just test the same thing, and I don't see
> the value in maintaining that. Also "bubblesort" and "memcpy" don't have comments
> explaining why running on those two different test programs actually makes a
> difference. Obviously this comment is partially related to the run time, if it was
> shorter perhaps it would be less important how many variations we ran.

Those were existing tests being used in test_etm (out of kernel tree)
already so I put them in as they were seemingly good enough there so
perf test would become a superset of the above and add more.

The runtime is almost entirely due to perf dump. I spent a little time
profiling perf dump and didn't see any obvious hotspots to quickly pick
low hanging fruit from.

> It's also not clear what failure modes the tests are looking for. There are
> comments like "We should almost always see F3 atoms", but it's not clear how
> F3 atoms are a signal of a high quality trace. And there are numbers like:
>
> perf_dump_aux_verify "$DATA" 66 6 6
> perf_dump_aux_verify "$DATA" 4188 1630 1630

Think of it measuring the body - seeing some amount as opposed to none
or only 1 ... yes- this is measuring the compressed encoding but it's
one of the very common ones so it was a quick way to do this as opposed
to completely decoding the data and then checking that (which would be
more costly and make tests take longer). I did have high-ish numbers but
they were actually a result of going "well on most runs we tend to get X
in real life so if we get X/10 we should have enough". Yes - 1 or 2 or
10 could also be sensible as it is lossy and we should collect SOME
data, but preferably we should be collecting more. If we would not have
a lossy process that collected everything we should get a stable amount
of data collected... that would be the goal eventually.

> but there are no comments to say how 66 or 4188 were judged to be "high quality" vs
> any other number. This means that anyone encountering a failure is just going to
> change the number until it passes, undoing any value that the test added. If the tests
> are looking for complete loss of data, then > 1 or > 2 would be sufficient. But if
> someone makes a mistake in the driver to produce less data, then these tests aren't
> going to catch that anyway, since there is a chance that it falls within the allowed
> thresholds.

That's actually the point. Imagine someone makes a change in the driver
that now loses 60% of the trace data. If we just assume any amount of
loss is just fine - we'd never know unless we have tests measuring this
until eventually some time later someone wonders why their profile data
is so variable... this is exactly why the tests store the data they
collect over time in csv files so you can see trends or points where
suddenly data took a hit or jumped up to collect more.

> In my opinion a much better measure of quality would be to look at the coverage of
> fully decoded trace, for example if you have 10 functions called from a loop across
> multiple DSOs, do each of those functions show up in synthesised instruction samples.

That would be more expensive to do (and make the tests take longer)
which goes against some of your desires above. This would be another
stage in the tests beyond what they do (Rome was not built in a day :)).
Coverage would then tell us if we cover the function at least once. How
many times do we cover it? If it runs 10000 times do we get trace data
for all of its 10000 executions? or only 100 of them? or 10? or 1? This
is certainly much more involved and an evolution of tests to do more.
I'm not sure I should sit and make the test do everything possible and
test everything from day 1. Start with a base that is intended to expand
cleanly and in a "modular" way and then build from there. I've learned
over the years to always build things in steps and get your groundwork
good before going the next step. I'm doing this here. Groundwork with
some exercising of it.

> Which brings me to my next point, the tests only seem to look at the raw trace, rather
> than the synthesised samples. To me this seems like it's validating what comes out of
> the CPU more than looking at what the driver or userspace Perf are doing. I think this

100% correct. Or more looking at what comes out of the kernel perf
driver into perf data files. It's focusing on this part of the pipeline
- not the "decode that data and do something useful with it" part. I
specifically focused on this part as this is a source of data loss and
quality of data. You can have the best decoding on the planet - if your
input data is poor ... you will have poor results. I also understood
that you were working on the other end of the pipeline (the decode/do
something with it end) and thus thought I'd fill in the part you were
not working on rather than conflict with the stuff you are doing.

> isn't the right place for these tests to live and would be better suited to run on bare
> metal. This is because a user isn't going to be interested in how many F3 atoms there are,
> that's just an implementation detail. What's much more valuable is what samples are
> synthesised. We're also skipping most of the code in Perf by only looking at the raw
> trace, which makes it harder to justify putting the tests in the Perf code base.

Then then we would have our tests fragmented. Testing kernel output
won't have tests in the kernel tree for the data/subsystem that is
reading/collecting/writinf that data...

> In short I think it would be much better if we had the following:
>
> * Much shorter run time

Done. Patches coming.

> * Run each test program only once (for example it doesn't add value to run memcpy with different sizes)

Done mostly as above (except the TID test where I'm down to 2 tests).

> * Only one test for each thing/failure mode

Done - mostly, as above.

> * Much less overlapping test code (for example F3 atoms only need to be counted for one test, not all of them)

It's measuring if we have test "body". I could do this in more expensive
ways in addition to the metadata blocks (async and trace info).

> * Concrete descriptions of failure modes and what each test is looking for

I haven't done this yet - let me send a new patch set which is smaller
and we'll go from there.

> * Small magic numbers which are easy to justify (like "samples < 1, check for complete loss of data")

Done.

> * Run through the full Perf pipeline and look at the synthesised samples rather than raw trace

I thought you were dealing with this end?

> * Some thought about how this fits in with test_arm_coresight.sh

As above - more of an extended harness to add to over time rather than a
single test that fails or succeeds - its broken down into many tests so
you know which succeed or fail. I've dealt with tests units that merge
dozens or even 100+ tests into a single case and then just report fail
or succeed and it's very annoying as you don't get an isolated result to
tell you what you broke. If this single shell script keeps getting more
and more things to test then .. which one broke when all you see is a
single fail? It's a time sink to go digging every time. Broken cleanly
into multiple tests is far better.

> Thanks
> James
>
>
>
> Test failure outputs:
> ---
>
> 94: Coresight / Thread Loop 10 Threads - Check TID :
> --- start ---
> test child forked, pid 5821
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 128.106 MB ./perf-thread_loop-check-tid-10th.data ]
>
>
>
> Warning:
> AUX data lost 1 times out of 1!
>
> Thread IDs not found in perf AUX data
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 10 Threads - Check TID: FAILED!
>
> ========================================================
>
>
> 92: Coresight / Thread Loop 25 Threads :
> --- start ---
> test child forked, pid 5871
> Couldn't synthesize bpf events.
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 28.849 MB ./perf-thread_loop-25th.data ]
> Sanity check number of ATOM_F3 is too low (92062 < 388121)
> test child finished with -1
> ---- end ----
> Coresight / Thread Loop 25 Threads: FAILED!
>
>
>> ---
>> MAINTAINERS | 1 +
>> tools/perf/Documentation/arm-coresight.txt | 140 +++++++++++++++++++++
>> 2 files changed, 141 insertions(+)
>> create mode 100644 tools/perf/Documentation/arm-coresight.txt
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index d46e8469c467..1a93977a0132 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1890,6 +1890,7 @@ F: Documentation/trace/coresight/*
>> F: drivers/hwtracing/coresight/*
>> F: include/dt-bindings/arm/coresight-cti-dt.h
>> F: include/linux/coresight*
>> +F: tools/perf/Documentation/arm-coresight.txt
>> F: tools/perf/arch/arm/util/auxtrace.c
>> F: tools/perf/arch/arm/util/cs-etm.c
>> F: tools/perf/arch/arm/util/cs-etm.h
>> diff --git a/tools/perf/Documentation/arm-coresight.txt b/tools/perf/Documentation/arm-coresight.txt
>> new file mode 100644
>> index 000000000000..3a9e6c573c58
>> --- /dev/null
>> +++ b/tools/perf/Documentation/arm-coresight.txt
>> @@ -0,0 +1,140 @@
>> +Arm Coresight Support
>> +=====================
>> +
>> +Coresight is a feature of some Arm based processors that allows for
>> +debugging. One of the things it can do is trace every instruction
>> +executed and remotely expose that information in a hardware compressed
>> +stream. Perf is able to locally access that stream and store it to the
>> +output perf data files. This stream can then be later decoded to give the
>> +instructions that were traced for debugging or profiling purposes. You
>> +can log such data with a perf record command like:
>> +
>> + perf record -e cs_etm//u testbinary
>> +
>> +This would run some test binary (testbinary) until it exits and record
>> +a perf.data trace file. That file would have AUX sections if coresight
>> +is working correctly. You can dump the content of this file as
>> +readable text with a command like:
>> +
>> + perf report --stdio --dump -i perf.data
>> +
>> +You should find some sections of this file have AUX data blocks like:
>> +
>> + 0x1e78 [0x30]: PERF_RECORD_AUXTRACE size: 0x11dd0 offset: 0 ref: 0x1b614fc1061b0ad1 idx: 0 tid: 531230 cpu: -1
>> +
>> + . ... CoreSight ETM Trace data: size 73168 bytes
>> + Idx:0; ID:10; I_ASYNC : Alignment Synchronisation.
>> + Idx:12; ID:10; I_TRACE_INFO : Trace Info.; INFO=0x0 { CC.0 }
>> + Idx:17; ID:10; I_ADDR_L_64IS0 : Address, Long, 64 bit, IS0.; Addr=0x0000000000000000;
>> + Idx:26; ID:10; I_TRACE_ON : Trace On.
>> + Idx:27; ID:10; I_ADDR_CTXT_L_64IS0 : Address & Context, Long, 64 bit, IS0.; Addr=0x0000FFFFB6069140; Ctxt: AArch64,EL0, NS;
>> + Idx:38; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:39; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:40; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEEEEEEEEEEEEEE
>> + Idx:41; ID:10; I_ATOM_F6 : Atom format 6.; EEEEEEEEEEEN
>> + ...
>> +
>> +If you see these above, then your system is tracing coresight data
>> +correctly.
>> +
>> +To compile perf with coresight support in the perf directory do
>> +
>> + make CORESIGHT=1
>> +
>> +This will compile the perf tool with coresight support as well as
>> +build some small test binaries for perf test. This requires you also
>> +be compiling for 64bit Arm (ARM64/aarch64). The tools run as part of
>> +perf coresight tracing are in tests/shell/tools/coresight.
>> +
>> +You will also want coresight support enabled in your kernel config.
>> +Ensure it is enabled with:
>> +
>> + CONFIG_CORESIGHT=y
>> +
>> +There are various other coresight options you probably also want
>> +enabled like:
>> +
>> + CONFIG_CORESIGHT_LINKS_AND_SINKS=y
>> + CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
>> + CONFIG_CORESIGHT_CATU=y
>> + CONFIG_CORESIGHT_SINK_TPIU=y
>> + CONFIG_CORESIGHT_SINK_ETBV10=y
>> + CONFIG_CORESIGHT_SOURCE_ETM4X=y
>> + CONFIG_CORESIGHT_STM=y
>> + CONFIG_CORESIGHT_CPU_DEBUG=y
>> + CONFIG_CORESIGHT_CTI=y
>> + CONFIG_CORESIGHT_CTI_INTEGRATION_REGS=y
>> +
>> +Please refer to the kernel configuration help for more information.
>> +
>> +Perf test - Verify kernel and userspace perf coresight work
>> +===========================================================
>> +
>> +When you run perf test, it will do a lot of self tests. Some of those
>> +tests will cover Coresight (only if enabled and on ARM64). You
>> +generally would run perf test from the tools/perf directory in the
>> +kernel tree. Some tests will check some internal perf support like:
>> +
>> + Check Arm CoreSight trace data recording and synthesized samples
>> +
>> +Some others will actually use perf record and some test binaries that
>> +are in tests/shell/tools/coresight and will collect traces to ensure a
>> +minimum level of functionality is met. The scripts that launch these
>> +tests are in tests/shell. These will all look like:
>> +
>> + Coresight / Memcpy 1M 25 Threads
>> + Coresight / Unroll Loop Thread 2
>> + ...
>> +
>> +These perf record tests will not run if the tool binaries do not exist
>> +in tests/shell/tools/coresight/*/ and will be skipped. If you do not
>> +have coresight support in hardware then either do not build perf with
>> +coresight support or remove these binaries in order to not have these
>> +tests fail and have them skip instead.
>> +
>> +These tests will log historical results in the current working
>> +directory (e.g. tools/perf) and will be named stats-*.csv like:
>> +
>> + stats-asm_pure_loop-out.csv
>> + stats-bubble_sort-random.csv
>> + ...
>> +
>> +These statistic files log some aspects of the AUX data sections in
>> +the perf data output counting some numbers of certain encodings (a
>> +good way to know that it's working in a very simple way). One problem
>> +with coresight is that given a large enough amount of data needing to
>> +be logged, some of it can be lost due to the processor not waking up
>> +in time to read out all the data from buffers etc.. You will notice
>> +that the amount of data collected can vary a lot per run of perf test.
>> +If you wish to see how this changes over time, simply run perf test
>> +multiple times and all these csv files will have more and more data
>> +appended to it that you can later examine, graph and otherwise use to
>> +figure out if things have become worse or better.
>> +
>> +Be aware that amny of these tests take quite a while to run, specifically
>> +in processing the perf data file and dumping contents to then examine what
>> +is inside.
>> +
>> +You can change where these csv logs are stored by setting the
>> +PERF_TEST_CORESIGHT_STATDIR environment variable before running perf
>> +test like:
>> +
>> + export PERF_TEST_CORESIGHT_STATDIR=/var/tmp
>> + perf test
>> +
>> +They will also store resulting perf output data in the current
>> +directory for later inspection like:
>> +
>> + perf-memcpy-1m.data
>> + perf-thread_loop-2th.data
>> + ...
>> +
>> +You can alter where the perf data files are stored by setting the
>> +PERF_TEST_CORESIGHT_DATADIR environment variable such as:
>> +
>> + PERF_TEST_CORESIGHT_DATADIR=/var/tmp
>> + perf test
>> +
>> +You may wish to set these above environment variables if you which to
>> +keep the output of tests outside of the current working directory for
>> +longer term storage and examination.
>>