/* Copyright (C) 2003,2004 Andi Kleen, SuSE Labs.
   Test/demo program for libnuma. This is also a more or less useful benchmark
   of the NUMA characteristics of your machine. It benchmarks most possible
   NUMA policy memory configurations with various benchmarks.
   Compile standalone with cc -O2 numademo.c -o numademo -lnuma -lm

   numactl is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; version
   2.

   numactl is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should find a copy of v2 of the GNU General Public License somewhere
   on your Linux system; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define _GNU_SOURCE 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/time.h>
#include "numa.h"
#ifdef HAVE_STREAM_LIB
#include "stream_lib.h"
#endif
#ifdef HAVE_MT
#include "mt.h"
#endif
#ifdef HAVE_CLEAR_CACHE
#include "clearcache.h"
#else
static inline void clearcache(void *a, unsigned size) {}
#endif
#define FRACT_NODES 8
#define FRACT_MASKS 32
int fract_nodes;
int *node_to_use;
unsigned long msize;

/* Should get this from cpuinfo, but on !x86 it's not there */
enum {
	CACHELINESIZE = 64,
};

enum test {
	MEMSET = 0,
	MEMCPY,
	FORWARD,
	BACKWARD,
	STREAM,
	RANDOM2,
	PTRCHASE,
} thistest;

char *delim = " ";
int force;
int regression_testing=0;

char *testname[] = {
	"memset",
	"memcpy",
	"forward",
	"backward",
#ifdef HAVE_STREAM_LIB
	"stream",
#endif
#ifdef HAVE_MT
	"random2",
#endif
	"ptrchase",
	NULL,
};

void output(char *title, char *result)
{
	if (!isspace(delim[0]))
		printf("%s%s%s\n", title,delim, result);
	else
		printf("%-42s%s\n", title, result);
}

#ifdef HAVE_STREAM_LIB
void do_stream(char *name, unsigned char *mem)
{
	int i;
	char title[100], buf[100];
	double res[STREAM_NRESULTS];
	stream_verbose = 0;
	clearcache(mem, msize);
	stream_init(mem);
	stream_test(res);
	sprintf(title, "%s%s%s", name, delim, "STREAM");
	buf[0] = '\0';
	for (i = 0; i < STREAM_NRESULTS; i++) {
		if (buf[0])
			strcat(buf,delim);
		sprintf(buf+strlen(buf), "%s%s%.2f%sMB/s",
			stream_names[i], delim, res[i], delim);
	}
	output(title, buf);
	clearcache(mem, msize);
}
#endif

/* Set up a randomly distributed list to fool prefetchers */
union node {
	union node *next;
	struct {
		unsigned nexti;
		unsigned val;
	};
};

static int cmp_node(const void *ap, const void *bp)
{
	union node *a = (union node *)ap;
	union node *b = (union node *)bp;
	return a->val - b->val;
}

void **ptrchase_init(unsigned char *mem)
{
	long i;
	union node *nodes = (union node *)mem;
	long nmemb = msize / sizeof(union node);
	srand(1234);
	for (i = 0; i < nmemb; i++) {
		nodes[i].val = rand();
		nodes[i].nexti = i + 1;
	}
	qsort(nodes, nmemb, sizeof(union node), cmp_node);
	for (i = 0; i < nmemb; i++) {
		union node *n = &nodes[i];
		n->next = n->nexti >= nmemb ? NULL : &nodes[n->nexti];
	}
	return (void **)nodes;
}

static inline unsigned long long timerfold(struct timeval *tv)
{
	return tv->tv_sec * 1000000ULL + tv->tv_usec;
}

#define LOOPS 10

void memtest(char *name, unsigned char *mem)
{
	long k;
	struct timeval start, end, res;
	unsigned long long max, min, sum, r;
	int i;
	char title[128], result[128];

	if (!mem) {
		fprintf(stderr,
		"Failed to allocate %lu bytes of memory. Test \"%s\" exits.\n",
			msize, name);
		return;
	}

#ifdef HAVE_STREAM_LIB
	if (thistest == STREAM) {
		do_stream(name, mem);
		goto out;
	}
#endif

	max = 0;
	min = ~0UL;
	sum = 0;

	/*
	 * Note:  0th pass allocates the pages, don't measure
	 */
	for (i = 0; i < LOOPS+1; i++) {
		clearcache(mem, msize);
		switch (thistest) {
		case PTRCHASE:
		{
			void **ptr;
			ptr = ptrchase_init(mem);
			gettimeofday(&start,NULL);
			while (*ptr)
				ptr = (void **)*ptr;
			gettimeofday(&end,NULL);
			/* Side effect to trick the optimizer */
			*ptr = "bla";
			break;
		}

		case MEMSET:
			gettimeofday(&start,NULL);
			memset(mem, 0xff, msize);
			gettimeofday(&end,NULL);
			break;

		case MEMCPY:
			gettimeofday(&start,NULL);
			memcpy(mem, mem + msize/2, msize/2);
			gettimeofday(&end,NULL);
			break;

		case FORWARD:
			/* simple kernel to just fetch cachelines and write them back.
			   will trigger hardware prefetch */
			gettimeofday(&start,NULL);
			for (k = 0; k < msize; k+=CACHELINESIZE)
				mem[k]++;
			gettimeofday(&end,NULL);
			break;

		case BACKWARD:
			gettimeofday(&start,NULL);
			for (k = msize-5; k > 0; k-=CACHELINESIZE)
				mem[k]--;
			gettimeofday(&end,NULL);
			break;

#ifdef HAVE_MT
		case RANDOM2:
		{
			unsigned * __restrict m = (unsigned *)mem;
			unsigned max = msize / sizeof(unsigned);
			unsigned mask;

			mt_init();
			mask = 1;
			while (mask < max)
				mask = (mask << 1) | 1;
			/*
			 * There's no guarantee all memory is touched, but
			 * we assume (hope) that the distribution of the MT
			 * is good enough to touch most.
			 */
			gettimeofday(&start,NULL);
			for (k = 0; k < max; k++) {
				unsigned idx = mt_random() & mask;
				if (idx >= max)
					idx -= max;
				m[idx]++;
			}
			gettimeofday(&end,NULL);
		}

#endif
		default:
			break;
		}

		if (!i)
			continue;  /* don't count allocation pass */

		timersub(&end, &start, &res);
		r = timerfold(&res);
		if (r > max) max = r;
		if (r < min) min = r;
		sum += r;
	}
	sprintf(title, "%s%s%s", name, delim, testname[thistest]);
#define H(t) (((double)msize) / ((double)t))
#define D3 delim,delim,delim
	sprintf(result, "Avg%s%.2f%sMB/s%sMax%s%.2f%sMB/s%sMin%s%.2f%sMB/s",
		delim,
		H(sum/LOOPS),
		D3,
		H(min),
		D3,
		H(max),
		delim);
#undef H
#undef D3
	output(title,result);

#ifdef HAVE_STREAM_LIB
 out:
#endif
	/* Just to make sure that when we switch CPUs that the old guy
	   doesn't still keep it around. */
	clearcache(mem, msize);

	numa_free(mem, msize);
}

int popcnt(unsigned long val)
{
	int i = 0, cnt = 0;
	while (val >> i) {
		if ((1UL << i) & val)
			cnt++;
		i++;
	}
	return cnt;
}

int max_node, numnodes;

void get_node_list()
{
        int a, got_nodes = 0;
        long free_node_sizes;

        numnodes = numa_num_configured_nodes();
        node_to_use = (int *)malloc(numnodes * sizeof(int));
        max_node = numa_max_node();
        for (a = 0; a <= max_node; a++) {
                if(numa_node_size(a, &free_node_sizes) != -1)
                        node_to_use[got_nodes++] = a;
        }
}

void test(enum test type)
{
	unsigned long mask;
	int i, k;
	char buf[512];
	struct bitmask *nodes;

	nodes = numa_allocate_nodemask();
	thistest = type;

	if (regression_testing) {
		printf("\nTest %s doing 1 of %d nodes and 1 of %d masks.\n",
			testname[thistest], fract_nodes, FRACT_MASKS);
	}

	memtest("memory with no policy", numa_alloc(msize));
	memtest("local memory", numa_alloc_local(msize));

	memtest("memory interleaved on all nodes", numa_alloc_interleaved(msize));
	for (i = 0; i < numnodes; i++) {
		if (regression_testing && (node_to_use[i] % fract_nodes)) {
		/* for regression testing (-t) do only every eighth node */
			continue;
		}
		sprintf(buf, "memory on node %d", node_to_use[i]);
		memtest(buf, numa_alloc_onnode(msize, node_to_use[i]));
	}

	for (mask = 1, i = 0; mask < (1UL<<numnodes); mask++, i++) {
		int w;
		char buf2[20];
		if (popcnt(mask) == 1)
			continue;
		if (regression_testing && (i > 50)) {
			break;
		}
		if (regression_testing && (i % FRACT_MASKS)) {
		/* for regression testing (-t)
			do only every 32nd mask permutation */
			continue;
		}
		numa_bitmask_clearall(nodes);
		for (w = 0; mask >> w; w++) {
			if ((mask >> w) & 1)
				numa_bitmask_setbit(nodes, w);
		}

		sprintf(buf, "memory interleaved on");
		for (k = 0; k < numnodes; k++)
			if ((1UL<<node_to_use[k]) & mask) {
				sprintf(buf2, " %d", node_to_use[k]);
				strcat(buf, buf2);
			}
		memtest(buf, numa_alloc_interleaved_subset(msize, nodes));
	}

	for (i = 0; i < numnodes; i++) {
		if (regression_testing && (node_to_use[i] % fract_nodes)) {
		/* for regression testing (-t) do only every eighth node */
			continue;
		}
		printf("setting preferred node to %d\n", node_to_use[i]);
		numa_set_preferred(node_to_use[i]);
		memtest("memory without policy", numa_alloc(msize));
	}

	numa_set_interleave_mask(numa_all_nodes_ptr);
	memtest("manual interleaving to all nodes", numa_alloc(msize));

	if (numnodes > 0) {
		numa_bitmask_clearall(nodes);
		numa_bitmask_setbit(nodes, 0);
		numa_bitmask_setbit(nodes, 1);
		numa_set_interleave_mask(nodes);
		memtest("manual interleaving on node 0/1", numa_alloc(msize));
		printf("current interleave node %d\n", numa_get_interleave_node());
	}

	numa_set_interleave_mask(numa_no_nodes_ptr);

	nodes = numa_allocate_nodemask();

	for (i = 0; i < numnodes; i++) {
		int oldhn = numa_preferred();

		if (regression_testing && (node_to_use[i] % fract_nodes)) {
		/* for regression testing (-t) do only every eighth node */
			continue;
		}
		numa_run_on_node(node_to_use[i]);
		printf("running on node %d, preferred node %d\n",node_to_use[i], oldhn);

		memtest("local memory", numa_alloc_local(msize));

		memtest("memory interleaved on all nodes",
			numa_alloc_interleaved(msize));

		if (numnodes >= 2) {
			numa_bitmask_clearall(nodes);
			numa_bitmask_setbit(nodes, 0);
			numa_bitmask_setbit(nodes, 1);
			memtest("memory interleaved on node 0/1",
				numa_alloc_interleaved_subset(msize, nodes));
		}

		for (k = 0; k < numnodes; k++) {
			if (node_to_use[k] == node_to_use[i])
				continue;
			if (regression_testing && (node_to_use[k] % fract_nodes)) {
			/* for regression testing (-t)
				do only every eighth node */
				continue;
			}
			sprintf(buf, "alloc on node %d", node_to_use[k]);
			numa_bitmask_clearall(nodes);
			numa_bitmask_setbit(nodes, node_to_use[k]);
			numa_set_membind(nodes);
			memtest(buf, numa_alloc(msize));
			numa_set_membind(numa_all_nodes_ptr);
		}

		numa_set_localalloc();
		memtest("local allocation", numa_alloc(msize));

		numa_set_preferred((node_to_use[i]+1) % numnodes );
		memtest("setting wrong preferred node", numa_alloc(msize));
		numa_set_preferred(node_to_use[i]);
		memtest("setting correct preferred node", numa_alloc(msize));
		numa_set_preferred(-1);
		if (!delim[0])
			printf("\n\n\n");
	}

	/* numa_run_on_node_mask is not tested */
}

void usage(void)
{
	int i;
	printf("usage: numademo [-S] [-f] [-c] [-e] [-t] msize[kmg] {tests}\nNo tests means run all.\n");
	printf("-c output CSV data. -f run even without NUMA API. -S run stupid tests. -e exit on error\n");
	printf("-t regression test; do not run all node combinations\n");
	printf("valid tests:");
	for (i = 0; testname[i]; i++)
		printf(" %s", testname[i]);
	putchar('\n');
	exit(1);
}

/* duplicated to make numademo standalone */
long memsize(char *s)
{
	char *end;
	long length = strtoul(s,&end,0);
	switch (toupper(*end)) {
	case 'G': length *= 1024;  /*FALL THROUGH*/
	case 'M': length *= 1024;  /*FALL THROUGH*/
	case 'K': length *= 1024; break;
	}
	return length;
}

int main(int ac, char **av)
{
	int simple_tests = 0;

	while (av[1] && av[1][0] == '-') {
		ac--;
		switch (av[1][1]) {
		case 'c':
			delim = ",";
			break;
		case 'f':
			force = 1;
			break;
		case 'S':
			simple_tests = 1;
			break;
		case 'e':
			numa_exit_on_error = 1;
			numa_exit_on_warn = 1;
			break;
		case 't':
			regression_testing = 1;
			break;
		default:
			usage();
			break;
		}
		++av;
	}

	if (!av[1])
		usage();

	if (numa_available() < 0) {
		printf("your system does not support the numa API.\n");
		if (!force)
			exit(1);
	}
	get_node_list();
	printf("%d nodes available\n", numnodes);
	fract_nodes = (((numnodes-1)/8)*2) + FRACT_NODES;

	if (numnodes <= 3)
		regression_testing = 0; /* set -t auto-off for small systems */

	msize = memsize(av[1]);

	if (!msize)
		usage();

#ifdef HAVE_STREAM_LIB
	stream_setmem(msize);
#endif

	if (av[2] == NULL) {
		test(MEMSET);
		test(MEMCPY);
		if (simple_tests) {
			test(FORWARD);
			test(BACKWARD);
		}
#ifdef HAVE_MT
		test(RANDOM2);
#endif
#ifdef HAVE_STREAM_LIB
		test(STREAM);
#endif
		if (msize >= sizeof(union node)) {
			test(PTRCHASE);
		} else {
			fprintf(stderr, "You must set msize at least %lu bytes for ptrchase test.\n",
				sizeof(union node));
			exit(1);
		}
	} else {
		int k;
		for (k = 2; k < ac; k++) {
			int i;
			int found = 0;
			for (i = 0; testname[i]; i++) {
				if (!strcmp(testname[i],av[k])) {
					test(i);
					found = 1;
					break;
				}
			}
			if (!found) {
				fprintf(stderr,"unknown test `%s'\n", av[k]);
				usage();
			}
		}
	}
	return 0;
}
