1/*
2 * Copyright (c) 2014 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9#include <string.h>
10#include <stdlib.h>
11#include <omp.h>
12
13#include <barrelfish/barrelfish.h>
14#include <barrelfish/nameservice_client.h>
15
16#include <xeon_phi/xeon_phi.h>
17#include <xeon_phi/xeon_phi_domain.h>
18
19#include <bench/bench.h>
20#include <xomp/xomp.h>
21
22#define BENCH_MEASURE_LOCAL 0
23
24#define BENCH_RUN_COUNT 25
25#define BENCH_RUN_SINGLE 0
26
27#define DEBUG(x...) debug_printf(x)
28
29#define EXPECT_SUCCESS(errval, msg) \
30    if (err_is_fail(err)) {USER_PANIC_ERR(err, msg);}
31
32static uint32_t nthreads;
33
34static cycles_t timer_xompinit;
35
36#define SCHEDULE static
37#define CHUNK    25
38
39#define MATRIX_TYPE uint64_t
40#define MATRIX_ROWS 1000
41#define MATRIX_COLS 1000
42#define MATRIX_ELEMENTS (MATRIX_ROWS * MATRIX_COLS)
43
44static void prepare_bomp(void)
45{
46    debug_printf("prepare_bomp\n");
47    cycles_t tsc_start = bench_tsc();
48    bomp_bomp_init(nthreads);
49    cycles_t tsc_end = bench_tsc();
50    timer_xompinit = bench_time_diff(tsc_start, tsc_end);
51}
52
53static int prepare_xomp(int argc,
54                        char *argv[])
55{
56    errval_t err;
57
58    xomp_wloc_t location = XOMP_WORKER_LOC_MIXED;
59    for (int i = 3; i < argc; ++i) {
60        if (!strncmp(argv[i], "--location=", 11)) {
61            char *p = strchr(argv[i], '=');
62            p++;
63            if (!strcmp(p, "local")) {
64                location = XOMP_WORKER_LOC_LOCAL;
65            }
66        }
67    }
68
69    if (location == XOMP_WORKER_LOC_MIXED) {
70        debug_printf("waiting for xeon phi to be ready\n");
71        err = xeon_phi_domain_blocking_lookup("xeon_phi.0.ready", NULL);
72        EXPECT_SUCCESS(err, "nameservice_blocking_lookup");
73        err = xeon_phi_domain_blocking_lookup("xeon_phi.1.ready", NULL);
74        EXPECT_SUCCESS(err, "nameservice_blocking_lookup");
75
76#if XOMP_BENCH_ENABLED
77        xomp_master_bench_enable(BENCH_RUN_COUNT, nthreads,
78                        XOMP_MASTER_BENCH_MEM_ADD);
79#endif
80    }
81
82    struct xomp_spawn local_info = {
83        .argc = argc,
84        .argv = argv,
85#ifdef __k1om__
86        .path = "/k1om/sbin/benchmarks/bomp_mm",
87#else
88                    .path = "/x86_64/sbin/benchmarks/bomp_mm",
89#endif
90                };
91
92    struct xomp_spawn remote_info = {
93        .argc = argc,
94        .argv = argv,
95        .path = "/k1om/sbin/benchmarks/bomp_mm",
96    };
97
98    struct xomp_args xomp_arg = {
99        .type = XOMP_ARG_TYPE_DISTINCT,
100        .core_stride = 0,  // use default
101        .args = {
102            .distinct = {
103                .nthreads = nthreads,
104                .worker_loc = location,
105                .nphi = 2,
106                .local = local_info,
107                .remote = remote_info
108            }
109        }
110    };
111
112    cycles_t tsc_start = bench_tsc();
113    if (bomp_xomp_init(&xomp_arg)) {
114        debug_printf("bomp init failed!\n");
115        exit(1);
116    }
117    cycles_t tsc_end = bench_tsc();
118    timer_xompinit = bench_time_diff(tsc_start, tsc_end);
119
120    return (location == XOMP_WORKER_LOC_LOCAL);
121}
122
123int main(int argc,
124         char *argv[])
125{
126    errval_t err;
127    xomp_wid_t wid;
128
129    bench_init();
130
131    err = xomp_worker_parse_cmdline(argc, argv, &wid);
132    if (err_is_ok(err)) {
133        struct xomp_args xw_arg = {
134            .type = XOMP_ARG_TYPE_WORKER,
135            .args = {
136                .worker = {
137                    .id = wid
138                }
139            }
140        };
141        bomp_xomp_init(&xw_arg);
142    }
143
144    if (argc < 4) {
145        debug_printf("Usage: %s <size> <numthreats>\n", argv[0]);
146        exit(1);
147    }
148
149    nthreads = strtoul(argv[1], NULL, 10);
150    if (nthreads == 0) {
151        debug_printf("num threads must be >0\n");
152        exit(1);
153    }
154
155    DEBUG("\n");
156    DEBUG("======================================================\n");
157    debug_printf("Num Threads: %u\n", nthreads);
158
159    uint8_t is_shared = 0;
160    for (int i = 2; i < argc; ++i) {
161        if (!strcmp(argv[i], "bomp")) {
162            prepare_bomp();
163            is_shared = 1;
164        } else if (!strcmp(argv[i], "xomp")) {
165            is_shared = prepare_xomp(argc, argv);
166        } else {
167            debug_printf("ignoring argument {%s}\n", argv[i]);
168        }
169    }
170
171    debug_printf("-------------------------------------\n");
172    debug_printf("init time: %lu\n", timer_xompinit);
173    debug_printf("-------------------------------------\n");
174#if XOMP_BENCH_ENABLED
175    xomp_master_bench_print_results();
176#endif
177    while (1)
178        ;
179
180}
181
182