benchmarks initial commit
authorYunsup Lee <yunsup@cs.berkeley.edu>
Tue, 30 Apr 2013 01:44:21 +0000 (18:44 -0700)
committerYunsup Lee <yunsup@cs.berkeley.edu>
Tue, 30 Apr 2013 01:44:21 +0000 (18:44 -0700)
71 files changed:
benchmarks/Makefile [new file with mode: 0644]
benchmarks/common/crt-mt.S [new file with mode: 0644]
benchmarks/common/crt.S [new file with mode: 0644]
benchmarks/common/pcr.h [new file with mode: 0644]
benchmarks/common/syscalls.S [new file with mode: 0644]
benchmarks/common/syscalls.c [new file with mode: 0644]
benchmarks/common/test-mt.ld [new file with mode: 0644]
benchmarks/common/test.ld [new file with mode: 0644]
benchmarks/common/util.h [new file with mode: 0644]
benchmarks/dgemm/bmark.mk [new file with mode: 0644]
benchmarks/dgemm/dataset1.h [new file with mode: 0644]
benchmarks/dgemm/dgemm_gendata.scala [new file with mode: 0644]
benchmarks/dgemm/dgemm_main.c [new file with mode: 0644]
benchmarks/dhrystone/bmark.mk [new file with mode: 0644]
benchmarks/dhrystone/dhrystone.c [new file with mode: 0644]
benchmarks/dhrystone/dhrystone.h [new file with mode: 0644]
benchmarks/dhrystone/dhrystone_main.c [new file with mode: 0644]
benchmarks/median/bmark.mk [new file with mode: 0644]
benchmarks/median/dataset1.h [new file with mode: 0644]
benchmarks/median/median.c [new file with mode: 0644]
benchmarks/median/median.h [new file with mode: 0644]
benchmarks/median/median_gendata.pl [new file with mode: 0755]
benchmarks/median/median_main.c [new file with mode: 0644]
benchmarks/mt-matmul/bmark.mk [new file with mode: 0644]
benchmarks/mt-matmul/dataset.h [new file with mode: 0644]
benchmarks/mt-matmul/matmul_gendata.pl [new file with mode: 0755]
benchmarks/mt-matmul/mt-matmul.c [new file with mode: 0644]
benchmarks/mt-vvadd/bmark.mk [new file with mode: 0644]
benchmarks/mt-vvadd/dataset.h [new file with mode: 0644]
benchmarks/mt-vvadd/mt-vvadd.c [new file with mode: 0644]
benchmarks/mt-vvadd/vvadd_gendata.pl [new file with mode: 0755]
benchmarks/multiply/bmark.mk [new file with mode: 0644]
benchmarks/multiply/dataset1.h [new file with mode: 0644]
benchmarks/multiply/multiply.c [new file with mode: 0644]
benchmarks/multiply/multiply.h [new file with mode: 0644]
benchmarks/multiply/multiply_gendata.pl [new file with mode: 0755]
benchmarks/multiply/multiply_main.c [new file with mode: 0644]
benchmarks/qsort/bmark.mk [new file with mode: 0644]
benchmarks/qsort/dataset1.h [new file with mode: 0644]
benchmarks/qsort/qsort_gendata.pl [new file with mode: 0755]
benchmarks/qsort/qsort_main.c [new file with mode: 0644]
benchmarks/readme.txt [new file with mode: 0644]
benchmarks/spmv/bmark.mk [new file with mode: 0644]
benchmarks/spmv/dataset1.h [new file with mode: 0644]
benchmarks/spmv/spmv_gendata.scala [new file with mode: 0644]
benchmarks/spmv/spmv_main.c [new file with mode: 0644]
benchmarks/towers/bmark.mk [new file with mode: 0644]
benchmarks/towers/towers_main.c [new file with mode: 0644]
benchmarks/vec-cmplxmult/bmark.mk [new file with mode: 0644]
benchmarks/vec-cmplxmult/cmplxmult_gendata.pl [new file with mode: 0755]
benchmarks/vec-cmplxmult/dataset.h [new file with mode: 0644]
benchmarks/vec-cmplxmult/dataset_test.h [new file with mode: 0644]
benchmarks/vec-cmplxmult/vec_cmplxmult_asm.S [new file with mode: 0644]
benchmarks/vec-cmplxmult/vec_cmplxmult_main.c [new file with mode: 0644]
benchmarks/vec-matmul/bmark.mk [new file with mode: 0644]
benchmarks/vec-matmul/dataset.h [new file with mode: 0644]
benchmarks/vec-matmul/dataset_test.h [new file with mode: 0644]
benchmarks/vec-matmul/matmul_gendata.pl [new file with mode: 0755]
benchmarks/vec-matmul/vec_matmul_asm.S [new file with mode: 0644]
benchmarks/vec-matmul/vec_matmul_main.c [new file with mode: 0644]
benchmarks/vec-vvadd/bmark.mk [new file with mode: 0644]
benchmarks/vec-vvadd/dataset.h [new file with mode: 0644]
benchmarks/vec-vvadd/dataset_test.h [new file with mode: 0644]
benchmarks/vec-vvadd/vec_vvadd_asm.S [new file with mode: 0644]
benchmarks/vec-vvadd/vec_vvadd_main.c [new file with mode: 0644]
benchmarks/vec-vvadd/vvadd_gendata.pl [new file with mode: 0755]
benchmarks/vvadd/bmark.mk [new file with mode: 0644]
benchmarks/vvadd/dataset1-large.h [new file with mode: 0644]
benchmarks/vvadd/dataset1.h [new file with mode: 0644]
benchmarks/vvadd/vvadd_gendata.pl [new file with mode: 0755]
benchmarks/vvadd/vvadd_main.c [new file with mode: 0644]

diff --git a/benchmarks/Makefile b/benchmarks/Makefile
new file mode 100644 (file)
index 0000000..a0ce377
--- /dev/null
@@ -0,0 +1,144 @@
+#=======================================================================
+# UCB VLSI FLOW: Makefile for riscv-bmarks
+#-----------------------------------------------------------------------
+# Yunsup Lee (yunsup@cs.berkeley.edu)
+#
+
+default: all
+
+bmarkdir = .
+
+instname = riscv-bmarks
+instbasedir = $(UCB_VLSI_HOME)/install
+
+#--------------------------------------------------------------------
+# Sources
+#--------------------------------------------------------------------
+
+bmarks = \
+       median \
+       qsort \
+       towers \
+       vvadd \
+       multiply \
+       dgemm \
+       dhrystone \
+       spmv \
+       vec-vvadd \
+       vec-cmplxmult \
+       vec-matmul \
+       mt-vvadd \
+       mt-matmul \
+
+bmarks_host = \
+       median \
+       qsort \
+       towers \
+       vvadd \
+       multiply \
+       dgemm \
+       spmv \
+       vec-vvadd \
+       vec-cmplxmult \
+       vec-matmul \
+
+#--------------------------------------------------------------------
+# Build rules
+#--------------------------------------------------------------------
+
+HOST_OPTS = -std=gnu99 -DPREALLOCATE=0 -DHOST_DEBUG=1
+HOST_COMP = gcc $(HOST_OPTS)
+
+RISCV_GCC = riscv-gcc
+RISCV_GCC_OPTS = -std=gnu99 -DSET_STATS -O2 -nostdlib -nostartfiles -ffast-math
+RISCV_LINK = riscv-gcc -T $(bmarkdir)/common/test.ld
+RISCV_LINK_MT = riscv-gcc -T $(bmarkdir)/common/test-mt.ld
+RISCV_LINK_OPTS = -lc
+RISCV_LINK_SYSCALL = $(bmarkdir)/common/syscalls.c -lc
+RISCV_OBJDUMP = riscv-objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.data
+RISCV_SIM = riscv-isa-run
+
+VPATH += $(addprefix $(bmarkdir)/, $(bmarks))
+VPATH += $(bmarkdir)/common
+
+incs  += -I. -I./common $(addprefix -I$(bmarkdir)/, $(bmarks))
+objs  :=
+
+include $(patsubst %, $(bmarkdir)/%/bmark.mk, $(bmarks))
+
+#------------------------------------------------------------
+# Build and run benchmarks on riscv simulator
+
+bmarks_riscv_bin  = $(addsuffix .riscv,  $(bmarks))
+bmarks_riscv_dump = $(addsuffix .riscv.dump, $(bmarks))
+bmarks_riscv_hex = $(addsuffix .riscv.hex, $(bmarks))
+bmarks_riscv_out  = $(addsuffix .riscv.out,  $(bmarks))
+
+bmarks_defs   = -DPREALLOCATE=1 -DHOST_DEBUG=0
+bmarks_cycles = 80000
+
+%.hex: %
+       elf2hex 16 32768 $< > $@
+
+$(bmarks_riscv_dump): %.riscv.dump: %.riscv
+       $(RISCV_OBJDUMP) $< > $@
+
+$(bmarks_riscv_out): %.riscv.out: %.riscv
+       $(RISCV_SIM) $< > $@
+
+%.o: %.c
+       $(RISCV_GCC) $(RISCV_GCC_OPTS) $(bmarks_defs) \
+                    -c $(incs) $< -o $@
+
+%.o: %.S
+       $(RISCV_GCC) $(RISCV_GCC_OPTS) $(bmarks_defs) \
+                    -c $(incs) $< -o $@
+
+riscv: $(bmarks_riscv_dump) $(bmarks_riscv_hex)
+run-riscv: $(bmarks_riscv_out)
+       echo; perl -ne 'print "  [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \
+              $(bmarks_riscv_out); echo;
+
+junk += $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(bmarks_riscv_hex) $(bmarks_riscv_out)
+
+#------------------------------------------------------------
+# Build and run benchmarks on host machine
+
+bmarks_host_bin = $(addsuffix .host, $(bmarks_host))
+bmarks_host_out = $(addsuffix .host.out, $(bmarks_host))
+
+$(bmarks_host_out): %.host.out: %.host
+       ./$< > $@
+
+host: $(bmarks_host_bin)
+run-host: $(bmarks_host_out)
+       echo; perl -ne 'print "  [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \
+              $(bmarks_host_out); echo;
+
+junk += $(bmarks_host_bin) $(bmarks_host_out)
+
+#------------------------------------------------------------
+# Default
+
+all: riscv
+
+#------------------------------------------------------------
+# Install
+
+date_suffix = $(shell date +%Y-%m-%d_%H-%M)
+install_dir = $(instbasedir)/$(instname)-$(date_suffix)
+latest_install = $(shell ls -1 -d $(instbasedir)/$(instname)* | tail -n 1)
+
+install:
+       mkdir $(install_dir)
+       cp -r $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(install_dir)
+
+install-link:
+       rm -rf $(instbasedir)/$(instname)
+       ln -s $(latest_install) $(instbasedir)/$(instname)
+
+#------------------------------------------------------------
+# Clean up
+
+clean:
+       rm -rf $(objs) $(junk)
diff --git a/benchmarks/common/crt-mt.S b/benchmarks/common/crt-mt.S
new file mode 100644 (file)
index 0000000..283b3bf
--- /dev/null
@@ -0,0 +1,116 @@
+  .data
+  .globl _heapend
+  .globl environ
+_heapend:
+  .word 0
+environ:
+  .word 0
+
+  .text
+  .globl _start
+
+_start:
+  li  x1, 0
+  li  x2, 0
+  li  x3, 0
+  li  x4, 0
+  li  x5, 0
+  li  x6, 0
+  li  x7, 0
+  li  x8, 0
+  li  x9, 0
+  li  x10,0
+  li  x11,0
+  li  x12,0
+  li  x13,0
+  li  x14,0
+  li  x15,0
+  li  x16,0
+  li  x17,0
+  li  x18,0
+  li  x19,0
+  li  x20,0
+  li  x21,0
+  li  x22,0
+  li  x23,0
+  li  x24,0
+  li  x25,0
+  li  x26,0
+  li  x27,0
+  li  x28,0
+  li  x29,0
+  li  x30,0
+  li  x31,0
+
+  # enable fp
+  mfpcr  x1,cr0
+  ori  x1,x1,0x2
+  mtpcr  x1,cr0
+
+  # enable vec
+  mfpcr  x1,cr0
+  ori  x1,x1,0x4
+  mtpcr  x1,cr0
+
+  ## if that didn't stick, we don't have an FPU, so don't initialize it
+  mfpcr x1,cr0
+  andi x1,x1,0x2
+  beqz x1,1f
+
+  mtfsr   x0
+  mxtf.s  f0, x0
+  mxtf.s  f1, x0
+  mxtf.s  f2, x0
+  mxtf.s  f3, x0
+  mxtf.s  f4, x0
+  mxtf.s  f5, x0
+  mxtf.s  f6, x0
+  mxtf.s  f7, x0
+  mxtf.s  f8, x0
+  mxtf.s  f9, x0
+  mxtf.s  f10,x0
+  mxtf.s  f11,x0
+  mxtf.s  f12,x0
+  mxtf.s  f13,x0
+  mxtf.s  f14,x0
+  mxtf.s  f15,x0
+  mxtf.s  f16,x0
+  mxtf.s  f17,x0
+  mxtf.s  f18,x0
+  mxtf.s  f19,x0
+  mxtf.s  f20,x0
+  mxtf.s  f21,x0
+  mxtf.s  f22,x0
+  mxtf.s  f23,x0
+  mxtf.s  f24,x0
+  mxtf.s  f25,x0
+  mxtf.s  f26,x0
+  mxtf.s  f27,x0
+  mxtf.s  f28,x0
+  mxtf.s  f29,x0
+  mxtf.s  f30,x0
+  mxtf.s  f31,x0
+1:
+
+  # get core id and number of cores
+  mfpcr a0,cr10
+  lw a1, 4(zero)
+
+  slli a2, a0, 13
+  la sp, stacktop
+  sub sp, sp, a2
+
+  la tp, tlstop
+  sub tp, tp, a2
+
+  jal thread_entry
+
+  .bss
+  .globl stacktop
+  .globl tlstop
+
+  .align 4
+  .skip 32768
+stacktop:
+  .skip 65536
+tlstop:
diff --git a/benchmarks/common/crt.S b/benchmarks/common/crt.S
new file mode 100644 (file)
index 0000000..d153210
--- /dev/null
@@ -0,0 +1,108 @@
+  .data
+  .globl _heapend
+  .globl environ
+_heapend:
+  .word 0
+environ:
+  .word 0
+
+  .text
+  .globl _start
+
+_start:
+  li  x1, 0
+  li  x2, 0
+  li  x3, 0
+  li  x4, 0
+  li  x5, 0
+  li  x6, 0
+  li  x7, 0
+  li  x8, 0
+  li  x9, 0
+  li  x10,0
+  li  x11,0
+  li  x12,0
+  li  x13,0
+  li  x14,0
+  li  x15,0
+  li  x16,0
+  li  x17,0
+  li  x18,0
+  li  x19,0
+  li  x20,0
+  li  x21,0
+  li  x22,0
+  li  x23,0
+  li  x24,0
+  li  x25,0
+  li  x26,0
+  li  x27,0
+  li  x28,0
+  li  x29,0
+  li  x30,0
+  li  x31,0
+
+  # enable fp
+  mfpcr  x1,cr0
+  ori  x1,x1,0x2
+  mtpcr  x1,cr0
+
+  # enable vec
+  mfpcr  x1,cr0
+  ori  x1,x1,0x4
+  mtpcr  x1,cr0
+
+  ## if that didn't stick, we don't have an FPU, so don't initialize it
+  mfpcr x1,cr0
+  andi x1,x1,0x2
+  beqz x1,1f
+
+  mtfsr   x0
+  mxtf.s  f0, x0
+  mxtf.s  f1, x0
+  mxtf.s  f2, x0
+  mxtf.s  f3, x0
+  mxtf.s  f4, x0
+  mxtf.s  f5, x0
+  mxtf.s  f6, x0
+  mxtf.s  f7, x0
+  mxtf.s  f8, x0
+  mxtf.s  f9, x0
+  mxtf.s  f10,x0
+  mxtf.s  f11,x0
+  mxtf.s  f12,x0
+  mxtf.s  f13,x0
+  mxtf.s  f14,x0
+  mxtf.s  f15,x0
+  mxtf.s  f16,x0
+  mxtf.s  f17,x0
+  mxtf.s  f18,x0
+  mxtf.s  f19,x0
+  mxtf.s  f20,x0
+  mxtf.s  f21,x0
+  mxtf.s  f22,x0
+  mxtf.s  f23,x0
+  mxtf.s  f24,x0
+  mxtf.s  f25,x0
+  mxtf.s  f26,x0
+  mxtf.s  f27,x0
+  mxtf.s  f28,x0
+  mxtf.s  f29,x0
+  mxtf.s  f30,x0
+  mxtf.s  f31,x0
+1:
+
+  # only allow core 0 to proceed
+1:mfpcr a0, cr10
+  bnez a0, 1b
+
+  la  sp,stacktop
+  jal main
+1:b 1b
+
+  .bss
+  .globl stacktop
+
+  .align 4
+  .skip 131072
+stacktop:
diff --git a/benchmarks/common/pcr.h b/benchmarks/common/pcr.h
new file mode 100644 (file)
index 0000000..7659a97
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef _RISCV_PCR_H
+#define _RISCV_PCR_H
+
+#define SR_ET    0x00000001
+#define SR_EF    0x00000002
+#define SR_EV    0x00000004
+#define SR_EC    0x00000008
+#define SR_PS    0x00000010
+#define SR_S     0x00000020
+#define SR_U64   0x00000040
+#define SR_S64   0x00000080
+#define SR_VM    0x00000100
+#define SR_IM    0x00FF0000
+#define SR_ZERO  ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_U64|SR_S64|SR_VM|SR_IM)
+#define SR_IM_SHIFT 16
+
+#define PCR_SR       0
+#define PCR_EPC      1
+#define PCR_BADVADDR 2
+#define PCR_EVEC     3
+#define PCR_COUNT    4
+#define PCR_COMPARE  5
+#define PCR_CAUSE    6
+#define PCR_PTBR     7
+#define PCR_SEND_IPI 8
+#define PCR_CLR_IPI  9
+#define PCR_COREID   10
+#define PCR_IMPL     11
+#define PCR_K0       12
+#define PCR_K1       13
+#define PCR_VECBANK  18
+#define PCR_VECCFG   19
+#define PCR_RESET    29
+#define PCR_TOHOST   30
+#define PCR_FROMHOST 31
+
+#define IRQ_IPI   5
+#define IRQ_TIMER 7
+
+#define CAUSE_MISALIGNED_FETCH 0
+#define CAUSE_FAULT_FETCH 1
+#define CAUSE_ILLEGAL_INSTRUCTION 2
+#define CAUSE_PRIVILEGED_INSTRUCTION 3
+#define CAUSE_FP_DISABLED 4
+#define CAUSE_SYSCALL 6
+#define CAUSE_BREAKPOINT 7
+#define CAUSE_MISALIGNED_LOAD 8
+#define CAUSE_MISALIGNED_STORE 9
+#define CAUSE_FAULT_LOAD 10
+#define CAUSE_FAULT_STORE 11
+#define CAUSE_VECTOR_DISABLED 12
+#define CAUSE_VECTOR_BANK 13
+
+#define CAUSE_VECTOR_MISALIGNED_FETCH 24
+#define CAUSE_VECTOR_FAULT_FETCH 25
+#define CAUSE_VECTOR_ILLEGAL_INSTRUCTION 26
+#define CAUSE_VECTOR_ILLEGAL_COMMAND 27
+#define CAUSE_VECTOR_MISALIGNED_LOAD 28
+#define CAUSE_VECTOR_MISALIGNED_STORE 29
+#define CAUSE_VECTOR_FAULT_LOAD 30
+#define CAUSE_VECTOR_FAULT_STORE 31
+
+#ifdef __riscv
+
+#define ASM_CR(r)   _ASM_CR(r)
+#define _ASM_CR(r)  cr##r
+
+#ifndef __ASSEMBLER__
+
+#define mtpcr(reg,val) ({ long __tmp = (long)(val), __tmp2; \
+          asm volatile ("mtpcr %0,%1,cr%2" : "=r"(__tmp2) : "r"(__tmp),"i"(reg)); \
+          __tmp2; })
+
+#define mfpcr(reg) ({ long __tmp; \
+          asm volatile ("mfpcr %0,cr%1" : "=r"(__tmp) : "i"(reg)); \
+          __tmp; })
+
+#define setpcr(reg,val) ({ long __tmp; \
+          asm volatile ("setpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+          __tmp; })
+
+#define clearpcr(reg,val) ({ long __tmp; \
+          asm volatile ("clearpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \
+          __tmp; })
+
+#endif
+
+#endif
+
+#endif
diff --git a/benchmarks/common/syscalls.S b/benchmarks/common/syscalls.S
new file mode 100644 (file)
index 0000000..a0cdf6e
--- /dev/null
@@ -0,0 +1,678 @@
+       .file   1 "syscalls.c"
+       .section .mdebug.abi64
+       .previous
+       .section        .rodata.str1.8,"aMS",@progbits,1
+       .align  3
+$LC0:
+       .ascii  "0123456789abcdef\000"
+       .text
+       .align  2
+       .ent    printnum
+       .type   printnum, @function
+printnum:
+       .frame  x30,64,x1               # vars= 0, regs= 7/0, args= 0
+       .mask   0x03f00002,-8
+       .fmask  0x00000000,0
+       add     x30,x30,-64
+       sd      x22,32(x30)
+       sll     x22,x7,32
+       srl     x22,x22,32
+       sd      x24,48(x30)
+       sd      x23,40(x30)
+       sd      x21,24(x30)
+       sd      x20,16(x30)
+       sd      x25,56(x30)
+       sd      x1,8(x30)
+       move    x23,x6
+       move    x20,x4
+       move    x21,x5
+       move    x24,x9
+       bleu    x22,x6,$L2
+       addw    x8,x8,-1
+       move    x25,x8
+       ble     x8,x0,$L4
+$L6:
+       addw    x25,x25,-1
+       move    x4,x24
+       move    x5,x21
+       jalr    x20
+       bne     x25,x0,$L6
+$L4:
+       lui     x2,%hi($LC0)
+       add     x2,x2,%lo($LC0)
+       remu    x22,x23,x22
+       add     x22,x22,x2
+       lb      x4,0(x22)
+       move    x5,x21
+       move    x19,x20
+       ld      x25,56(x30)
+       ld      x24,48(x30)
+       ld      x23,40(x30)
+       ld      x22,32(x30)
+       ld      x21,24(x30)
+       ld      x20,16(x30)
+       ld      x1,8(x30)
+       add     x30,x30,64
+       jr      x19
+$L2:
+       addw    x8,x8,-1
+       divu    x6,x6,x22
+       jal     printnum
+       j       $L4
+       .end    printnum
+       .size   printnum, .-printnum
+       .align  2
+       .ent    getuint
+       .type   getuint, @function
+getuint:
+       .frame  x30,0,x1                # vars= 0, regs= 0/0, args= 0
+       .mask   0x00000000,0
+       .fmask  0x00000000,0
+       slt     x2,x5,2
+       bne     x2,x0,$L10
+$L13:
+       ld      x2,0(x4)
+       add     x3,x2,8
+       sd      x3,0(x4)
+       ld      x2,0(x2)
+       ret
+$L10:
+       bne     x5,x0,$L13
+       ld      x3,0(x4)
+       lwu     x2,0(x3)
+       add     x3,x3,8
+       sd      x3,0(x4)
+       ret
+       .end    getuint
+       .size   getuint, .-getuint
+       .align  2
+       .globl  putchar
+       .ent    putchar
+       .type   putchar, @function
+putchar:
+       .frame  x30,64,x1               # vars= 64, regs= 0/0, args= 0
+       .mask   0x00000000,0
+       .fmask  0x00000000,0
+       li      x2,-1                   # 0xffffffffffffffff
+       add     x30,x30,-64
+       lui     x3,%hi(buflen.1596)
+       beq     x4,x2,$L21
+       lw      x5,%lo(buflen.1596)(x3)
+       lui     x2,%hi(buf.1595)
+       add     x2,x2,%lo(buf.1595)
+       add     x6,x2,x5
+       sb      x4,0(x6)
+       addw    x5,x5,1
+       li      x4,64                   # 0x40
+       sw      x5,%lo(buflen.1596)(x3)
+       beq     x5,x4,$L15
+       move    x2,x0
+       add     x30,x30,64
+       j       x1
+$L21:
+       lui     x2,%hi(buf.1595)
+       add     x2,x2,%lo(buf.1595)
+$L15:
+       lw      x4,%lo(buflen.1596)(x3)
+       li      x5,4                    # 0x4
+       sd      x0,0(x30)
+       sd      x0,8(x30)
+       sd      x0,16(x30)
+       sd      x0,24(x30)
+       sd      x0,32(x30)
+       sd      x0,40(x30)
+       sd      x0,48(x30)
+       sd      x0,56(x30)
+       sd      x5,0(x30)
+       li      x5,1                    # 0x1
+       sd      x5,8(x30)
+       sd      x2,16(x30)
+       sd      x4,24(x30)
+       fence
+ #APP
+ # 45 "syscalls.c" 1
+       mtpcr x2,x30,cr30
+ # 0 "" 2
+ #NO_APP
+$L17:
+ #APP
+ # 46 "syscalls.c" 1
+       mfpcr x2,cr31
+ # 0 "" 2
+ #NO_APP
+       beq     x2,x0,$L17
+       move    x2,x0
+       sw      x0,%lo(buflen.1596)(x3)
+       add     x30,x30,64
+       j       x1
+       .end    putchar
+       .size   putchar, .-putchar
+       .align  2
+       .globl  exit
+       .ent    exit
+       .type   exit, @function
+exit:
+       .frame  x30,64,x1               # vars= 64, regs= 0/0, args= 0
+       .mask   0x00000000,0
+       .fmask  0x00000000,0
+       add     x30,x30,-64
+       li      x2,1                    # 0x1
+       sd      x0,0(x30)
+       sd      x0,8(x30)
+       sd      x0,16(x30)
+       sd      x0,24(x30)
+       sd      x0,32(x30)
+       sd      x0,40(x30)
+       sd      x0,48(x30)
+       sd      x0,56(x30)
+       sd      x2,0(x30)
+       sd      x4,8(x30)
+       fence
+ #APP
+ # 12 "syscalls.c" 1
+       mtpcr x2,x30,cr30
+ # 0 "" 2
+ #NO_APP
+$L23:
+       j       $L23
+       .end    exit
+       .size   exit, .-exit
+       .align  2
+       .globl  printstr
+       .ent    printstr
+       .type   printstr, @function
+printstr:
+       .frame  x30,80,x1               # vars= 64, regs= 1/0, args= 0
+       .mask   0x00000002,-8
+       .fmask  0x00000000,0
+       add     x30,x30,-80
+       li      x3,4                    # 0x4
+       sd      x0,0(x30)
+       sd      x0,8(x30)
+       sd      x0,16(x30)
+       sd      x0,24(x30)
+       sd      x0,32(x30)
+       sd      x0,40(x30)
+       sd      x0,48(x30)
+       sd      x0,56(x30)
+       sd      x3,0(x30)
+       li      x3,1                    # 0x1
+       sd      x3,8(x30)
+       sd      x1,72(x30)
+       sd      x4,16(x30)
+       jal     strlen
+       sd      x2,24(x30)
+       fence
+ #APP
+ # 24 "syscalls.c" 1
+       mtpcr x2,x30,cr30
+ # 0 "" 2
+ #NO_APP
+$L25:
+ #APP
+ # 25 "syscalls.c" 1
+       mfpcr x2,cr31
+ # 0 "" 2
+ #NO_APP
+       beq     x2,x0,$L25
+       ld      x1,72(x30)
+       add     x30,x30,80
+       j       x1
+       .end    printstr
+       .size   printstr, .-printstr
+       .align  2
+       .globl  printhex
+       .ent    printhex
+       .type   printhex, @function
+printhex:
+       .frame  x30,48,x1               # vars= 32, regs= 1/0, args= 0
+       .mask   0x00000002,-8
+       .fmask  0x00000000,0
+       add     x30,x30,-48
+       sd      x1,40(x30)
+       add     x2,x30,15
+       add     x7,x30,-1
+$L29:
+       and     x3,x4,15
+       sltu    x6,x3,10
+       li      x5,87                   # 0x57
+       beq     x6,x0,$L28
+       li      x5,48                   # 0x30
+$L28:
+       add     x3,x5,x3
+       sb      x3,0(x2)
+       add     x2,x2,-1
+       srl     x4,x4,4
+       bne     x2,x7,$L29
+       move    x4,x30
+       sb      x0,16(x30)
+       jal     printstr
+       ld      x1,40(x30)
+       add     x30,x30,48
+       j       x1
+       .end    printhex
+       .size   printhex, .-printhex
+       .section        .rodata.str1.8
+       .align  3
+$LC1:
+       .ascii  "(null)\000"
+       .text
+       .align  2
+       .globl  vprintfmt
+       .ent    vprintfmt
+       .type   vprintfmt, @function
+vprintfmt:
+       .frame  x30,112,x1              # vars= 32, regs= 10/0, args= 0
+       .mask   0x2ff00002,-8
+       .fmask  0x00000000,0
+       add     x30,x30,-112
+       sd      x25,80(x30)
+       lui     x25,%hi($L53)
+       sd      x26,88(x30)
+       sd      x24,72(x30)
+       sd      x23,64(x30)
+       sd      x22,56(x30)
+       sd      x21,48(x30)
+       sd      x20,40(x30)
+       sd      x29,104(x30)
+       sd      x27,96(x30)
+       sd      x1,32(x30)
+       move    x21,x4
+       move    x20,x5
+       move    x23,x6
+       sd      x7,0(x30)
+       li      x22,37                  # 0x25
+       add     x25,x25,%lo($L53)
+       li      x24,-1                  # 0xffffffffffffffff
+       lui     x26,%hi($LC1)
+       j       $L84
+$L35:
+       beq     x2,x0,$L32
+       move    x5,x20
+       add     x23,x23,1
+       jalr    x21
+$L84:
+       lbu     x4,0(x23)
+       move    x2,x4
+       bne     x4,x22,$L35
+       ld      x2,0(x30)
+       add     x6,x23,1
+       move    x7,x6
+       li      x27,32                  # 0x20
+       sd      x0,8(x30)
+       li      x3,-1                   # 0xffffffffffffffff
+       li      x29,-1                  # 0xffffffffffffffff
+       move    x5,x0
+$L85:
+       lbu     x4,0(x7)
+       add     x23,x7,1
+       addw    x8,x4,-35
+       and     x9,x8,0xff
+       sltu    x9,x9,86
+       bne     x9,x0,$L90
+$L38:
+       li      x4,37                   # 0x25
+       move    x5,x20
+       sd      x2,0(x30)
+       move    x23,x6
+       jalr    x21
+       j       $L84
+$L32:
+       ld      x1,32(x30)
+       ld      x29,104(x30)
+       ld      x27,96(x30)
+       ld      x26,88(x30)
+       ld      x25,80(x30)
+       ld      x24,72(x30)
+       ld      x23,64(x30)
+       ld      x22,56(x30)
+       ld      x21,48(x30)
+       ld      x20,40(x30)
+       add     x30,x30,112
+       j       x1
+$L90:
+       and     x8,x8,0xff
+       sll     x8,x8,3
+       add     x8,x25,x8
+       ld      x8,0(x8)
+       j       x8
+       .section        .rodata
+       .align  3
+       .align  2
+$L53:
+       .dword  $L39
+       .dword  $L38
+       .dword  $L40
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L41
+       .dword  $L38
+       .dword  $L38
+       .dword  $L42
+       .dword  $L43
+       .dword  $L38
+       .dword  $L74
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L44
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L45
+       .dword  $L46
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L38
+       .dword  $L47
+       .dword  $L38
+       .dword  $L38
+       .dword  $L48
+       .dword  $L49
+       .dword  $L38
+       .dword  $L38
+       .dword  $L50
+       .dword  $L38
+       .dword  $L51
+       .dword  $L38
+       .dword  $L38
+       .dword  $L52
+       .text
+$L52:
+       move    x4,x30
+       sd      x2,0(x30)
+       jal     getuint
+       move    x6,x2
+       li      x7,16                   # 0x10
+$L73:
+       move    x4,x21
+       move    x5,x20
+       move    x8,x29
+       move    x9,x27
+       jal     printnum
+       j       $L84
+$L39:
+       li      x4,1                    # 0x1
+       move    x7,x23
+       sd      x4,8(x30)
+       j       $L85
+$L40:
+       move    x5,x20
+       sd      x2,0(x30)
+       jalr    x21
+       j       $L84
+$L41:
+       lw      x3,0(x2)
+       move    x7,x23
+       add     x2,x2,8
+$L54:
+       bge     x29,x0,$L85
+       move    x29,x3
+       li      x3,-1                   # 0xffffffffffffffff
+       j       $L85
+$L42:
+       move    x7,x23
+       li      x27,45                  # 0x2d
+       j       $L85
+$L43:
+       blt     x29,x0,$L91
+       move    x7,x23
+       j       $L85
+$L74:
+       move    x7,x23
+       li      x27,48                  # 0x30
+       j       $L85
+$L44:
+       lb      x8,1(x7)
+       addw    x3,x4,-48
+       move    x7,x23
+       addw    x4,x8,-48
+       sltu    x4,x4,10
+       beq     x4,x0,$L54
+$L55:
+       add     x7,x7,1
+       lb      x4,0(x7)
+       sllw    x9,x3,1
+       sllw    x3,x3,3
+       addw    x3,x9,x3
+       addw    x9,x4,-48
+       addw    x3,x3,x8
+       sltu    x9,x9,10
+       addw    x3,x3,-48
+       move    x8,x4
+       bne     x9,x0,$L55
+       j       $L54
+$L45:
+       lw      x4,0(x2)
+       add     x2,x2,8
+       move    x5,x20
+       sd      x2,0(x30)
+       jalr    x21
+       j       $L84
+$L46:
+       slt     x3,x5,2
+       bne     x3,x0,$L69
+$L88:
+       add     x3,x2,8
+       sd      x3,0(x30)
+       ld      x6,0(x2)
+       blt     x6,x0,$L72
+$L89:
+       li      x7,10                   # 0xa
+       j       $L73
+$L47:
+       addw    x5,x5,1
+       move    x7,x23
+       j       $L85
+$L48:
+       move    x4,x30
+       sd      x2,0(x30)
+       jal     getuint
+       move    x6,x2
+       li      x7,8                    # 0x8
+       j       $L73
+$L49:
+       sd      x2,0(x30)
+       li      x4,48                   # 0x30
+       move    x5,x20
+       jalr    x21
+       li      x4,120                  # 0x78
+       move    x5,x20
+       jalr    x21
+       ld      x2,0(x30)
+       li      x7,16                   # 0x10
+       add     x3,x2,8
+       sd      x3,0(x30)
+       ld      x6,0(x2)
+       j       $L73
+$L50:
+       add     x4,x2,8
+       sd      x4,0(x30)
+       ld      x2,0(x2)
+       sd      x2,16(x30)
+       beq     x2,x0,$L92
+$L58:
+       ble     x29,x0,$L59
+       li      x2,45                   # 0x2d
+       beq     x27,x2,$L59
+       ld      x4,16(x30)
+       move    x5,x3
+       sd      x3,24(x30)
+       jal     strnlen
+       sllw    x2,x2,0
+       subw    x2,x29,x2
+       move    x29,x2
+       ld      x3,24(x30)
+       ble     x2,x0,$L59
+       move    x29,x2
+$L60:
+       sd      x3,24(x30)
+       move    x4,x27
+       move    x5,x20
+       addw    x29,x29,-1
+       jalr    x21
+       ld      x3,24(x30)
+       bne     x29,x0,$L60
+$L59:
+       ld      x2,16(x30)
+       lb      x4,0(x2)
+       add     x27,x2,1
+       beq     x4,x0,$L62
+$L80:
+       blt     x3,x0,$L67
+       addw    x2,x3,-1
+       move    x3,x2
+       beq     x2,x24,$L62
+$L67:
+       ld      x2,8(x30)
+       beq     x2,x0,$L63
+       addw    x2,x4,-32
+       sltu    x2,x2,95
+       beq     x2,x0,$L93
+$L63:
+       sd      x3,24(x30)
+       move    x5,x20
+       jalr    x21
+       ld      x3,24(x30)
+$L64:
+       lb      x4,0(x27)
+       addw    x29,x29,-1
+       add     x27,x27,1
+       bne     x4,x0,$L80
+$L62:
+       ble     x29,x0,$L84
+$L79:
+       addw    x29,x29,-1
+       li      x4,32                   # 0x20
+       move    x5,x20
+       jalr    x21
+       bne     x29,x0,$L79
+       j       $L84
+$L51:
+       move    x4,x30
+       sd      x2,0(x30)
+       jal     getuint
+       move    x6,x2
+       li      x7,10                   # 0xa
+       j       $L73
+$L93:
+       sd      x3,24(x30)
+       li      x4,63                   # 0x3f
+       move    x5,x20
+       jalr    x21
+       ld      x3,24(x30)
+       j       $L64
+$L91:
+       move    x7,x23
+       move    x29,x0
+       j       $L85
+$L92:
+       add     x2,x26,%lo($LC1)
+       sd      x2,16(x30)
+       j       $L58
+$L72:
+       sd      x6,24(x30)
+       li      x4,45                   # 0x2d
+       move    x5,x20
+       jalr    x21
+       ld      x6,24(x30)
+       li      x7,10                   # 0xa
+       sub     x6,zero,x6
+       j       $L73
+$L69:
+       bne     x5,x0,$L88
+       lw      x6,0(x2)
+       add     x2,x2,8
+       sd      x2,0(x30)
+       bge     x6,x0,$L89
+       j       $L72
+       .end    vprintfmt
+       .size   vprintfmt, .-vprintfmt
+       .align  2
+       .globl  printf
+       .ent    printf
+       .type   printf, @function
+printf:
+       .frame  x30,96,x1               # vars= 16, regs= 1/0, args= 0
+       .mask   0x00000002,-72
+       .fmask  0x00000000,0
+       add     x30,x30,-96
+       add     x2,x30,40
+       move    x3,x4
+       lui     x4,%hi(putchar)
+       sd      x5,40(x30)
+       sd      x6,48(x30)
+       sd      x7,56(x30)
+       add     x4,x4,%lo(putchar)
+       move    x5,x0
+       move    x6,x3
+       move    x7,x2
+       sd      x1,24(x30)
+       sd      x8,64(x30)
+       sd      x9,72(x30)
+       sd      x10,80(x30)
+       sd      x11,88(x30)
+       sd      x2,0(x30)
+       jal     vprintfmt
+       li      x4,-1                   # 0xffffffffffffffff
+       jal     putchar
+       ld      x1,24(x30)
+       move    x2,x0
+       add     x30,x30,96
+       j       x1
+       .end    printf
+       .size   printf, .-printf
+       .local  buflen.1596
+       .comm   buflen.1596,4,4
+       .local  buf.1595
+       .comm   buf.1595,64,8
+       .ident  "GCC: (GNU) 4.6.1"
diff --git a/benchmarks/common/syscalls.c b/benchmarks/common/syscalls.c
new file mode 100644 (file)
index 0000000..f95dde4
--- /dev/null
@@ -0,0 +1,265 @@
+#include <stdint.h>
+#include <string.h>
+#include <stdarg.h>
+#include "pcr.h"
+
+void exit(int code)
+{
+  volatile uint64_t magic_mem[8] = {0};
+  magic_mem[0] = 1;
+  magic_mem[1] = code;
+  __sync_synchronize();
+  mtpcr(PCR_TOHOST, (long)magic_mem);
+  while(1);
+}
+
+void printstr(const char* s)
+{
+  volatile uint64_t magic_mem[8] = {0};
+  magic_mem[0] = 4;
+  magic_mem[1] = 1;
+  magic_mem[2] = (unsigned long)s;
+  magic_mem[3] = strlen(s);
+  __sync_synchronize();
+  mtpcr(PCR_TOHOST, (long)magic_mem);
+  while(mtpcr(PCR_FROMHOST, 0) == 0);
+}
+
+int putchar(int ch)
+{
+  #define buffered_putch_bufsize 64
+  static char buf[buffered_putch_bufsize];
+  static int buflen = 0;
+
+  if(ch != -1)
+    buf[buflen++] = ch;
+
+  if(ch == -1 || buflen == buffered_putch_bufsize)
+  {
+    volatile uint64_t magic_mem[8] = {0};
+    magic_mem[0] = 4;
+    magic_mem[1] = 1;
+    magic_mem[2] = (long)buf;
+    magic_mem[3] = buflen;
+    __sync_synchronize();
+    mtpcr(PCR_TOHOST, (long)magic_mem);
+    while(mtpcr(PCR_FROMHOST, 0) == 0);
+
+    buflen = 0;
+  }
+
+  return 0;
+}
+
+void printhex(uint64_t x)
+{
+  char str[17];
+  int i;
+  for (i = 0; i < 16; i++)
+  {
+    str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
+    x >>= 4;
+  }
+  str[16] = 0;
+
+  printstr(str);
+}
+
+static void printnum(void (*putch)(int, void**), void **putdat,
+                   unsigned long long num, unsigned base, int width, int padc)
+{
+  if (num >= base)
+    printnum(putch, putdat, num / base, base, width - 1, padc);
+  else while (--width > 0)
+    putch(padc, putdat);
+
+  putch("0123456789abcdef"[num % base], putdat);
+}
+
+static unsigned long long getuint(va_list *ap, int lflag)
+{
+  if (lflag >= 2)
+    return va_arg(*ap, unsigned long long);
+  else if (lflag)
+    return va_arg(*ap, unsigned long);
+  else
+    return va_arg(*ap, unsigned int);
+}
+
+static long long getint(va_list *ap, int lflag)
+{
+  if (lflag >= 2)
+    return va_arg(*ap, long long);
+  else if (lflag)
+    return va_arg(*ap, long);
+  else
+    return va_arg(*ap, int);
+}
+
+void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
+{
+  register const char* p;
+  const char* last_fmt;
+  register int ch, err;
+  unsigned long long num;
+  int base, lflag, width, precision, altflag;
+  char padc;
+
+  while (1) {
+    while ((ch = *(unsigned char *) fmt) != '%') {
+      if (ch == '\0')
+        return;
+      fmt++;
+      putch(ch, putdat);
+    }
+    fmt++;
+
+    // Process a %-escape sequence
+    last_fmt = fmt;
+    padc = ' ';
+    width = -1;
+    precision = -1;
+    lflag = 0;
+    altflag = 0;
+  reswitch:
+    switch (ch = *(unsigned char *) fmt++) {
+
+    // flag to pad on the right
+    case '-':
+      padc = '-';
+      goto reswitch;
+      
+    // flag to pad with 0's instead of spaces
+    case '0':
+      padc = '0';
+      goto reswitch;
+
+    // width field
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      for (precision = 0; ; ++fmt) {
+        precision = precision * 10 + ch - '0';
+        ch = *fmt;
+        if (ch < '0' || ch > '9')
+          break;
+      }
+      goto process_precision;
+
+    case '*':
+      precision = va_arg(ap, int);
+      goto process_precision;
+
+    case '.':
+      if (width < 0)
+        width = 0;
+      goto reswitch;
+
+    case '#':
+      altflag = 1;
+      goto reswitch;
+
+    process_precision:
+      if (width < 0)
+        width = precision, precision = -1;
+      goto reswitch;
+
+    // long flag (doubled for long long)
+    case 'l':
+      lflag++;
+      goto reswitch;
+
+    // character
+    case 'c':
+      putch(va_arg(ap, int), putdat);
+      break;
+
+    // string
+    case 's':
+      if ((p = va_arg(ap, char *)) == NULL)
+        p = "(null)";
+      if (width > 0 && padc != '-')
+        for (width -= strnlen(p, precision); width > 0; width--)
+          putch(padc, putdat);
+      for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
+        if (altflag && (ch < ' ' || ch > '~'))
+          putch('?', putdat);
+        else
+          putch(ch, putdat);
+        p++;
+      }
+      for (; width > 0; width--)
+        putch(' ', putdat);
+      break;
+
+    // (signed) decimal
+    case 'd':
+      num = getint(&ap, lflag);
+      if ((long long) num < 0) {
+        putch('-', putdat);
+        num = -(long long) num;
+      }
+      base = 10;
+      goto number;
+
+    // unsigned decimal
+    case 'u':
+      num = getuint(&ap, lflag);
+      base = 10;
+      goto number;
+
+    // (unsigned) octal
+    case 'o':
+      // should do something with padding so it's always 3 octits
+      num = getuint(&ap, lflag);
+      base = 8;
+      goto number;
+
+    // pointer
+    case 'p':
+      putch('0', putdat);
+      putch('x', putdat);
+      num = (unsigned long long)
+        (uintptr_t) va_arg(ap, void *);
+      base = 16;
+      goto number;
+
+    // (unsigned) hexadecimal
+    case 'x':
+      num = getuint(&ap, lflag);
+      base = 16;
+    number:
+      printnum(putch, putdat, num, base, width, padc);
+      break;
+
+    // escaped '%' character
+    case '%':
+      putch(ch, putdat);
+      break;
+      
+    // unrecognized escape sequence - just print it literally
+    default:
+      putch('%', putdat);
+      fmt = last_fmt;
+      break;
+    }
+  }
+}
+
+int printf(const char* fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+
+  vprintfmt((void*)putchar, 0, fmt, ap);
+  putchar(-1);
+
+  va_end(ap);
+  return 0; // incorrect return value, but who cares, anyway?
+}
diff --git a/benchmarks/common/test-mt.ld b/benchmarks/common/test-mt.ld
new file mode 100644 (file)
index 0000000..5523032
--- /dev/null
@@ -0,0 +1,45 @@
+/*======================================================================*/
+/* Proxy kernel linker script                                           */
+/*======================================================================*/
+/* This is the linker script used when building the proxy kernel. */
+
+/*----------------------------------------------------------------------*/
+/* Setup                                                                */
+/*----------------------------------------------------------------------*/
+
+/* The OUTPUT_ARCH command specifies the machine architecture where the
+   argument is one of the names used in the BFD library. More
+   specifically one of the entires in bfd/cpu-mips.c */
+
+OUTPUT_ARCH( "riscv" )
+
+/* The ENTRY command specifies the entry point (ie. first instruction
+   to execute). The symbol _start should be defined in each test. */
+
+ENTRY( _start )
+
+/*----------------------------------------------------------------------*/
+/* Sections                                                             */
+/*----------------------------------------------------------------------*/
+
+SECTIONS
+{
+
+  /* text: test code section */
+  . = 0x00002000;
+  .text : 
+  {
+    crt-mt.o(.text)
+    *(.text)
+  }
+
+  /* data: Initialized data segment */
+  .data : 
+  {
+    *(.data)
+  }
+
+  /* End of uninitalized data segement */
+  _end = .;
+}
+
diff --git a/benchmarks/common/test.ld b/benchmarks/common/test.ld
new file mode 100644 (file)
index 0000000..952bf53
--- /dev/null
@@ -0,0 +1,45 @@
+/*======================================================================*/
+/* Proxy kernel linker script                                           */
+/*======================================================================*/
+/* This is the linker script used when building the proxy kernel. */
+
+/*----------------------------------------------------------------------*/
+/* Setup                                                                */
+/*----------------------------------------------------------------------*/
+
+/* The OUTPUT_ARCH command specifies the machine architecture where the
+   argument is one of the names used in the BFD library. More
+   specifically one of the entires in bfd/cpu-mips.c */
+
+OUTPUT_ARCH( "riscv" )
+
+/* The ENTRY command specifies the entry point (ie. first instruction
+   to execute). The symbol _start should be defined in each test. */
+
+ENTRY( _start )
+
+/*----------------------------------------------------------------------*/
+/* Sections                                                             */
+/*----------------------------------------------------------------------*/
+
+SECTIONS
+{
+
+  /* text: test code section */
+  . = 0x00002000;
+  .text : 
+  {
+    crt.o(.text)
+    *(.text)
+  }
+
+  /* data: Initialized data segment */
+  .data : 
+  {
+    *(.data)
+  }
+
+  /* End of uninitalized data segement */
+  _end = .;
+}
+
diff --git a/benchmarks/common/util.h b/benchmarks/common/util.h
new file mode 100644 (file)
index 0000000..83b2b6c
--- /dev/null
@@ -0,0 +1,32 @@
+// helpful utility and synch functions 
+
+// relies on defining "ncores" before including this file...
+
+#ifndef __UTIL_H
+#define __UTIL_H
+
+#define rdcycle() ({ unsigned long _c; asm volatile ("rdcycle %0" : "=r"(_c) :: "memory"); _c; })
+#define rdinstret() ({ unsigned long _c; asm volatile ("rdinstret %0" : "=r"(_c) :: "memory"); _c; })
+                            
+void __attribute__((noinline)) barrier()
+{
+  static volatile int sense;
+  static volatile int count;
+  static __thread int threadsense;
+
+  __sync_synchronize();
+
+  threadsense = !threadsense;
+  if (__sync_fetch_and_add(&count, 1) == ncores-1)
+  {
+    count = 0;
+    sense = threadsense;
+  }
+  else while(sense != threadsense)
+    ;
+
+  __sync_synchronize();
+}
+   
+#endif //__UTIL_H
+
diff --git a/benchmarks/dgemm/bmark.mk b/benchmarks/dgemm/bmark.mk
new file mode 100644 (file)
index 0000000..5a26242
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+dgemm_c_src = \
+       dgemm_main.c \
+
+dgemm_riscv_src = \
+       crt.S \
+
+dgemm_c_objs     = $(patsubst %.c, %.o, $(dgemm_c_src))
+dgemm_riscv_objs = $(patsubst %.S, %.o, $(dgemm_riscv_src))
+
+dgemm_host_bin = dgemm.host
+$(dgemm_host_bin) : $(dgemm_c_src)
+       $(HOST_COMP) $^ -o $(dgemm_host_bin)
+
+dgemm_riscv_bin = dgemm.riscv
+$(dgemm_riscv_bin) : $(dgemm_c_objs) $(dgemm_riscv_objs)
+       $(RISCV_LINK) $(dgemm_c_objs) $(dgemm_riscv_objs) -o $(dgemm_riscv_bin)
+
+junk += $(dgemm_c_objs) $(dgemm_riscv_objs) \
+        $(dgemm_host_bin) $(dgemm_riscv_bin)
diff --git a/benchmarks/dgemm/dataset1.h b/benchmarks/dgemm/dataset1.h
new file mode 100644 (file)
index 0000000..9db066e
--- /dev/null
@@ -0,0 +1,97 @@
+#define DATA_SIZE 30
+const double input1_data[DATA_SIZE*DATA_SIZE] = {
+745.0, 504.0, 772.0, 818.0, 443.0, 308.0, 823.0, 523.0, 93.0, 379.0, 728.0, 543.0, 40.0, 482.0, 728.0, 487.0, 144.0, 486.0, 109.0, 994.0, 373.0, 257.0, 196.0, 145.0, 234.0, 301.0, 639.0, 379.0, 913.0, 420.0, 
+264.0, 636.0, 873.0, 677.0, 330.0, 928.0, 30.0, 603.0, 96.0, 510.0, 196.0, 55.0, 702.0, 663.0, 151.0, 526.0, 624.0, 598.0, 529.0, 926.0, 914.0, 641.0, 401.0, 146.0, 756.0, 550.0, 92.0, 452.0, 786.0, 417.0, 
+115.0, 202.0, 806.0, 841.0, 657.0, 33.0, 66.0, 595.0, 751.0, 302.0, 70.0, 453.0, 318.0, 580.0, 114.0, 85.0, 585.0, 959.0, 393.0, 810.0, 276.0, 839.0, 58.0, 632.0, 940.0, 568.0, 676.0, 625.0, 861.0, 702.0, 
+413.0, 79.0, 762.0, 494.0, 695.0, 774.0, 877.0, 968.0, 327.0, 742.0, 163.0, 353.0, 692.0, 870.0, 634.0, 60.0, 545.0, 300.0, 625.0, 48.0, 390.0, 713.0, 661.0, 613.0, 673.0, 89.0, 116.0, 472.0, 837.0, 864.0, 
+256.0, 542.0, 660.0, 768.0, 474.0, 229.0, 783.0, 583.0, 975.0, 278.0, 838.0, 557.0, 372.0, 815.0, 94.0, 820.0, 713.0, 685.0, 606.0, 304.0, 549.0, 150.0, 237.0, 981.0, 111.0, 85.0, 741.0, 960.0, 499.0, 110.0, 
+540.0, 414.0, 153.0, 809.0, 477.0, 176.0, 46.0, 27.0, 106.0, 704.0, 709.0, 728.0, 355.0, 934.0, 38.0, 974.0, 744.0, 651.0, 169.0, 514.0, 550.0, 742.0, 456.0, 453.0, 106.0, 956.0, 374.0, 945.0, 688.0, 594.0, 
+983.0, 686.0, 86.0, 247.0, 389.0, 914.0, 378.0, 837.0, 556.0, 332.0, 884.0, 102.0, 651.0, 329.0, 305.0, 874.0, 863.0, 752.0, 94.0, 102.0, 878.0, 200.0, 645.0, 601.0, 573.0, 369.0, 247.0, 241.0, 158.0, 647.0, 
+166.0, 139.0, 810.0, 531.0, 118.0, 750.0, 759.0, 621.0, 87.0, 472.0, 846.0, 644.0, 209.0, 515.0, 172.0, 565.0, 685.0, 344.0, 850.0, 218.0, 788.0, 323.0, 867.0, 809.0, 991.0, 806.0, 617.0, 878.0, 937.0, 816.0, 
+517.0, 811.0, 181.0, 590.0, 705.0, 691.0, 847.0, 233.0, 652.0, 374.0, 570.0, 160.0, 873.0, 78.0, 246.0, 652.0, 876.0, 145.0, 587.0, 729.0, 467.0, 111.0, 590.0, 653.0, 972.0, 987.0, 231.0, 809.0, 456.0, 887.0, 
+861.0, 60.0, 588.0, 71.0, 519.0, 479.0, 640.0, 608.0, 336.0, 259.0, 7.0, 578.0, 53.0, 823.0, 305.0, 911.0, 230.0, 445.0, 216.0, 696.0, 278.0, 804.0, 413.0, 333.0, 409.0, 632.0, 86.0, 401.0, 226.0, 93.0, 
+815.0, 177.0, 894.0, 51.0, 441.0, 785.0, 888.0, 915.0, 347.0, 55.0, 762.0, 896.0, 964.0, 539.0, 572.0, 889.0, 275.0, 43.0, 220.0, 195.0, 963.0, 342.0, 915.0, 651.0, 750.0, 286.0, 632.0, 168.0, 652.0, 880.0, 
+803.0, 439.0, 112.0, 544.0, 624.0, 656.0, 679.0, 117.0, 413.0, 798.0, 230.0, 571.0, 106.0, 36.0, 656.0, 848.0, 733.0, 931.0, 513.0, 614.0, 302.0, 776.0, 401.0, 703.0, 510.0, 682.0, 280.0, 351.0, 79.0, 353.0, 
+106.0, 355.0, 343.0, 802.0, 232.0, 583.0, 103.0, 663.0, 683.0, 37.0, 130.0, 795.0, 261.0, 202.0, 949.0, 739.0, 926.0, 930.0, 522.0, 872.0, 567.0, 724.0, 0.0, 385.0, 191.0, 704.0, 586.0, 974.0, 944.0, 100.0, 
+506.0, 903.0, 325.0, 622.0, 218.0, 842.0, 298.0, 676.0, 503.0, 4.0, 784.0, 63.0, 195.0, 495.0, 740.0, 518.0, 845.0, 649.0, 730.0, 287.0, 231.0, 477.0, 939.0, 472.0, 324.0, 459.0, 784.0, 988.0, 572.0, 338.0, 
+114.0, 993.0, 965.0, 134.0, 608.0, 613.0, 527.0, 645.0, 324.0, 497.0, 949.0, 659.0, 555.0, 494.0, 91.0, 317.0, 222.0, 276.0, 232.0, 266.0, 985.0, 146.0, 713.0, 54.0, 592.0, 879.0, 799.0, 16.0, 273.0, 791.0, 
+47.0, 235.0, 306.0, 873.0, 829.0, 266.0, 672.0, 893.0, 396.0, 396.0, 809.0, 603.0, 307.0, 712.0, 551.0, 390.0, 551.0, 898.0, 777.0, 672.0, 385.0, 810.0, 39.0, 311.0, 868.0, 734.0, 554.0, 941.0, 414.0, 182.0, 
+549.0, 589.0, 24.0, 141.0, 332.0, 833.0, 76.0, 431.0, 528.0, 313.0, 690.0, 190.0, 860.0, 670.0, 991.0, 679.0, 0.0, 460.0, 122.0, 585.0, 647.0, 157.0, 260.0, 941.0, 943.0, 27.0, 820.0, 81.0, 612.0, 622.0, 
+252.0, 183.0, 673.0, 275.0, 27.0, 867.0, 36.0, 45.0, 80.0, 321.0, 373.0, 485.0, 232.0, 428.0, 379.0, 973.0, 532.0, 804.0, 763.0, 91.0, 802.0, 463.0, 190.0, 153.0, 910.0, 552.0, 885.0, 976.0, 84.0, 572.0, 
+83.0, 109.0, 349.0, 881.0, 368.0, 980.0, 316.0, 97.0, 654.0, 737.0, 652.0, 525.0, 714.0, 526.0, 608.0, 245.0, 296.0, 765.0, 222.0, 403.0, 419.0, 663.0, 256.0, 23.0, 144.0, 446.0, 905.0, 933.0, 238.0, 709.0, 
+17.0, 587.0, 508.0, 879.0, 525.0, 310.0, 486.0, 372.0, 742.0, 764.0, 462.0, 8.0, 108.0, 741.0, 803.0, 502.0, 422.0, 579.0, 993.0, 835.0, 953.0, 584.0, 92.0, 932.0, 579.0, 534.0, 602.0, 473.0, 99.0, 961.0, 
+413.0, 83.0, 255.0, 849.0, 953.0, 912.0, 552.0, 220.0, 968.0, 600.0, 918.0, 48.0, 863.0, 88.0, 132.0, 278.0, 957.0, 507.0, 320.0, 618.0, 768.0, 776.0, 401.0, 943.0, 995.0, 695.0, 869.0, 295.0, 960.0, 357.0, 
+446.0, 304.0, 926.0, 664.0, 785.0, 211.0, 287.0, 420.0, 187.0, 325.0, 49.0, 355.0, 607.0, 752.0, 783.0, 963.0, 952.0, 188.0, 939.0, 953.0, 384.0, 255.0, 674.0, 747.0, 243.0, 892.0, 60.0, 3.0, 643.0, 831.0, 
+734.0, 240.0, 944.0, 943.0, 382.0, 671.0, 12.0, 292.0, 18.0, 966.0, 296.0, 335.0, 206.0, 881.0, 22.0, 473.0, 888.0, 510.0, 725.0, 276.0, 769.0, 506.0, 202.0, 789.0, 515.0, 110.0, 658.0, 835.0, 345.0, 885.0, 
+776.0, 194.0, 8.0, 124.0, 908.0, 176.0, 144.0, 820.0, 803.0, 56.0, 270.0, 676.0, 741.0, 621.0, 290.0, 214.0, 511.0, 382.0, 431.0, 164.0, 173.0, 504.0, 116.0, 828.0, 68.0, 465.0, 263.0, 383.0, 793.0, 32.0, 
+313.0, 39.0, 34.0, 331.0, 874.0, 310.0, 607.0, 128.0, 505.0, 948.0, 827.0, 357.0, 31.0, 904.0, 165.0, 491.0, 809.0, 607.0, 390.0, 156.0, 441.0, 219.0, 198.0, 165.0, 592.0, 890.0, 192.0, 791.0, 234.0, 424.0, 
+886.0, 552.0, 965.0, 615.0, 370.0, 30.0, 79.0, 178.0, 67.0, 148.0, 20.0, 241.0, 928.0, 301.0, 73.0, 55.0, 428.0, 812.0, 752.0, 535.0, 110.0, 518.0, 584.0, 661.0, 35.0, 856.0, 279.0, 633.0, 354.0, 450.0, 
+327.0, 165.0, 508.0, 261.0, 763.0, 496.0, 415.0, 872.0, 557.0, 428.0, 110.0, 406.0, 341.0, 425.0, 326.0, 644.0, 904.0, 676.0, 542.0, 590.0, 738.0, 651.0, 980.0, 521.0, 865.0, 511.0, 920.0, 563.0, 448.0, 780.0, 
+920.0, 999.0, 28.0, 940.0, 120.0, 908.0, 167.0, 319.0, 891.0, 53.0, 158.0, 319.0, 202.0, 283.0, 793.0, 608.0, 320.0, 711.0, 447.0, 533.0, 528.0, 300.0, 532.0, 797.0, 571.0, 960.0, 104.0, 773.0, 122.0, 99.0, 
+156.0, 119.0, 932.0, 689.0, 227.0, 991.0, 396.0, 890.0, 579.0, 54.0, 459.0, 624.0, 976.0, 904.0, 781.0, 712.0, 403.0, 560.0, 226.0, 225.0, 940.0, 68.0, 140.0, 714.0, 937.0, 731.0, 624.0, 416.0, 601.0, 50.0, 
+883.0, 869.0, 921.0, 350.0, 226.0, 596.0, 698.0, 51.0, 510.0, 865.0, 942.0, 971.0, 794.0, 254.0, 757.0, 19.0, 690.0, 303.0, 664.0, 127.0, 538.0, 487.0, 609.0, 86.0, 688.0, 76.0, 477.0, 664.0, 343.0, 613.0
+};
+const double input2_data[DATA_SIZE*DATA_SIZE] = {
+494.0, 929.0, 783.0, 86.0, 317.0, 957.0, 289.0, 481.0, 222.0, 945.0, 97.0, 952.0, 1.0, 834.0, 795.0, 59.0, 127.0, 10.0, 399.0, 904.0, 907.0, 665.0, 623.0, 841.0, 190.0, 903.0, 698.0, 132.0, 775.0, 911.0, 
+346.0, 417.0, 995.0, 439.0, 159.0, 390.0, 902.0, 917.0, 174.0, 462.0, 638.0, 484.0, 505.0, 353.0, 943.0, 724.0, 684.0, 845.0, 753.0, 983.0, 353.0, 730.0, 883.0, 679.0, 449.0, 442.0, 242.0, 117.0, 64.0, 143.0, 
+42.0, 476.0, 395.0, 343.0, 983.0, 724.0, 153.0, 3.0, 88.0, 131.0, 475.0, 517.0, 297.0, 917.0, 522.0, 776.0, 796.0, 468.0, 11.0, 9.0, 788.0, 908.0, 161.0, 554.0, 429.0, 381.0, 495.0, 720.0, 795.0, 563.0, 
+976.0, 786.0, 349.0, 930.0, 421.0, 218.0, 589.0, 210.0, 18.0, 536.0, 888.0, 18.0, 142.0, 674.0, 684.0, 297.0, 190.0, 160.0, 195.0, 232.0, 917.0, 451.0, 955.0, 340.0, 553.0, 470.0, 287.0, 263.0, 164.0, 28.0, 
+133.0, 206.0, 141.0, 697.0, 860.0, 45.0, 508.0, 61.0, 442.0, 142.0, 991.0, 523.0, 720.0, 544.0, 787.0, 231.0, 635.0, 828.0, 162.0, 150.0, 656.0, 915.0, 557.0, 56.0, 539.0, 108.0, 862.0, 160.0, 739.0, 561.0, 
+525.0, 564.0, 334.0, 977.0, 789.0, 287.0, 316.0, 169.0, 18.0, 140.0, 322.0, 707.0, 458.0, 646.0, 902.0, 728.0, 877.0, 386.0, 922.0, 657.0, 490.0, 942.0, 127.0, 617.0, 143.0, 979.0, 911.0, 71.0, 348.0, 989.0, 
+55.0, 968.0, 173.0, 987.0, 959.0, 865.0, 850.0, 194.0, 776.0, 681.0, 893.0, 564.0, 305.0, 645.0, 600.0, 214.0, 613.0, 790.0, 496.0, 127.0, 564.0, 197.0, 818.0, 419.0, 597.0, 414.0, 552.0, 240.0, 517.0, 34.0, 
+487.0, 497.0, 614.0, 182.0, 761.0, 45.0, 959.0, 441.0, 90.0, 500.0, 76.0, 435.0, 905.0, 920.0, 402.0, 641.0, 621.0, 526.0, 521.0, 438.0, 457.0, 224.0, 718.0, 611.0, 909.0, 347.0, 524.0, 158.0, 491.0, 331.0, 
+727.0, 536.0, 243.0, 503.0, 252.0, 633.0, 675.0, 671.0, 600.0, 598.0, 479.0, 522.0, 92.0, 778.0, 793.0, 956.0, 562.0, 659.0, 29.0, 132.0, 182.0, 491.0, 107.0, 891.0, 108.0, 664.0, 985.0, 608.0, 610.0, 589.0, 
+364.0, 665.0, 689.0, 262.0, 356.0, 324.0, 646.0, 275.0, 906.0, 316.0, 551.0, 836.0, 14.0, 495.0, 900.0, 859.0, 529.0, 900.0, 516.0, 654.0, 635.0, 90.0, 337.0, 59.0, 954.0, 419.0, 921.0, 903.0, 393.0, 503.0, 
+458.0, 879.0, 568.0, 925.0, 809.0, 496.0, 22.0, 780.0, 966.0, 265.0, 759.0, 872.0, 352.0, 110.0, 467.0, 641.0, 321.0, 272.0, 646.0, 765.0, 413.0, 935.0, 309.0, 661.0, 796.0, 881.0, 283.0, 612.0, 602.0, 684.0, 
+680.0, 332.0, 688.0, 896.0, 483.0, 131.0, 680.0, 265.0, 828.0, 779.0, 410.0, 176.0, 657.0, 776.0, 678.0, 232.0, 522.0, 722.0, 485.0, 878.0, 987.0, 754.0, 225.0, 897.0, 374.0, 704.0, 117.0, 929.0, 586.0, 891.0, 
+162.0, 237.0, 300.0, 147.0, 648.0, 324.0, 376.0, 552.0, 381.0, 589.0, 788.0, 637.0, 461.0, 802.0, 481.0, 694.0, 406.0, 127.0, 623.0, 743.0, 662.0, 257.0, 636.0, 655.0, 827.0, 649.0, 961.0, 561.0, 511.0, 991.0, 
+633.0, 907.0, 279.0, 732.0, 527.0, 31.0, 54.0, 320.0, 875.0, 863.0, 82.0, 881.0, 272.0, 677.0, 787.0, 149.0, 709.0, 457.0, 411.0, 287.0, 598.0, 27.0, 231.0, 853.0, 270.0, 520.0, 96.0, 178.0, 51.0, 938.0, 
+414.0, 639.0, 127.0, 888.0, 18.0, 821.0, 606.0, 253.0, 566.0, 134.0, 833.0, 324.0, 316.0, 393.0, 157.0, 753.0, 888.0, 131.0, 40.0, 450.0, 762.0, 139.0, 603.0, 196.0, 324.0, 590.0, 573.0, 738.0, 252.0, 297.0, 
+353.0, 280.0, 718.0, 350.0, 813.0, 663.0, 2.0, 405.0, 405.0, 353.0, 957.0, 699.0, 981.0, 499.0, 807.0, 648.0, 0.0, 675.0, 8.0, 514.0, 215.0, 22.0, 463.0, 671.0, 65.0, 764.0, 25.0, 232.0, 891.0, 152.0, 
+698.0, 426.0, 813.0, 87.0, 12.0, 246.0, 1.0, 834.0, 81.0, 695.0, 296.0, 935.0, 30.0, 699.0, 811.0, 881.0, 822.0, 259.0, 883.0, 935.0, 447.0, 973.0, 629.0, 58.0, 534.0, 745.0, 654.0, 344.0, 826.0, 568.0, 
+198.0, 814.0, 111.0, 912.0, 84.0, 179.0, 706.0, 700.0, 838.0, 455.0, 972.0, 216.0, 659.0, 210.0, 781.0, 842.0, 248.0, 465.0, 518.0, 37.0, 3.0, 803.0, 562.0, 983.0, 375.0, 34.0, 882.0, 586.0, 668.0, 228.0, 
+644.0, 632.0, 530.0, 729.0, 783.0, 543.0, 450.0, 151.0, 302.0, 148.0, 225.0, 794.0, 590.0, 212.0, 146.0, 191.0, 718.0, 621.0, 303.0, 343.0, 562.0, 715.0, 516.0, 409.0, 36.0, 486.0, 248.0, 416.0, 624.0, 865.0, 
+680.0, 460.0, 737.0, 813.0, 658.0, 396.0, 749.0, 132.0, 875.0, 73.0, 243.0, 874.0, 309.0, 5.0, 748.0, 526.0, 273.0, 634.0, 661.0, 382.0, 61.0, 728.0, 511.0, 960.0, 418.0, 454.0, 249.0, 725.0, 68.0, 306.0, 
+899.0, 127.0, 599.0, 587.0, 7.0, 236.0, 722.0, 531.0, 694.0, 403.0, 163.0, 483.0, 557.0, 10.0, 855.0, 494.0, 90.0, 186.0, 180.0, 335.0, 646.0, 74.0, 869.0, 751.0, 409.0, 777.0, 449.0, 310.0, 989.0, 624.0, 
+672.0, 27.0, 968.0, 211.0, 459.0, 70.0, 617.0, 431.0, 983.0, 291.0, 878.0, 599.0, 69.0, 873.0, 904.0, 337.0, 250.0, 120.0, 20.0, 389.0, 254.0, 714.0, 478.0, 62.0, 931.0, 992.0, 324.0, 537.0, 84.0, 333.0, 
+724.0, 874.0, 511.0, 407.0, 915.0, 566.0, 809.0, 905.0, 811.0, 291.0, 572.0, 374.0, 376.0, 988.0, 751.0, 881.0, 888.0, 169.0, 922.0, 616.0, 181.0, 203.0, 389.0, 622.0, 568.0, 204.0, 924.0, 543.0, 331.0, 765.0, 
+273.0, 742.0, 682.0, 913.0, 38.0, 787.0, 983.0, 783.0, 821.0, 848.0, 114.0, 661.0, 678.0, 634.0, 865.0, 551.0, 700.0, 253.0, 481.0, 231.0, 860.0, 680.0, 801.0, 783.0, 987.0, 624.0, 888.0, 770.0, 11.0, 689.0, 
+731.0, 72.0, 538.0, 78.0, 324.0, 368.0, 176.0, 305.0, 817.0, 136.0, 122.0, 783.0, 608.0, 391.0, 136.0, 859.0, 13.0, 452.0, 663.0, 826.0, 880.0, 728.0, 947.0, 342.0, 646.0, 182.0, 13.0, 148.0, 450.0, 610.0, 
+477.0, 121.0, 487.0, 143.0, 125.0, 153.0, 268.0, 635.0, 745.0, 792.0, 981.0, 109.0, 694.0, 353.0, 547.0, 559.0, 974.0, 59.0, 655.0, 694.0, 165.0, 628.0, 544.0, 694.0, 476.0, 702.0, 494.0, 627.0, 88.0, 630.0, 
+194.0, 650.0, 165.0, 587.0, 884.0, 53.0, 44.0, 931.0, 432.0, 630.0, 214.0, 817.0, 383.0, 3.0, 908.0, 667.0, 205.0, 791.0, 845.0, 584.0, 396.0, 26.0, 547.0, 399.0, 189.0, 438.0, 698.0, 826.0, 734.0, 322.0, 
+678.0, 305.0, 868.0, 564.0, 480.0, 499.0, 182.0, 215.0, 276.0, 272.0, 803.0, 21.0, 458.0, 2.0, 90.0, 213.0, 223.0, 97.0, 68.0, 589.0, 408.0, 197.0, 472.0, 915.0, 771.0, 830.0, 907.0, 133.0, 146.0, 848.0, 
+89.0, 17.0, 580.0, 755.0, 909.0, 310.0, 249.0, 606.0, 544.0, 193.0, 409.0, 235.0, 537.0, 580.0, 850.0, 838.0, 882.0, 416.0, 365.0, 263.0, 331.0, 868.0, 68.0, 519.0, 206.0, 70.0, 530.0, 927.0, 590.0, 29.0, 
+990.0, 507.0, 164.0, 89.0, 550.0, 150.0, 959.0, 787.0, 444.0, 695.0, 79.0, 86.0, 359.0, 841.0, 991.0, 71.0, 537.0, 521.0, 253.0, 88.0, 872.0, 760.0, 71.0, 959.0, 844.0, 24.0, 323.0, 86.0, 284.0, 324.0
+};
+const double verify_data[DATA_SIZE*DATA_SIZE] = {
+6411903.0, 7533490.0, 6901412.0, 8515176.0, 7937886.0, 5660376.0, 6684238.0, 5930516.0, 7411434.0, 5963715.0, 7339541.0, 7325224.0, 5773363.0, 6987016.0, 9472107.0, 7333522.0, 6868741.0, 6373927.0, 5818371.0, 6232365.0, 7410967.0, 7456844.0, 7008217.0, 8317827.0, 6560681.0, 6993670.0, 6792972.0, 6664526.0, 6449148.0, 6153016.0, 
+7767492.0, 6619373.0, 8084203.0, 7609675.0, 7767288.0, 5081659.0, 6915392.0, 6473820.0, 7434817.0, 5832034.0, 7317348.0, 8206514.0, 6552649.0, 7813213.0, 1.0197744E7, 8753506.0, 7589899.0, 6153453.0, 6716065.0, 7097060.0, 7488858.0, 8435675.0, 7671781.0, 8759777.0, 7413370.0, 7802106.0, 7613653.0, 6343832.0, 6741596.0, 7885307.0, 
+7584476.0, 6627809.0, 7334380.0, 7777143.0, 7311439.0, 4673418.0, 7231791.0, 6792764.0, 8133419.0, 6543855.0, 7278453.0, 7372708.0, 6345899.0, 7821711.0, 1.0014052E7, 8297702.0, 7222827.0, 6550430.0, 5927298.0, 5988751.0, 7626028.0, 8765186.0, 7449916.0, 8719206.0, 7751464.0, 6820384.0, 7786274.0, 7199576.0, 6446456.0, 7164579.0, 
+7690319.0, 8107202.0, 7462090.0, 8353962.0, 8807718.0, 5963658.0, 8163425.0, 6652851.0, 8169066.0, 6906018.0, 7448498.0, 8403353.0, 6499220.0, 9827668.0, 1.0370807E7, 8413234.0, 8979741.0, 6743719.0, 6583108.0, 6733404.0, 9203350.0, 8305284.0, 7661872.0, 8475391.0, 8638725.0, 7679995.0, 8961802.0, 6750314.0, 7049775.0, 8577580.0, 
+7412324.0, 8652125.0, 7961811.0, 9598288.0, 8296849.0, 6391772.0, 7240482.0, 7531594.0, 8110724.0, 7533868.0, 8155571.0, 8596878.0, 6925515.0, 7915918.0, 1.0572044E7, 8603488.0, 7693006.0, 7286678.0, 6399408.0, 6860014.0, 8027549.0, 7922416.0, 8053228.0, 9735395.0, 7584369.0, 8588126.0, 8653757.0, 7169521.0, 7682896.0, 8137235.0, 
+7988409.0, 7238778.0, 8449952.0, 7992084.0, 7262269.0, 5011760.0, 6432958.0, 7422948.0, 8648278.0, 7337408.0, 8462957.0, 7677222.0, 6397788.0, 7568297.0, 1.0797395E7, 7705063.0, 7146568.0, 6022723.0, 6370298.0, 7586299.0, 7452484.0, 7887693.0, 7307727.0, 9197385.0, 7726968.0, 8478492.0, 7601569.0, 6960883.0, 6522251.0, 7976344.0, 
+7572166.0, 7897218.0, 7706123.0, 7359858.0, 6988842.0, 5975477.0, 7234281.0, 8027665.0, 7471601.0, 7160694.0, 7249166.0, 8618544.0, 6644699.0, 8171915.0, 1.0497206E7, 8729802.0, 7174778.0, 5972218.0, 7216469.0, 7843533.0, 7628960.0, 7931021.0, 7962767.0, 9166492.0, 7547189.0, 8369468.0, 8488684.0, 5609773.0, 7562941.0, 8204473.0, 
+8857954.0, 8551958.0, 8909718.0, 9431684.0, 9556061.0, 6617423.0, 7827032.0, 8179745.0, 9353072.0, 7550842.0, 8121182.0, 8962388.0, 7937096.0, 8954704.0, 1.1085794E7, 9549551.0, 9145331.0, 7163225.0, 7988163.0, 8211966.0, 9352371.0, 9330003.0, 8532410.0, 1.0197366E7, 8931427.0, 8915845.0, 8823015.0, 7853048.0, 8044845.0, 9386048.0, 
+8545963.0, 7912549.0, 8606518.0, 8379764.0, 8351466.0, 6814749.0, 8057369.0, 8048780.0, 8451865.0, 7466527.0, 8749940.0, 8919463.0, 7276916.0, 8536482.0, 1.0911699E7, 9197448.0, 8560655.0, 7064115.0, 7860209.0, 8511883.0, 8654584.0, 9323289.0, 8981720.0, 9803015.0, 8598113.0, 8780796.0, 9135261.0, 6665333.0, 7324434.0, 8872122.0, 
+5946430.0, 6135788.0, 6591364.0, 6433251.0, 6632373.0, 4985963.0, 5769881.0, 4843727.0, 7021916.0, 5697194.0, 6385378.0, 6994046.0, 5502157.0, 7123974.0, 8365161.0, 6212258.0, 6104723.0, 5313031.0, 4845223.0, 5646055.0, 6129753.0, 6289476.0, 6051385.0, 7494259.0, 5723628.0, 6965055.0, 6172636.0, 5253106.0, 5610430.0, 6685980.0, 
+8055844.0, 8469174.0, 8170470.0, 8793113.0, 9859241.0, 7007325.0, 8137618.0, 8029717.0, 8997562.0, 7852580.0, 7740885.0, 9375326.0, 7883965.0, 1.0029182E7, 1.1346371E7, 9215599.0, 8636081.0, 7104102.0, 7496227.0, 8176023.0, 9732692.0, 8508678.0, 8257884.0, 1.0379885E7, 8448925.0, 9060668.0, 8836821.0, 7441640.0, 8726147.0, 9513821.0, 
+7367171.0, 7678838.0, 7804927.0, 8158615.0, 6673882.0, 6127379.0, 7575878.0, 6722516.0, 8300529.0, 6711008.0, 8389597.0, 8171405.0, 6196454.0, 7704372.0, 1.029698E7, 8112392.0, 7236981.0, 6508313.0, 6457042.0, 7280014.0, 7526900.0, 8231928.0, 7990796.0, 8184970.0, 7283106.0, 8214745.0, 8201658.0, 6708897.0, 6728783.0, 7449993.0, 
+7865362.0, 6776674.0, 8132061.0, 9041300.0, 7066772.0, 5445850.0, 7151522.0, 6942482.0, 7679044.0, 6487802.0, 8458847.0, 7314760.0, 6955102.0, 7314651.0, 9998347.0, 8897441.0, 7785211.0, 6248190.0, 6094040.0, 7118063.0, 7145775.0, 8373612.0, 7778499.0, 9104195.0, 6890059.0, 8603542.0, 8143136.0, 7583203.0, 6981314.0, 7304046.0, 
+7986730.0, 8495508.0, 8226132.0, 8837284.0, 8110164.0, 6270243.0, 7155084.0, 8144444.0, 7505249.0, 6776566.0, 8180893.0, 8341901.0, 6720764.0, 7941827.0, 1.0232075E7, 9099507.0, 8475362.0, 6245408.0, 7407245.0, 7953062.0, 7429359.0, 8415664.0, 8058703.0, 9250511.0, 7408836.0, 8633240.0, 8794298.0, 6612461.0, 6871055.0, 8223063.0, 
+7048151.0, 7129340.0, 7082981.0, 7489318.0, 8235538.0, 4945598.0, 7158417.0, 7404589.0, 7952446.0, 6524416.0, 7264108.0, 7881673.0, 6788833.0, 7675645.0, 1.0238341E7, 8484876.0, 7867557.0, 7037936.0, 7237519.0, 7346638.0, 7710289.0, 7883823.0, 7209172.0, 8844511.0, 7452039.0, 7340367.0, 7433870.0, 6571140.0, 7229344.0, 7904304.0, 
+8240448.0, 7954564.0, 8154706.0, 9504953.0, 8400499.0, 5460298.0, 7584126.0, 6871697.0, 9185194.0, 6905207.0, 9141475.0, 8494493.0, 7418418.0, 7753101.0, 1.0000234E7, 8633021.0, 7846515.0, 7199308.0, 6775263.0, 7435406.0, 8253684.0, 8758868.0, 8831361.0, 9095568.0, 8526076.0, 8528570.0, 8182811.0, 7299290.0, 7191919.0, 8226562.0, 
+6751777.0, 7186625.0, 6646412.0, 8018233.0, 6909389.0, 5658036.0, 6840978.0, 7190409.0, 7959774.0, 6192193.0, 6295944.0, 8365353.0, 6495593.0, 6989066.0, 9678769.0, 8422620.0, 6708233.0, 6122942.0, 6541236.0, 6976638.0, 7715128.0, 7027844.0, 7287427.0, 8765201.0, 6824683.0, 7411205.0, 7587931.0, 6447872.0, 6342510.0, 7582018.0, 
+7082585.0, 6197492.0, 6807726.0, 6956058.0, 6641216.0, 4830697.0, 5048238.0, 6053977.0, 6808066.0, 5552500.0, 6709804.0, 7175350.0, 6209976.0, 5950372.0, 8477306.0, 7412364.0, 5897445.0, 5540244.0, 5666371.0, 6696737.0, 6961106.0, 6862383.0, 6637593.0, 8019798.0, 5997948.0, 7597047.0, 6638311.0, 5646733.0, 6753680.0, 7600719.0, 
+7405626.0, 7342316.0, 6412193.0, 8347922.0, 7388131.0, 4709450.0, 6484686.0, 6422277.0, 7614878.0, 6155351.0, 8101524.0, 7056940.0, 5444306.0, 7010298.0, 9663947.0, 7786125.0, 6890705.0, 6006121.0, 6032720.0, 6508389.0, 7243995.0, 7137452.0, 6513236.0, 8338516.0, 7172679.0, 7934665.0, 8344129.0, 6707389.0, 6191989.0, 7659162.0, 
+8824351.0, 8499764.0, 7935349.0, 9362467.0, 7540129.0, 6218015.0, 8666871.0, 7431305.0, 9119473.0, 7093927.0, 8066413.0, 8889088.0, 6865107.0, 7703744.0, 1.1009442E7, 8749305.0, 8122317.0, 7493355.0, 6353037.0, 6661887.0, 8703986.0, 8305822.0, 8770358.0, 9415405.0, 8359360.0, 8392544.0, 8323587.0, 7316703.0, 6900664.0, 7998790.0, 
+8559320.0, 8232032.0, 8582628.0, 9561300.0, 8909146.0, 6399353.0, 7974575.0, 8670453.0, 9676934.0, 7602031.0, 9078286.0, 1.0045779E7, 7111219.0, 8996593.0, 1.226795E7, 1.0495147E7, 8627020.0, 7247946.0, 8214785.0, 8248879.0, 8942703.0, 1.0207892E7, 9159335.0, 9386478.0, 9122587.0, 9412550.0, 1.0407378E7, 8320858.0, 8412198.0, 9183005.0, 
+7864178.0, 7731246.0, 7874580.0, 8126602.0, 8217140.0, 6306880.0, 7598202.0, 6913447.0, 7964758.0, 7035041.0, 7879116.0, 8569671.0, 7028566.0, 9038832.0, 1.0641974E7, 8450936.0, 9082649.0, 6675630.0, 6481241.0, 6939335.0, 8501496.0, 8693928.0, 7876616.0, 8953343.0, 7470078.0, 7817750.0, 7845736.0, 7283306.0, 7144396.0, 8159051.0, 
+8244761.0, 8043437.0, 8160617.0, 7960796.0, 7638538.0, 5521627.0, 6770600.0, 6827077.0, 7424432.0, 7085102.0, 6703036.0, 8663556.0, 6008305.0, 8127122.0, 1.0757715E7, 7838981.0, 7320679.0, 6470974.0, 6395050.0, 7078761.0, 9051568.0, 8296696.0, 7669203.0, 8793438.0, 7935840.0, 8242858.0, 8167852.0, 6513437.0, 7222152.0, 8621155.0, 
+5398601.0, 5656258.0, 6127160.0, 6431306.0, 5861315.0, 4330490.0, 5807953.0, 5755300.0, 6320034.0, 6114599.0, 5885148.0, 6497254.0, 5450734.0, 6993714.0, 8061082.0, 6229394.0, 6511621.0, 4914814.0, 4902640.0, 5650877.0, 6261491.0, 6670406.0, 5878213.0, 7134964.0, 5872648.0, 6551681.0, 7116052.0, 5637658.0, 5610163.0, 6938664.0, 
+6665479.0, 6655902.0, 6361533.0, 6987969.0, 6216951.0, 4491075.0, 5339732.0, 5808102.0, 7720459.0, 6041092.0, 7229382.0, 7153949.0, 5369655.0, 6203304.0, 8545499.0, 6785740.0, 6520276.0, 5817279.0, 5606822.0, 6256946.0, 6558416.0, 6783016.0, 6327605.0, 7218378.0, 6631328.0, 6923787.0, 7005653.0, 5461050.0, 6094680.0, 7234228.0, 
+5843630.0, 6349173.0, 6588290.0, 6096008.0, 6187686.0, 4971317.0, 6130619.0, 5956329.0, 6069945.0, 6017854.0, 6689679.0, 6237127.0, 5164682.0, 6970236.0, 8278739.0, 6412665.0, 6644780.0, 4531485.0, 5404887.0, 5762443.0, 6496410.0, 7358530.0, 6524107.0, 7809916.0, 6432073.0, 6378435.0, 7274185.0, 5883336.0, 5290775.0, 7048857.0, 
+8593925.0, 7961767.0, 8292016.0, 8257014.0, 8765041.0, 5832016.0, 8184239.0, 8118105.0, 8933460.0, 7297129.0, 7909218.0, 9048344.0, 7497893.0, 8965430.0, 1.135426E7, 9530131.0, 8401874.0, 7390341.0, 7549933.0, 7675511.0, 8338916.0, 8618154.0, 8505674.0, 9483324.0, 8414926.0, 8193850.0, 9268065.0, 7355728.0, 8122626.0, 8739657.0, 
+7908996.0, 7506755.0, 7778220.0, 8175639.0, 5766252.0, 6284412.0, 7460913.0, 6975311.0, 7164714.0, 6767688.0, 7763452.0, 7215835.0, 6324251.0, 7271730.0, 9511219.0, 8140001.0, 7262476.0, 5372931.0, 6328202.0, 7443961.0, 7220668.0, 7721429.0, 8144112.0, 9294316.0, 6481768.0, 8506164.0, 8022424.0, 5875671.0, 5724007.0, 7793814.0, 
+7633150.0, 7688795.0, 7394176.0, 9147539.0, 8138372.0, 6018889.0, 6933383.0, 7053057.0, 8134616.0, 7254464.0, 7889703.0, 8526882.0, 7741309.0, 8523760.0, 1.0130337E7, 9570375.0, 8261785.0, 6437251.0, 6961202.0, 7470969.0, 8885321.0, 7952766.0, 8360734.0, 9775719.0, 7554078.0, 8847637.0, 8491061.0, 7347352.0, 7755601.0, 8960722.0, 
+7960421.0, 8470588.0, 8332189.0, 8444058.0, 8235295.0, 6839043.0, 7517756.0, 7415098.0, 8360872.0, 7000654.0, 8095598.0, 8937832.0, 5813282.0, 8713683.0, 1.0340755E7, 8893432.0, 8245456.0, 6941267.0, 7209275.0, 8630017.0, 9331110.0, 8897494.0, 7845643.0, 9026386.0, 8115773.0, 8895582.0, 8748333.0, 7461803.0, 7814024.0, 9201676.0
+};
diff --git a/benchmarks/dgemm/dgemm_gendata.scala b/benchmarks/dgemm/dgemm_gendata.scala
new file mode 100644 (file)
index 0000000..de2740b
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env scala
+!#
+
+val size = args(0).toInt
+
+def print_matrix(name: String, rows: Int, cols: Int, data: Array[Double]) = {
+  println("const double " + name + "[DATA_SIZE*DATA_SIZE] = {")
+  for (i <- 0 until rows) {
+    println(data.slice(cols*i, cols*(i+1)).mkString(", ") + (if (i < rows-1) ", " else ""))
+  }
+  println("};")
+}
+def rand_matrix(rows: Int, cols: Int) = {
+  var r = new scala.util.Random
+  var m = new Array[Double](rows*cols)
+  for (i <- 0 until rows*cols)
+    m(i) = r.nextInt(1000)
+  m
+}
+def matmul(a: Array[Double], b: Array[Double], m: Int, n: Int, k: Int) = {
+  var c = new Array[Double](m*n)
+  for (i <- 0 until m)
+    for (j <- 0 until n)
+      for (l <- 0 until k)
+        c(i*n+j) += a(i*n+l)*b(l*k+j)
+  c
+}
+
+println("#define DATA_SIZE " + size)
+
+val a = rand_matrix(size, size)
+val b = rand_matrix(size, size)
+val c = matmul(a, b, size, size, size)
+
+print_matrix("input1_data", size, size, a)
+print_matrix("input2_data", size, size, b)
+print_matrix("verify_data", size, size, c)
diff --git a/benchmarks/dgemm/dgemm_main.c b/benchmarks/dgemm/dgemm_main.c
new file mode 100644 (file)
index 0000000..7c8ce7c
--- /dev/null
@@ -0,0 +1,205 @@
+//**************************************************************************
+// Double-precision general matrix multiplication benchmark
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( long n, const double test[], const double correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+#include <stdio.h>
+#include <stdlib.h>
+void printArray( char name[], long n, const double arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %8.1f ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// square_dgemm function
+
+void square_dgemm( long n0, const double a0[], const double b0[], double c0[] )
+{
+  long n = (n0+2)/3*3;
+  double a[n*n], b[n*n], c[n*n];
+
+  for (long i = 0; i < n0; i++)
+  {
+    long j;
+    for (j = 0; j < n0; j++)
+    {
+      a[i*n+j] = a0[i*n0+j];
+      b[i*n+j] = b0[j*n0+i];
+    }
+    for ( ; j < n; j++)
+    {
+      a[i*n+j] = b[i*n+j] = 0;
+    }
+  }
+  for (long i = n0; i < n; i++)
+    for (long j = 0; j < n; j++)
+      a[i*n+j] = b[i*n+j] = 0;
+
+  long i, j, k;
+  for (i = 0; i < n; i+=3)
+  {
+    for (j = 0; j < n; j+=3)
+    {
+      double *a0 = a + (i+0)*n, *b0 = b + (j+0)*n;
+      double *a1 = a + (i+1)*n, *b1 = b + (j+1)*n;
+      double *a2 = a + (i+2)*n, *b2 = b + (j+2)*n;
+
+      double s00 = 0, s01 = 0, s02 = 0;
+      double s10 = 0, s11 = 0, s12 = 0;
+      double s20 = 0, s21 = 0, s22 = 0;
+
+      while (a0 < a + (i+1)*n)
+      {
+        double a00 = a0[0], a01 = a0[1], a02 = a0[2];
+        double b00 = b0[0], b01 = b0[1], b02 = b0[2];
+        double a10 = a1[0], a11 = a1[1], a12 = a1[2];
+        double b10 = b1[0], b11 = b1[1], b12 = b1[2];
+        asm ("" ::: "memory");
+        double a20 = a2[0], a21 = a2[1], a22 = a2[2];
+        double b20 = b2[0], b21 = b2[1], b22 = b2[2];
+
+        s00 = a00*b00 + (a01*b01 + (a02*b02 + s00));
+        s01 = a00*b10 + (a01*b11 + (a02*b12 + s01));
+        s02 = a00*b20 + (a01*b21 + (a02*b22 + s02));
+        s10 = a10*b00 + (a11*b01 + (a12*b02 + s10));
+        s11 = a10*b10 + (a11*b11 + (a12*b12 + s11));
+        s12 = a10*b20 + (a11*b21 + (a12*b22 + s12));
+        s20 = a20*b00 + (a21*b01 + (a22*b02 + s20));
+        s21 = a20*b10 + (a21*b11 + (a22*b12 + s21));
+        s22 = a20*b20 + (a21*b21 + (a22*b22 + s22));
+
+        a0 += 3; b0 += 3;
+        a1 += 3; b1 += 3;
+        a2 += 3; b2 += 3;
+      }
+
+      c[(i+0)*n+j+0] = s00; c[(i+0)*n+j+1] = s01; c[(i+0)*n+j+2] = s02;
+      c[(i+1)*n+j+0] = s10; c[(i+1)*n+j+1] = s11; c[(i+1)*n+j+2] = s12;
+      c[(i+2)*n+j+0] = s20; c[(i+2)*n+j+1] = s21; c[(i+2)*n+j+2] = s22;
+    }
+  }
+
+  for (long i = 0; i < n0; i++)
+  {
+    long j;
+    for (j = 0; j < n0 - 2; j+=3)
+    {
+      c0[i*n0+j+0] = c[i*n+j+0];
+      c0[i*n0+j+1] = c[i*n+j+1];
+      c0[i*n0+j+2] = c[i*n+j+2];
+    }
+    for ( ; j < n0; j++)
+      c0[i*n0+j] = c[i*n+j];
+  }
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  double results_data[DATA_SIZE*DATA_SIZE];
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input1", DATA_SIZE*DATA_SIZE, input1_data );
+  printArray( "input2", DATA_SIZE*DATA_SIZE, input2_data );
+  printArray( "verify", DATA_SIZE*DATA_SIZE, verify_data );
+#endif
+
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+  square_dgemm( DATA_SIZE, input1_data, input2_data, results_data );
+#endif
+
+  // Do the dgemm
+
+  setStats(1);
+  square_dgemm( DATA_SIZE, input1_data, input2_data, results_data );
+  setStats(0);
+
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", DATA_SIZE*DATA_SIZE, results_data );
+#endif
+
+  // Check the results
+
+  finishTest(verify( DATA_SIZE*DATA_SIZE, results_data, verify_data ));
+
+}
diff --git a/benchmarks/dhrystone/bmark.mk b/benchmarks/dhrystone/bmark.mk
new file mode 100644 (file)
index 0000000..6e45706
--- /dev/null
@@ -0,0 +1,31 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+dhrystone_c_src = \
+       dhrystone_main.c \
+       dhrystone.c \
+
+dhrystone_riscv_src = \
+       crt.S \
+
+dhrystone_c_objs     = $(patsubst %.c, %.o, $(dhrystone_c_src))
+dhrystone_riscv_objs = $(patsubst %.S, %.o, $(dhrystone_riscv_src))
+
+dhrystone_host_bin = dhrystone.host
+$(dhrystone_host_bin): $(dhrystone_c_src)
+       $(HOST_COMP) $^ -o $(dhrystone_host_bin)
+
+dhrystone_riscv_bin = dhrystone.riscv
+$(dhrystone_riscv_bin): $(dhrystone_c_objs) $(dhrystone_riscv_objs)
+       $(RISCV_LINK) $(dhrystone_c_objs) $(dhrystone_riscv_objs) \
+    -o $(dhrystone_riscv_bin) $(RISCV_LINK_OPTS)
+
+junk += $(dhrystone_c_objs) $(dhrystone_riscv_objs) \
+        $(dhrystone_host_bin) $(dhrystone_riscv_bin)
diff --git a/benchmarks/dhrystone/dhrystone.c b/benchmarks/dhrystone/dhrystone.c
new file mode 100644 (file)
index 0000000..abc45d4
--- /dev/null
@@ -0,0 +1,160 @@
+#include "dhrystone.h"
+
+#ifndef REG
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+#undef REG
+#define REG register
+#endif
+
+extern  int     Int_Glob;
+extern  char    Ch_1_Glob;
+
+
+void Proc_6(Enumeration Enum_Val_Par, Enumeration* Enum_Ref_Par)
+/*********************************/
+    /* executed once */
+    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+  *Enum_Ref_Par = Enum_Val_Par;
+  if (! Func_3 (Enum_Val_Par))
+    /* then, not executed */
+    *Enum_Ref_Par = Ident_4;
+  switch (Enum_Val_Par)
+  {
+    case Ident_1: 
+      *Enum_Ref_Par = Ident_1;
+      break;
+    case Ident_2: 
+      if (Int_Glob > 100)
+        /* then */
+      *Enum_Ref_Par = Ident_1;
+      else *Enum_Ref_Par = Ident_4;
+      break;
+    case Ident_3: /* executed */
+      *Enum_Ref_Par = Ident_2;
+      break;
+    case Ident_4: break;
+    case Ident_5: 
+      *Enum_Ref_Par = Ident_3;
+      break;
+  } /* switch */
+} /* Proc_6 */
+
+
+void Proc_7(int Int_1_Par_Val, int Int_2_Par_Val, int* Int_Par_Ref)
+/**********************************************/
+    /* executed three times                                      */ 
+    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+    /*                  Int_Par_Ref becomes 7                    */
+    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+    /*                  Int_Par_Ref becomes 17                   */
+    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+    /*                  Int_Par_Ref becomes 18                   */
+{
+  One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 2;
+  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val)
+/*********************************************************************/
+    /* executed once      */
+    /* Int_Par_Val_1 == 3 */
+    /* Int_Par_Val_2 == 7 */
+{
+  REG One_Fifty Int_Index;
+  REG One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 5;
+  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+  Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (char Ch_1_Par_Val, char Ch_2_Par_Val)
+/*************************************************/
+    /* executed three times                                         */
+    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+{
+  Capital_Letter        Ch_1_Loc;
+  Capital_Letter        Ch_2_Loc;
+
+  Ch_1_Loc = Ch_1_Par_Val;
+  Ch_2_Loc = Ch_1_Loc;
+  if (Ch_2_Loc != Ch_2_Par_Val)
+    /* then, executed */
+    return (Ident_1);
+  else  /* not executed */
+  {
+    Ch_1_Glob = Ch_1_Loc;
+    return (Ident_2);
+   }
+} /* Func_1 */
+
+
+Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref)
+/*************************************************/
+    /* executed once */
+    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+{
+  REG One_Thirty        Int_Loc;
+      Capital_Letter    Ch_Loc;
+
+  Int_Loc = 2;
+  while (Int_Loc <= 2) /* loop body executed once */
+    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+      /* then, executed */
+    {
+      Ch_Loc = 'A';
+      Int_Loc += 1;
+    } /* if, while */
+  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+    /* then, not executed */
+    Int_Loc = 7;
+  if (Ch_Loc == 'R')
+    /* then, not executed */
+    return (true);
+  else /* executed */
+  {
+    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+      /* then, not executed */
+    {
+      Int_Loc += 7;
+      Int_Glob = Int_Loc;
+      return (true);
+    }
+    else /* executed */
+      return (false);
+  } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3(Enumeration Enum_Par_Val)
+/***************************/
+    /* executed once        */
+    /* Enum_Par_Val == Ident_3 */
+{
+  Enumeration Enum_Loc;
+
+  Enum_Loc = Enum_Par_Val;
+  if (Enum_Loc == Ident_3)
+    /* then, executed */
+    return (true);
+  else /* not executed */
+    return (false);
+} /* Func_3 */
diff --git a/benchmarks/dhrystone/dhrystone.h b/benchmarks/dhrystone/dhrystone.h
new file mode 100644 (file)
index 0000000..8abb874
--- /dev/null
@@ -0,0 +1,491 @@
+#ifndef _DHRYSTONE_H
+#define _DHRYSTONE_H
+
+/****************** "DHRYSTONE" Benchmark Program ***************************/
+#define Version "C, Version 2.2"
+/*  File:       dhry_1.c (part 2 of 3)
+ *  Author:     Reinhold P. Weicker
+ *              Siemens Nixdorf, Paderborn/Germany
+ *              weicker@specbench.org
+ *  Date:       May 25, 1988
+ *  Modified:  Steven Pemberton, CWI, Amsterdam; Steven.Pemberton@cwi.nl
+ *  Date:       October, 1993; March 1995
+ *              Included both files into one source, that gets compiled
+ *              in two passes. Made program auto-compiling, and auto-running,
+ *              and generally made it much easier to use.
+ *
+ *              Original Version (in Ada) published in
+ *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ *              pp. 1013 - 1030, together with the statistics
+ *              on which the distribution of statements etc. is based.
+ *
+ *              In this C version, the following C library functions are used:
+ *              - strcpy, strcmp (inside the measurement loop)
+ *              - printf, scanf (outside the measurement loop)
+ *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ *              are used for execution time measurement. For measurements
+ *              on other systems, these calls have to be changed.
+ *
+ *  Collection of Results:
+ *              Reinhold Weicker (address see above) and
+ *              
+ *              Rick Richardson
+ *              PC Research. Inc.
+ *              94 Apple Orchard Drive
+ *              Tinton Falls, NJ 07724
+ *                      Phone:  (201) 389-8963 (9-17 EST)               
+ *                      Usenet: ...!uunet!pcrat!rick
+ *
+ *      Please send results to Rick Richardson and/or Reinhold Weicker.
+ *      Complete information should be given on hardware and software used.
+ *      Hardware information includes: Machine type, CPU, type and size
+ *      of caches; for microprocessors: clock frequency, memory speed
+ *      (number of wait states).
+ *      Software information includes: Compiler (and runtime library)
+ *      manufacturer and version, compilation switches, OS version.
+ *      The Operating System version may give an indication about the compiler;
+ *      Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ *      The complete output generated by the program should be mailed
+ *      such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ * Defines:     The following "Defines" are possible:
+ *      -DREG          (default: Not defined)
+ *              As an approximation to what an average C programmer
+ *              might do, causes the "register" storage class to be applied
+ *              - for local variables, if they are used (dynamically)
+ *                five or more times
+ *              - for parameters if they are used (dynamically)
+ *                six or more times
+ *              Note that an optimal "register" strategy is
+ *              compiler-dependent, and that "register" declarations
+ *              do not necessarily lead to faster execution.
+ *      -DNOSTRUCTASSIGN        (default: Not defined)
+ *              Define if the C compiler does not support
+ *              assignment of structures.
+ *      -DNOENUMS               (default: Not defined)
+ *              Define if the C compiler does not support
+ *              enumeration types.
+ *      -DTIMES                 (default)
+ *      -DTIME
+ *              The "times" function of UNIX (returning process times)
+ *              or the "time" function (returning wallclock time)
+ *              is used for measurement. 
+ *              For single user machines, "time ()" is adequate. For
+ *              multi-user machines where you cannot get single-user
+ *              access, use the "times ()" function. If you have
+ *              neither, use a stopwatch in the dead of night.
+ *              "printf"s are provided marking the points "Start Timer"
+ *              and "Stop Timer". DO NOT use the UNIX "time(1)"
+ *              command, as this will measure the total time to
+ *              run this program, which will (erroneously) include
+ *              the time to allocate storage (malloc) and to perform
+ *              the initialization.
+ *      -DHZ=nnn
+ *              In Berkeley UNIX, the function "times" returns process
+ *              time in 1/HZ seconds, with HZ = 60 for most systems.
+ *              CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ *              A VALUE.
+ *
+ ***************************************************************************
+ *
+ *  History:   Version C/2.1 was made for two reasons:
+ *
+ *     1) There was an obvious need for a common C version of
+ *      Dhrystone, since C is at present the most popular system
+ *      programming language for the class of processors
+ *      (microcomputers, minicomputers) where Dhrystone is used most.
+ *      There should be, as far as possible, only one C version of
+ *      Dhrystone such that results can be compared without
+ *      restrictions. In the past, the C versions distributed
+ *      by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ *      had small (though not significant) differences.
+ *
+ *      2) As far as it is possible without changes to the Dhrystone
+ *      statistics, optimizing compilers should be prevented from
+ *      removing significant statements.
+ *
+ *      This C version has been developed in cooperation with
+ *      Rick Richardson (Tinton Falls, NJ), it incorporates many
+ *      ideas from the "Version 1.1" distributed previously by
+ *      him over the UNIX network Usenet.
+ *      I also thank Chaim Benedelac (National Semiconductor),
+ *      David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ *      Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ *      for their help with comments on earlier versions of the
+ *      benchmark.
+ *
+ *  Changes:    In the initialization part, this version follows mostly
+ *      Rick Richardson's version distributed via Usenet, not the
+ *      version distributed earlier via floppy disk by Reinhold Weicker.
+ *      As a concession to older compilers, names have been made
+ *      unique within the first 8 characters.
+ *      Inside the measurement loop, this version follows the
+ *      version previously distributed by Reinhold Weicker.
+ *
+ *      At several places in the benchmark, code has been added,
+ *      but within the measurement loop only in branches that 
+ *      are not executed. The intention is that optimizing compilers
+ *      should be prevented from moving code out of the measurement
+ *      loop, or from removing code altogether. Since the statements
+ *      that are executed within the measurement loop have NOT been
+ *      changed, the numbers defining the "Dhrystone distribution"
+ *      (distribution of statements, operand types and locality)
+ *      still hold. Except for sophisticated optimizing compilers,
+ *      execution times for this version should be the same as
+ *      for previous versions.
+ *
+ *      Since it has proven difficult to subtract the time for the
+ *      measurement loop overhead in a correct way, the loop check
+ *      has been made a part of the benchmark. This does have
+ *      an impact - though a very minor one - on the distribution
+ *      statistics which have been updated for this version.
+ *
+ *      All changes within the measurement loop are described
+ *      and discussed in the companion paper "Rationale for
+ *      Dhrystone version 2".
+ *
+ *      Because of the self-imposed limitation that the order and
+ *      distribution of the executed statements should not be
+ *      changed, there are still cases where optimizing compilers
+ *      may not generate code for some statements. To a certain
+ *      degree, this is unavoidable for small synthetic benchmarks.
+ *      Users of the benchmark are advised to check code listings
+ *      whether code is generated for all statements of Dhrystone.
+ *
+ *      Version 2.1 is identical to version 2.0 distributed via
+ *      the UNIX network Usenet in March 1988 except that it corrects
+ *      some minor deficiencies that were found by users of version 2.0.
+ *      The only change within the measurement loop is that a
+ *      non-executed "else" part was added to the "if" statement in
+ *      Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ * Version C/2.2, Steven Pemberton, October 1993
+ *     Functionally, identical to version 2.2; the changes are in
+ *     how you compile and use it:
+ *     - Everything is in one file now, but compiled in 2 passes
+ *     - Compile (and run) by running the file through the shell: 'sh dhry.c"
+ *     - Uses the system definition of HZ if one can be found
+ *     - HZ must be defined, otherwise it won't compile (no defaults here)
+ *     - The (uninteresting) output is printed to stderr (dhry2 > /dev/null)
+ *     - The number of loops is passed as a parameter, rather than read
+ *       (dhry2 500000)
+ *     - If the number of loops is insufficient to get a good result,
+ *       it repeats it with loops*10 until it is enough (rather than just
+ *       stopping)
+ *     - Output says which sort of clock it is using, and the HZ value
+ *     - You can use -DREG instead of the -DREG=register of previous versions
+ *     - Some stylistic cleanups.
+ *             
+ ***************************************************************************
+ *
+ *  Compilation model and measurement (IMPORTANT):
+ *
+ *  The following "ground rules" apply for measurements:
+ *  - Separate compilation
+ *  - No procedure merging
+ *  - Otherwise, compiler optimizations are allowed but should be indicated
+ *  - Default results are those without register declarations
+ *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+ *  detailed discussion of these ground rules.
+ *
+ *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ *  models ("small", "medium", "large" etc.) should be given if possible,
+ *  together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ *  Dhrystone (C version) statistics:
+ *
+ *  [Comment from the first distribution, updated for version 2.
+ *   Note that because of language differences, the numbers are slightly
+ *   different from the Ada version.]
+ *
+ *  The following program contains statements of a high level programming
+ *  language (here: C) in a distribution considered representative:           
+ *
+ *    assignments                  52 (51.0 %)
+ *    control statements           33 (32.4 %)
+ *    procedure, function calls    17 (16.7 %)
+ *
+ *  103 statements are dynamically executed. The program is balanced with
+ *  respect to the three aspects:                                             
+ *
+ *    - statement type
+ *    - operand type
+ *    - operand locality
+ *         operand global, local, parameter, or constant.                     
+ *
+ *  The combination of these three aspects is balanced only approximately.    
+ *
+ *  1. Statement Type:                                                        
+ *  -----------------             number
+ *
+ *     V1 = V2                     9
+ *       (incl. V1 = F(..)
+ *     V = Constant               12
+ *     Assignment,                 7
+ *       with array element
+ *     Assignment,                 6
+ *       with record component
+ *                                --
+ *                                34       34
+ *
+ *     X = Y +|-|"&&"|"|" Z        5
+ *     X = Y +|-|"==" Constant     6
+ *     X = X +|- 1                 3
+ *     X = Y *|/ Z                 2
+ *     X = Expression,             1
+ *           two operators
+ *     X = Expression,             1
+ *           three operators
+ *                                --
+ *                                18       18
+ *
+ *     if ....                    14
+ *       with "else"      7
+ *       without "else"   7
+ *           executed        3
+ *           not executed    4
+ *     for ...                     7  |  counted every time
+ *     while ...                   4  |  the loop condition
+ *     do ... while                1  |  is evaluated
+ *     switch ...                  1
+ *     break                       1
+ *     declaration with            1
+ *       initialization
+ *                                --
+ *                                34       34
+ *
+ *     P (...)  procedure call    11
+ *       user procedure      10
+ *       library procedure    1
+ *     X = F (...)
+ *             function  call      6
+ *       user function        5                                         
+ *       library function     1                                               
+ *                                --                                          
+ *                                17       17
+ *                                        ---
+ *                                        103
+ *
+ *    The average number of parameters in procedure or function calls
+ *    is 1.82 (not counting the function values aX *
+ *
+ *  2. Operators
+ *  ------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *    Arithmetic             32          50.8                                 
+ *
+ *       +                     21          33.3                              
+ *       -                      7          11.1                              
+ *       *                      3           4.8
+ *       / (int div)            1           1.6
+ *
+ *    Comparison             27           42.8
+ *
+ *       ==                     9           14.3
+ *       /=                     4            6.3
+ *       >                      1            1.6
+ *       <                      3            4.8
+ *       >=                     1            1.6
+ *       <=                     9           14.3
+ *
+ *    Logic                   4            6.3
+ *
+ *       && (AND-THEN)          1            1.6
+ *       |  (OR)                1            1.6
+ *       !  (NOT)               2            3.2
+ * 
+ *                           --          -----
+ *                           63          100.1
+ *
+ *
+ *  3. Operand Type (counted once per operand reference):
+ *  ---------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *     Integer               175        72.3 %
+ *     Character              45        18.6 %
+ *     Pointer                12         5.0 %
+ *     String30                6         2.5 %
+ *     Array                   2         0.8 %
+ *     Record                  2         0.8 %
+ *                           ---       -------
+ *                           242       100.0 %
+ *
+ *  When there is an access path leading to the final operand (e.g. a record
+ *  component), only the final data type on the access path is counted.       
+ *
+ *
+ *  4. Operand Locality:                                                      
+ *  -------------------
+ *                                number    approximate
+ *                                          percentage
+ *
+ *     local variable              114        47.1 %
+ *     global variable              22         9.1 %
+ *     parameter                    45        18.6 %
+ *        value                        23         9.5 %
+ *        reference                    22         9.1 %
+ *     function result               6         2.5 %
+ *     constant                     55        22.7 %
+ *                                 ---       -------
+ *                                 242       100.0 %
+ *
+ *  The program does not compute anything meaningful, but it is syntactically
+ *  and semantically correct. All variables have a value assigned to them
+ *  before they are used as a source operand.
+ *
+ *  There has been no explicit effort to account for the effects of a
+ *  cache, or to balance the use of long or short displacements for code or
+ *  data.
+ *
+ ***************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+/* variables for time measurement: */
+
+#ifdef TIME
+
+#define CLOCK_TYPE "time()"
+#undef HZ
+#define HZ     (1) /* time() returns time in seconds */
+extern long     time(); /* see library function "time"  */
+#define Too_Small_Time 2 /* Measurements should last at least 2 seconds */
+#define Start_Timer() Begin_Time = time ( (long *) 0)
+#define Stop_Timer()  End_Time   = time ( (long *) 0)
+
+#else
+
+#ifdef MSC_CLOCK /* Use Microsoft C hi-res clock */
+
+#undef HZ
+#undef TIMES
+#include <time.h>
+#define HZ     CLK_TCK
+#define CLOCK_TYPE "MSC clock()"
+extern clock_t clock();
+#define Too_Small_Time (2*HZ)
+#define Start_Timer() Begin_Time = clock()
+#define Stop_Timer()  End_Time   = clock()
+
+#elif defined(__riscv)
+
+#define HZ 976563
+#define Too_Small_Time 50
+#define rdcycle() ({ \
+  long __x; \
+  asm volatile("rdcycle %0; srl %0, %0, 10" : "=r"(__x)); \
+  __x; })
+#define CLOCK_TYPE "rdcycle()"
+#define Start_Timer() Begin_Time = rdcycle()
+#define Stop_Timer() End_Time = rdcycle()
+
+#else
+                /* Use times(2) time function unless    */
+                /* explicitly defined otherwise         */
+#define CLOCK_TYPE "times()"
+#include <sys/types.h>
+#include <sys/times.h>
+#ifndef HZ     /* Added by SP 900619 */
+#include <sys/param.h> /* If your system doesn't have this, use -DHZ=xxx */
+#else
+       *** You must define HZ!!! ***
+#endif /* HZ */
+#ifndef PASS2
+struct tms      time_info;
+#endif
+/*extern  int     times ();*/
+                /* see library function "times" */
+#define Too_Small_Time (2*HZ)
+                /* Measurements should last at least about 2 seconds */
+#define Start_Timer() times(&time_info); Begin_Time=(long)time_info.tms_utime
+#define Stop_Timer()  times(&time_info); End_Time = (long)time_info.tms_utime
+
+#endif /* MSC_CLOCK */
+#endif /* TIME */
+
+
+#define Mic_secs_Per_Second     1000000.0
+#define NUMBER_OF_RUNS         500 /* Default number of runs */
+
+#ifdef  NOSTRUCTASSIGN
+#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s)      d = s
+#endif
+
+#ifdef  NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+  typedef int   Enumeration;
+#else
+  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+                Enumeration;
+#endif
+        /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+#include <string.h>
+                /* for strcpy, strcmp */
+
+#define Null 0 
+                /* Value of a Null pointer */
+#define true  1
+#define false 0
+
+typedef int     One_Thirty;
+typedef int     One_Fifty;
+typedef char    Capital_Letter;
+typedef int     Boolean;
+typedef char    Str_30 [31];
+typedef int     Arr_1_Dim [50];
+typedef int     Arr_2_Dim [50] [50];
+
+typedef struct record 
+    {
+    struct record *Ptr_Comp;
+    Enumeration    Discr;
+    union {
+          struct {
+                  Enumeration Enum_Comp;
+                  int         Int_Comp;
+                  char        Str_Comp [31];
+                  } var_1;
+          struct {
+                  Enumeration E_Comp_2;
+                  char        Str_2_Comp [31];
+                  } var_2;
+          struct {
+                  char        Ch_1_Comp;
+                  char        Ch_2_Comp;
+                  } var_3;
+          } variant;
+      } Rec_Type, *Rec_Pointer;
+
+void Proc_1(Rec_Pointer Ptr_Val_Par);
+void Proc_2(int* Int_Par_Ref);
+void Proc_3(Rec_Pointer* Ptr_Ref_Par);
+void Proc_4();
+void Proc_5();
+void Proc_6(Enumeration Enum_Val_Par, Enumeration* Enum_Ref_Par);
+void Proc_7(int Int_1_Par_Val, int Int_2_Par_Val, int* Int_Par_Ref);
+void Proc_8(Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val);
+Enumeration Func_1 (char Ch_1_Par_Val, char Ch_2_Par_Val);
+Boolean Func_2(Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
+Boolean Func_3(Enumeration Enum_Par_Val);
+
+#endif
diff --git a/benchmarks/dhrystone/dhrystone_main.c b/benchmarks/dhrystone/dhrystone_main.c
new file mode 100644 (file)
index 0000000..7e8c6af
--- /dev/null
@@ -0,0 +1,400 @@
+//**************************************************************************
+// Dhrystone bencmark
+//--------------------------------------------------------------------------
+//
+// This is the classic Dhrystone synthetic integer benchmark.
+// You should not change anything except the HOST_DEBUG and
+// PREALLOCATE macros for your timing run.
+
+#include "dhrystone.h"
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+#if HOST_DEBUG
+# define do_fprintf fprintf
+#else
+int __attribute__((noinline)) do_fprintf(FILE* f, const char* str, ...)
+{
+  return 0;
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+#include <alloca.h>
+
+/* Global Variables: */
+
+Rec_Pointer     Ptr_Glob,
+                Next_Ptr_Glob;
+int             Int_Glob;
+Boolean         Bool_Glob;
+char            Ch_1_Glob,
+                Ch_2_Glob;
+int             Arr_1_Glob [50];
+int             Arr_2_Glob [50] [50];
+
+#ifndef REG
+        Boolean Reg = false;
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+        Boolean Reg = true;
+#undef REG
+#define REG register
+#endif
+
+Boolean                Done;
+
+long            Begin_Time,
+                End_Time,
+                User_Time;
+float           Microseconds,
+                Dhrystones_Per_Second;
+
+/* end of variables for time measurement */
+
+
+int main (int argc, char** argv)
+/*****/
+  /* main program, corresponds to procedures        */
+  /* Main and Proc_0 in the Ada version             */
+{
+        One_Fifty       Int_1_Loc;
+  REG   One_Fifty       Int_2_Loc;
+        One_Fifty       Int_3_Loc;
+  REG   char            Ch_Index;
+        Enumeration     Enum_Loc;
+        Str_30          Str_1_Loc;
+        Str_30          Str_2_Loc;
+  REG   int             Run_Index;
+  REG   int             Number_Of_Runs;
+
+  /* Arguments */
+#if HOST_DEBUG
+  if (argc > 2)
+  {
+     do_fprintf (stdout, "Usage: %s [number of loops]\n", argv[0]);
+     exit (1);
+  }
+  if (argc == 2)
+  {
+     Number_Of_Runs = atoi (argv[1]);
+  } else
+#endif
+  {
+     Number_Of_Runs = NUMBER_OF_RUNS;
+  }
+  if (Number_Of_Runs <= 0)
+  {
+     Number_Of_Runs = NUMBER_OF_RUNS;
+  }
+
+  /* Initializations */
+
+  Next_Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
+  Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
+
+  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+  Ptr_Glob->Discr                       = Ident_1;
+  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+  strcpy (Ptr_Glob->variant.var_1.Str_Comp, 
+          "DHRYSTONE PROGRAM, SOME STRING");
+  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+  Arr_2_Glob [8][7] = 10;
+        /* Was missing in published program. Without this statement,    */
+        /* Arr_2_Glob [8][7] would have an undefined value.             */
+        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+        /* overflow may occur for this array element.                   */
+
+#if HOST_DEBUG
+  do_fprintf (stdout, "\n");
+  do_fprintf (stdout, "Dhrystone Benchmark, Version %s\n", Version);
+  if (Reg)
+  {
+    do_fprintf (stdout, "Program compiled with 'register' attribute\n");
+  }
+  else
+  {
+    do_fprintf (stdout, "Program compiled without 'register' attribute\n");
+  }
+  do_fprintf (stdout, "Using %s, HZ=%d\n", CLOCK_TYPE, HZ);
+  do_fprintf (stdout, "\n");
+#endif
+
+  Done = false;
+  while (!Done) {
+#if HOST_DEBUG
+    do_fprintf (stdout, "Trying %d runs through Dhrystone:\n", Number_Of_Runs);
+#endif
+
+    /***************/
+    /* Start timer */
+    /***************/
+
+    Start_Timer();
+    setStats(1);
+
+    for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+    {
+
+      Proc_5();
+      Proc_4();
+       /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+      Int_1_Loc = 2;
+      Int_2_Loc = 3;
+      strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+      Enum_Loc = Ident_2;
+      Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+       /* Bool_Glob == 1 */
+      while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+      {
+       Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+         /* Int_3_Loc == 7 */
+       Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+         /* Int_3_Loc == 7 */
+       Int_1_Loc += 1;
+      } /* while */
+       /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+      Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+       /* Int_Glob == 5 */
+      Proc_1 (Ptr_Glob);
+      for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+                              /* loop body executed twice */
+      {
+       if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+           /* then, not executed */
+         {
+         Proc_6 (Ident_1, &Enum_Loc);
+         strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+         Int_2_Loc = Run_Index;
+         Int_Glob = Run_Index;
+         }
+      }
+       /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+      Int_2_Loc = Int_2_Loc * Int_1_Loc;
+      Int_1_Loc = Int_2_Loc / Int_3_Loc;
+      Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+       /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+      Proc_2 (&Int_1_Loc);
+       /* Int_1_Loc == 5 */
+
+    } /* loop "for Run_Index" */
+
+    /**************/
+    /* Stop timer */
+    /**************/
+
+    setStats(0);
+    Stop_Timer();
+
+    User_Time = End_Time - Begin_Time;
+
+    if (User_Time < Too_Small_Time)
+    {
+      do_fprintf (stdout, "Measured time too small to obtain meaningful results\n");
+      Number_Of_Runs = Number_Of_Runs * 10;
+      do_fprintf (stdout, "\n");
+    } else Done = true;
+  }
+
+  do_fprintf (stderr, "Final values of the variables used in the benchmark:\n");
+  do_fprintf (stderr, "\n");
+  do_fprintf (stderr, "Int_Glob:            %d\n", Int_Glob);
+  do_fprintf (stderr, "        should be:   %d\n", 5);
+  do_fprintf (stderr, "Bool_Glob:           %d\n", Bool_Glob);
+  do_fprintf (stderr, "        should be:   %d\n", 1);
+  do_fprintf (stderr, "Ch_1_Glob:           %c\n", Ch_1_Glob);
+  do_fprintf (stderr, "        should be:   %c\n", 'A');
+  do_fprintf (stderr, "Ch_2_Glob:           %c\n", Ch_2_Glob);
+  do_fprintf (stderr, "        should be:   %c\n", 'B');
+  do_fprintf (stderr, "Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
+  do_fprintf (stderr, "        should be:   %d\n", 7);
+  do_fprintf (stderr, "Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
+  do_fprintf (stderr, "        should be:   Number_Of_Runs + 10\n");
+  do_fprintf (stderr, "Ptr_Glob->\n");
+  do_fprintf (stderr, "  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
+  do_fprintf (stderr, "        should be:   (implementation-dependent)\n");
+  do_fprintf (stderr, "  Discr:             %d\n", Ptr_Glob->Discr);
+  do_fprintf (stderr, "        should be:   %d\n", 0);
+  do_fprintf (stderr, "  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+  do_fprintf (stderr, "        should be:   %d\n", 2);
+  do_fprintf (stderr, "  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+  do_fprintf (stderr, "        should be:   %d\n", 17);
+  do_fprintf (stderr, "  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+  do_fprintf (stderr, "        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  do_fprintf (stderr, "Next_Ptr_Glob->\n");
+  do_fprintf (stderr, "  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+  do_fprintf (stderr, "        should be:   (implementation-dependent), same as above\n");
+  do_fprintf (stderr, "  Discr:             %d\n", Next_Ptr_Glob->Discr);
+  do_fprintf (stderr, "        should be:   %d\n", 0);
+  do_fprintf (stderr, "  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+  do_fprintf (stderr, "        should be:   %d\n", 1);
+  do_fprintf (stderr, "  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+  do_fprintf (stderr, "        should be:   %d\n", 18);
+  do_fprintf (stderr, "  Str_Comp:          %s\n",
+                                Next_Ptr_Glob->variant.var_1.Str_Comp);
+  do_fprintf (stderr, "        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  do_fprintf (stderr, "Int_1_Loc:           %d\n", Int_1_Loc);
+  do_fprintf (stderr, "        should be:   %d\n", 5);
+  do_fprintf (stderr, "Int_2_Loc:           %d\n", Int_2_Loc);
+  do_fprintf (stderr, "        should be:   %d\n", 13);
+  do_fprintf (stderr, "Int_3_Loc:           %d\n", Int_3_Loc);
+  do_fprintf (stderr, "        should be:   %d\n", 7);
+  do_fprintf (stderr, "Enum_Loc:            %d\n", Enum_Loc);
+  do_fprintf (stderr, "        should be:   %d\n", 1);
+  do_fprintf (stderr, "Str_1_Loc:           %s\n", Str_1_Loc);
+  do_fprintf (stderr, "        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
+  do_fprintf (stderr, "Str_2_Loc:           %s\n", Str_2_Loc);
+  do_fprintf (stderr, "        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
+  do_fprintf (stderr, "\n");
+
+
+#if HOST_DEBUG
+    Microseconds = (float) User_Time * Mic_secs_Per_Second 
+                        / ((float) HZ * ((float) Number_Of_Runs));
+    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+                        / (float) User_Time;
+
+    do_fprintf (stdout, "Microseconds for one run through Dhrystone: ");
+    do_fprintf (stdout, "%10.1f \n", Microseconds);
+    do_fprintf (stdout, "Dhrystones per Second:                      ");
+    do_fprintf (stdout, "%10.0f \n", Dhrystones_Per_Second);
+    do_fprintf (stdout, "\n");
+#endif
+
+  finishTest(1);
+}
+
+
+void Proc_1(Rec_Pointer Ptr_Val_Par)
+/******************/
+    /* executed once */
+{
+  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;  
+                                        /* == Ptr_Glob_Next */
+  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+  /* corresponds to "rename" in Ada, "with" in Pascal           */
+  
+  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 
+  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+  Next_Record->variant.var_1.Int_Comp 
+        = Ptr_Val_Par->variant.var_1.Int_Comp;
+  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+  Proc_3 (&Next_Record->Ptr_Comp);
+    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 
+                        == Ptr_Glob->Ptr_Comp */
+  if (Next_Record->Discr == Ident_1)
+    /* then, executed */
+  {
+    Next_Record->variant.var_1.Int_Comp = 6;
+    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 
+           &Next_Record->variant.var_1.Enum_Comp);
+    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 
+           &Next_Record->variant.var_1.Int_Comp);
+  }
+  else /* not executed */
+    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2(int* Int_Par_Ref)
+/******************/
+    /* executed once */
+    /* *Int_Par_Ref == 1, becomes 4 */
+{
+  One_Fifty  Int_Loc;  
+  Enumeration   Enum_Loc;
+
+  Int_Loc = *Int_Par_Ref + 10;
+  do /* executed once */
+    if (Ch_1_Glob == 'A')
+      /* then, executed */
+    {
+      Int_Loc -= 1;
+      *Int_Par_Ref = Int_Loc - Int_Glob;
+      Enum_Loc = Ident_1;
+    } /* if */
+  while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3(Rec_Pointer* Ptr_Ref_Par)
+/******************/
+    /* executed once */
+    /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+  if (Ptr_Glob != Null)
+    /* then, executed */
+    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4()
+/*******/
+    /* executed once */
+{
+  Boolean Bool_Loc;
+
+  Bool_Loc = Ch_1_Glob == 'A';
+  Bool_Glob = Bool_Loc | Bool_Glob;
+  Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+
+void Proc_5()
+/*******/
+    /* executed once */
+{
+  Ch_1_Glob = 'A';
+  Bool_Glob = false;
+} /* Proc_5 */
diff --git a/benchmarks/median/bmark.mk b/benchmarks/median/bmark.mk
new file mode 100644 (file)
index 0000000..31c853a
--- /dev/null
@@ -0,0 +1,30 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+median_c_src = \
+       median_main.c \
+       median.c \
+
+median_riscv_src = \
+       crt.S \
+
+median_c_objs     = $(patsubst %.c, %.o, $(median_c_src))
+median_riscv_objs = $(patsubst %.S, %.o, $(median_riscv_src))
+
+median_host_bin = median.host
+$(median_host_bin): $(median_c_src)
+       $(HOST_COMP) $^ -o $(median_host_bin)
+
+median_riscv_bin = median.riscv
+$(median_riscv_bin): $(median_c_objs) $(median_riscv_objs)
+       $(RISCV_LINK) $(median_c_objs) $(median_riscv_objs) -o $(median_riscv_bin)
+
+junk += $(median_c_objs) $(median_riscv_objs) \
+        $(median_host_bin) $(median_riscv_bin)
diff --git a/benchmarks/median/dataset1.h b/benchmarks/median/dataset1.h
new file mode 100644 (file)
index 0000000..a7bc568
--- /dev/null
@@ -0,0 +1,51 @@
+
+#define DATA_SIZE 400
+
+int input_data[DATA_SIZE] =
+{
+   41, 454, 833, 335, 564,   1, 187, 989, 749, 365, 350, 572, 132,  64, 949, 153, 584, 216, 805, 140,
+  621, 210,   6, 572, 931, 339, 890, 593, 392, 898, 694, 228, 961,  12, 110, 883, 116, 750, 296, 646,
+  426, 500, 314, 436, 659, 701, 774, 812, 319, 981, 678, 150, 875, 696, 376, 564, 474, 272, 938, 258,
+  539, 647, 569, 509, 203,  88, 280, 703, 759, 669, 606, 375, 511, 551, 657, 936, 195, 592,  81, 569,
+  267, 952, 229, 800, 337, 584, 944, 643, 902, 368, 241, 489, 913, 328, 826, 313, 933, 592, 985, 388,
+  195, 543, 960, 649, 566, 979, 350, 997, 649, 814, 657,  79, 181, 208, 111, 998, 859, 629,  65, 847,
+  288, 704, 349, 997, 141, 253, 905, 715, 886, 430, 264, 415, 576, 538, 979, 700, 761,   4, 241, 494,
+  478, 100, 499, 864, 403, 693, 222, 416, 444, 296, 721, 285, 676, 620, 317,  78, 224, 351, 937, 540,
+  288, 646, 119, 169, 615, 527, 606, 289, 389, 796, 351, 801, 455, 720, 278, 758, 367, 745, 358,  92,
+  584, 989,  62, 271, 985, 853, 403, 788, 346, 531, 517, 222, 559, 461, 908, 241, 775, 358, 255, 332,
+  778, 684, 598, 740, 143, 446,  33, 311, 125, 743, 941, 557, 933, 479, 799, 557, 553, 925, 431, 796,
+  648, 357, 952, 891, 287, 666,  19, 514,  49, 557,  86, 870,  95, 853, 441, 440, 587,  61, 614, 678,
+  382, 396, 280,   9, 808,  17, 971, 170, 819, 291, 344, 380, 450, 536, 512, 185, 965, 917, 347, 539,
+  808, 983, 882, 887, 537,  54, 946, 612, 701, 951, 356, 479, 567, 151, 891,   7,  22, 641, 568, 335,
+  665, 730, 423,  95, 434, 728, 158, 280,   2, 395,  84, 688, 247, 911,  49, 476, 435, 815, 792, 729,
+  869, 265, 486, 127, 414, 236, 369, 214, 548, 180, 518,   6, 888, 503, 682, 596, 284, 173, 264, 643,
+  499, 346, 290, 599, 897,  68, 215, 849, 731, 658, 688, 619, 251, 121, 786, 131, 555, 828, 302, 667,
+  528, 433, 544, 487, 322, 753, 947, 125, 287, 626, 824,  14, 304,  10, 788, 403, 733, 106, 959, 703,
+  366, 818, 722, 964, 294, 406, 975, 874, 653, 856, 748,  86,  91,  60, 378, 660, 105, 667, 102, 153,
+  381, 121, 651,  98, 825, 412, 840, 236, 356,  12, 148, 423,  54, 965, 140, 216, 955, 621, 343, 361
+};
+
+int verify_data[DATA_SIZE] =
+{
+    0, 454, 454, 564, 335, 187, 187, 749, 749, 365, 365, 350, 132, 132, 153, 584, 216, 584, 216, 621,
+  210, 210, 210, 572, 572, 890, 593, 593, 593, 694, 694, 694, 228, 110, 110, 116, 750, 296, 646, 426,
+  500, 426, 436, 436, 659, 701, 774, 774, 812, 678, 678, 678, 696, 696, 564, 474, 474, 474, 272, 539,
+  539, 569, 569, 509, 203, 203, 280, 703, 703, 669, 606, 511, 511, 551, 657, 657, 592, 195, 569, 267,
+  569, 267, 800, 337, 584, 584, 643, 902, 643, 368, 368, 489, 489, 826, 328, 826, 592, 933, 592, 388,
+  388, 543, 649, 649, 649, 566, 979, 649, 814, 657, 657, 181, 181, 181, 208, 859, 859, 629, 629, 288,
+  704, 349, 704, 349, 253, 253, 715, 886, 715, 430, 415, 415, 538, 576, 700, 761, 700, 241, 241, 478,
+  478, 478, 499, 499, 693, 403, 416, 416, 416, 444, 296, 676, 620, 620, 317, 224, 224, 351, 540, 540,
+  540, 288, 169, 169, 527, 606, 527, 389, 389, 389, 796, 455, 720, 455, 720, 367, 745, 367, 358, 358,
+  584, 584, 271, 271, 853, 853, 788, 403, 531, 517, 517, 517, 461, 559, 461, 775, 358, 358, 332, 332,
+  684, 684, 684, 598, 446, 143, 311, 125, 311, 743, 743, 933, 557, 799, 557, 557, 557, 553, 796, 648,
+  648, 648, 891, 891, 666, 287, 514,  49, 514,  86, 557,  95, 853, 441, 441, 441, 440, 587, 614, 614,
+  396, 382, 280, 280,  17, 808, 170, 819, 291, 344, 344, 380, 450, 512, 512, 512, 917, 917, 539, 539,
+  808, 882, 887, 882, 537, 537, 612, 701, 701, 701, 479, 479, 479, 567, 151,  22,  22, 568, 568, 568,
+  665, 665, 423, 423, 434, 434, 280, 158, 280,  84, 395, 247, 688, 247, 476, 435, 476, 792, 792, 792,
+  729, 486, 265, 414, 236, 369, 236, 369, 214, 518, 180, 518, 503, 682, 596, 596, 284, 264, 264, 499,
+  499, 346, 346, 599, 599, 215, 215, 731, 731, 688, 658, 619, 251, 251, 131, 555, 555, 555, 667, 528,
+  528, 528, 487, 487, 487, 753, 753, 287, 287, 626, 626, 304,  14, 304, 403, 733, 403, 733, 703, 703,
+  703, 722, 818, 722, 406, 406, 874, 874, 856, 748, 748,  91,  86,  91, 378, 378, 660, 105, 153, 153,
+  153, 381, 121, 651, 412, 825, 412, 356, 236, 148, 148, 148, 423, 140, 216, 216, 621, 621, 361,   0
+};
+
diff --git a/benchmarks/median/median.c b/benchmarks/median/median.c
new file mode 100644 (file)
index 0000000..3c509cc
--- /dev/null
@@ -0,0 +1,40 @@
+//**************************************************************************
+// Median filter (c version)
+//--------------------------------------------------------------------------
+
+void median( int n, int input[], int results[] )
+{
+  int A, B, C, i;
+
+  // Zero the ends
+  results[0]   = 0;
+  results[n-1] = 0;
+
+  // Do the filter
+  for ( i = 1; i < (n-1); i++ ) {
+
+    A = input[i-1];
+    B = input[i];
+    C = input[i+1];
+
+    if ( A < B ) {
+      if ( B < C )
+        results[i] = B;
+      else if ( C < A )
+        results[i] = A;
+      else
+        results[i] = C;
+    }
+
+    else {
+      if ( A < C )
+        results[i] = A;
+      else if ( C < B )
+        results[i] = B;
+      else
+        results[i] = C;
+    }
+
+  }
+
+}
diff --git a/benchmarks/median/median.h b/benchmarks/median/median.h
new file mode 100644 (file)
index 0000000..b8b9a94
--- /dev/null
@@ -0,0 +1,9 @@
+//**************************************************************************
+// Median filters
+//--------------------------------------------------------------------------
+
+// Simple C version
+void median( int n, int input[], int results[] );
+
+// Simple assembly version
+void median_asm( int n, int input[], int results[] );
diff --git a/benchmarks/median/median_gendata.pl b/benchmarks/median/median_gendata.pl
new file mode 100755 (executable)
index 0000000..373904e
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# median_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : May 9, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the median benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: median_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [750]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 750;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "int ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3d",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    push( @values, int(rand(999)) );
+  }
+
+  my @median;
+  $median[0] = 0;
+  $median[$opts{"size"}-1] = 0;
+  for ( my $i = 1; $i < $opts{"size"}-1; $i++ ) {
+    my @tempList = ( $values[$i-1], $values[$i], $values[$i+1] );
+    my @sorted = sort { $a <=> $b } @tempList;
+    $median[$i] = $sorted[1];
+  }
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input_data", \@values );
+  printArray( "verify_data", \@median );
+
+}
+
+main();
+
diff --git a/benchmarks/median/median_main.c b/benchmarks/median/median_main.c
new file mode 100644 (file)
index 0000000..6decd3d
--- /dev/null
@@ -0,0 +1,131 @@
+//**************************************************************************
+// Median filter bencmark
+//--------------------------------------------------------------------------
+//
+// This benchmark performs a 1D three element median filter. The
+// input data (and reference data) should be generated using the
+// median_gendata.pl perl script and dumped to a file named
+// dataset1.h You should not change anything except the
+// HOST_DEBUG and PREALLOCATE macros for your timing run.
+
+#include "median.h"
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, int test[], int correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, int arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %3d ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  int results_data[DATA_SIZE];
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input",  DATA_SIZE, input_data  );
+  printArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+  // If needed we preallocate everything in the caches
+
+#if ( !HOST_DEBUG && PREALLOCATE )
+  median( DATA_SIZE, input_data, results_data );
+#endif
+
+  // Do the filter
+
+#if HOST_DEBUG
+  median( DATA_SIZE, input_data, results_data );
+#else
+  setStats(1);
+  median( DATA_SIZE, input_data, results_data );
+  setStats(0);
+#endif
+
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", DATA_SIZE, results_data );
+#endif
+
+  // Check the results
+
+  finishTest(verify( DATA_SIZE, results_data, verify_data ));
+
+}
diff --git a/benchmarks/mt-matmul/bmark.mk b/benchmarks/mt-matmul/bmark.mk
new file mode 100644 (file)
index 0000000..67d6af3
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+mt_matmul_c_src = \
+       mt-matmul.c \
+
+mt_matmul_riscv_src = \
+       crt-mt.S \
+
+mt_matmul_c_objs     = $(patsubst %.c, %.o, $(mt_matmul_c_src))
+mt_matmul_riscv_objs = $(patsubst %.S, %.o, $(mt_matmul_riscv_src))
+
+mt_matmul_host_bin = mt-matmul.host
+$(mt_matmul_host_bin) : $(mt_matmul_c_src)
+       $(HOST_COMP) $^ -o $(mt_matmul_host_bin)
+
+mt_matmul_riscv_bin = mt-matmul.riscv
+$(mt_matmul_riscv_bin) : $(mt_matmul_c_objs) $(mt_matmul_riscv_objs)
+       $(RISCV_LINK_MT) $(RISCV_LINK_SYSCALL) $(mt_matmul_c_objs) $(mt_matmul_riscv_objs) -o $(mt_matmul_riscv_bin)
+
+junk += $(mt_matmul_c_objs) $(mt_matmul_riscv_objs) \
+        $(mt_matmul_host_bin) $(mt_matmul_riscv_bin)
diff --git a/benchmarks/mt-matmul/dataset.h b/benchmarks/mt-matmul/dataset.h
new file mode 100644 (file)
index 0000000..dde3ee4
--- /dev/null
@@ -0,0 +1,174 @@
+
+#define ARRAY_SIZE 1024 
+
+
+#define DIM_SIZE 32 
+
+static data_t input1_data[ARRAY_SIZE] = 
+{
+    0,   3,   2,   0,   3,   1,   0,   3,   2,   3,   2,   0,   3,   3,   1,   2,   3,   0,   0,   1, 
+    1,   1,   2,   3,   1,   2,   3,   1,   1,   3,   2,   2,   0,   1,   3,   2,   2,   2,   0,   0, 
+    1,   0,   1,   3,   3,   0,   3,   3,   3,   3,   0,   3,   2,   1,   2,   2,   0,   0,   3,   0, 
+    1,   1,   0,   3,   3,   1,   2,   3,   3,   0,   1,   2,   1,   0,   1,   2,   2,   1,   0,   3, 
+    1,   0,   2,   2,   1,   1,   1,   1,   1,   1,   2,   0,   3,   1,   1,   2,   2,   3,   3,   1, 
+    3,   2,   0,   0,   0,   3,   3,   3,   2,   1,   2,   3,   1,   0,   0,   0,   0,   1,   2,   2, 
+    1,   1,   3,   3,   3,   1,   1,   2,   3,   1,   3,   3,   2,   3,   2,   1,   2,   3,   0,   2, 
+    2,   1,   1,   0,   0,   0,   0,   0,   1,   3,   3,   1,   1,   1,   2,   2,   3,   2,   1,   1, 
+    1,   1,   3,   0,   2,   2,   1,   3,   2,   1,   2,   2,   1,   3,   1,   3,   1,   3,   2,   3, 
+    1,   2,   1,   3,   2,   2,   0,   1,   0,   0,   1,   2,   3,   3,   1,   0,   0,   0,   3,   1, 
+    2,   3,   2,   3,   2,   0,   0,   0,   0,   0,   3,   1,   3,   0,   0,   0,   3,   1,   1,   1, 
+    1,   2,   1,   2,   3,   2,   0,   0,   2,   2,   3,   0,   3,   0,   0,   3,   0,   3,   1,   3, 
+    3,   1,   1,   1,   2,   2,   1,   3,   0,   3,   3,   1,   0,   0,   3,   2,   1,   3,   3,   3, 
+    1,   0,   1,   1,   2,   1,   0,   1,   1,   2,   2,   3,   1,   2,   2,   2,   0,   1,   3,   3, 
+    3,   2,   2,   1,   0,   1,   2,   0,   1,   1,   1,   1,   2,   3,   2,   2,   3,   3,   0,   0, 
+    2,   0,   0,   0,   3,   0,   1,   0,   3,   0,   0,   0,   3,   0,   0,   2,   0,   2,   0,   0, 
+    2,   3,   2,   0,   0,   3,   3,   2,   1,   1,   0,   2,   0,   0,   3,   3,   2,   3,   3,   0, 
+    1,   0,   2,   2,   0,   3,   3,   1,   1,   0,   2,   3,   2,   1,   1,   0,   1,   2,   1,   2, 
+    2,   0,   0,   1,   0,   1,   1,   0,   1,   0,   2,   3,   3,   2,   0,   0,   1,   3,   0,   3, 
+    3,   0,   0,   0,   0,   3,   3,   1,   0,   0,   3,   3,   2,   1,   2,   1,   3,   3,   0,   1, 
+    3,   0,   2,   3,   1,   3,   3,   3,   3,   3,   0,   1,   1,   3,   0,   2,   2,   3,   1,   2, 
+    2,   2,   1,   3,   3,   0,   3,   0,   0,   2,   0,   2,   3,   0,   1,   3,   2,   2,   0,   0, 
+    2,   3,   0,   2,   2,   2,   3,   1,   0,   3,   3,   3,   3,   1,   0,   3,   3,   2,   0,   3, 
+    2,   0,   3,   0,   2,   0,   0,   2,   2,   1,   0,   2,   3,   1,   1,   1,   1,   2,   3,   3, 
+    3,   0,   0,   3,   3,   3,   2,   3,   3,   1,   2,   2,   3,   1,   2,   1,   1,   3,   0,   1, 
+    2,   0,   2,   0,   0,   1,   3,   2,   0,   1,   3,   2,   3,   3,   0,   0,   0,   1,   0,   3, 
+    3,   2,   2,   2,   1,   1,   2,   2,   1,   3,   2,   0,   1,   3,   2,   0,   2,   1,   3,   0, 
+    0,   0,   1,   3,   3,   2,   2,   2,   3,   1,   0,   0,   1,   1,   2,   1,   3,   1,   1,   2, 
+    2,   3,   2,   3,   0,   2,   3,   3,   0,   3,   0,   0,   1,   0,   0,   0,   1,   3,   1,   1, 
+    2,   3,   2,   1,   1,   2,   2,   2,   3,   0,   1,   1,   2,   1,   2,   0,   2,   3,   1,   3, 
+    0,   1,   1,   3,   0,   2,   3,   0,   1,   2,   3,   2,   0,   0,   3,   3,   2,   1,   1,   2, 
+    3,   0,   1,   1,   1,   1,   2,   0,   1,   2,   0,   1,   1,   1,   0,   1,   3,   2,   3,   1, 
+    0,   2,   1,   2,   1,   3,   3,   1,   0,   2,   2,   3,   1,   3,   1,   3,   0,   1,   0,   3, 
+    0,   3,   2,   0,   3,   3,   3,   0,   3,   2,   2,   2,   1,   3,   0,   0,   1,   1,   3,   0, 
+    1,   2,   1,   0,   0,   0,   3,   2,   2,   0,   0,   2,   1,   3,   0,   0,   3,   0,   0,   2, 
+    1,   1,   2,   2,   1,   3,   2,   2,   1,   1,   2,   1,   3,   2,   1,   1,   3,   0,   1,   3, 
+    3,   2,   2,   1,   0,   3,   2,   2,   2,   3,   0,   1,   3,   3,   2,   3,   0,   3,   2,   3, 
+    1,   1,   0,   0,   0,   2,   3,   0,   3,   0,   1,   1,   3,   1,   3,   2,   1,   1,   2,   1, 
+    3,   2,   0,   2,   1,   0,   2,   3,   2,   3,   2,   1,   2,   3,   0,   0,   1,   1,   0,   0, 
+    2,   1,   0,   1,   2,   2,   2,   2,   0,   3,   3,   1,   0,   0,   0,   0,   3,   1,   1,   0, 
+    0,   0,   0,   1,   2,   2,   1,   3,   0,   2,   3,   2,   3,   2,   2,   1,   2,   2,   3,   3, 
+    1,   3,   0,   2,   2,   3,   3,   1,   2,   2,   2,   3,   1,   1,   1,   0,   0,   0,   3,   0, 
+    1,   0,   3,   1,   1,   3,   0,   1,   2,   2,   0,   0,   3,   3,   3,   3,   2,   1,   0,   0, 
+    1,   0,   2,   0,   1,   1,   0,   0,   3,   3,   2,   1,   1,   1,   0,   1,   1,   2,   2,   1, 
+    1,   2,   0,   3,   1,   3,   1,   0,   3,   0,   3,   1,   1,   1,   0,   2,   0,   3,   1,   0, 
+    1,   0,   2,   0,   2,   3,   3,   3,   1,   2,   3,   2,   2,   0,   1,   1,   0,   3,   3,   1, 
+    3,   3,   2,   0,   2,   0,   2,   2,   3,   3,   3,   0,   2,   3,   3,   1,   3,   2,   2,   2, 
+    0,   2,   3,   0,   2,   0,   3,   2,   2,   1,   1,   0,   2,   2,   2,   0,   2,   2,   0,   1, 
+    3,   2,   1,   3,   2,   2,   0,   3,   3,   1,   2,   2,   0,   0,   3,   2,   1,   2,   2,   1, 
+    3,   1,   2,   0,   0,   1,   1,   2,   1,   3,   2,   2,   3,   0,   2,   1,   3,   2,   1,   3, 
+    2,   3,   3,   1,   2,   1,   2,   2,   0,   0,   0,   3,   0,   2,   3,   1,   0,   0,   2,   3, 
+    3,   2,   2,   1
+};
+
+static data_t input2_data[ARRAY_SIZE] = 
+{
+    1,   1,   0,   3,   1,   2,   0,   0,   0,   0,   0,   2,   1,   2,   3,   0,   0,   3,   3,   2, 
+    2,   1,   2,   3,   3,   0,   2,   2,   1,   1,   2,   2,   0,   2,   2,   1,   2,   3,   2,   2, 
+    3,   3,   2,   2,   1,   1,   1,   1,   2,   1,   2,   2,   3,   3,   3,   0,   0,   3,   2,   3, 
+    2,   3,   1,   2,   1,   1,   2,   2,   0,   1,   0,   3,   2,   1,   1,   1,   2,   0,   1,   2, 
+    2,   0,   2,   1,   3,   3,   2,   3,   2,   0,   3,   1,   3,   3,   2,   0,   1,   0,   1,   1, 
+    2,   2,   1,   1,   2,   2,   1,   2,   3,   3,   1,   3,   2,   2,   2,   3,   3,   1,   0,   2, 
+    1,   0,   0,   0,   1,   1,   2,   0,   3,   2,   3,   3,   0,   2,   3,   1,   0,   0,   2,   1, 
+    2,   0,   2,   1,   1,   2,   3,   1,   3,   2,   1,   0,   0,   0,   0,   0,   2,   2,   0,   2, 
+    1,   2,   0,   3,   2,   2,   0,   0,   3,   2,   1,   1,   3,   0,   2,   0,   0,   1,   0,   2, 
+    3,   3,   1,   3,   3,   0,   0,   2,   2,   0,   0,   0,   1,   0,   0,   1,   3,   0,   2,   1, 
+    3,   2,   2,   1,   3,   2,   0,   1,   2,   2,   3,   2,   1,   1,   1,   1,   3,   0,   1,   3, 
+    2,   2,   3,   1,   1,   2,   0,   2,   1,   1,   2,   3,   1,   0,   1,   0,   1,   1,   0,   0, 
+    2,   0,   3,   0,   3,   0,   3,   2,   2,   3,   3,   2,   1,   0,   2,   2,   1,   1,   0,   3, 
+    3,   2,   2,   0,   0,   3,   0,   1,   0,   0,   1,   2,   0,   1,   3,   0,   1,   2,   2,   0, 
+    0,   3,   0,   3,   0,   1,   1,   2,   0,   0,   0,   3,   0,   0,   2,   1,   1,   1,   0,   2, 
+    1,   3,   1,   2,   0,   3,   0,   3,   1,   3,   0,   0,   2,   2,   2,   2,   3,   3,   2,   1, 
+    2,   2,   1,   1,   2,   2,   2,   2,   0,   3,   0,   0,   2,   0,   1,   2,   0,   3,   2,   3, 
+    2,   0,   2,   1,   2,   1,   0,   2,   1,   1,   3,   2,   2,   3,   1,   0,   3,   3,   1,   0, 
+    3,   2,   2,   0,   0,   3,   0,   0,   2,   0,   3,   2,   3,   1,   1,   0,   0,   2,   3,   0, 
+    0,   1,   1,   1,   2,   1,   3,   2,   1,   3,   0,   1,   3,   3,   1,   1,   1,   1,   1,   1, 
+    0,   0,   2,   3,   2,   2,   2,   3,   2,   3,   1,   2,   3,   2,   2,   2,   0,   1,   3,   0, 
+    1,   1,   0,   1,   0,   1,   1,   3,   3,   1,   2,   2,   3,   2,   0,   2,   2,   0,   1,   3, 
+    0,   1,   3,   2,   1,   3,   3,   2,   0,   1,   3,   2,   0,   2,   1,   1,   0,   3,   0,   1, 
+    1,   1,   1,   1,   3,   0,   0,   1,   0,   2,   3,   1,   3,   0,   2,   1,   3,   0,   3,   0, 
+    3,   2,   2,   0,   0,   2,   1,   3,   3,   2,   3,   2,   2,   1,   2,   2,   3,   0,   3,   2, 
+    2,   0,   3,   2,   3,   2,   0,   0,   1,   2,   0,   0,   2,   0,   0,   3,   3,   2,   0,   0, 
+    3,   3,   0,   2,   3,   1,   0,   1,   0,   2,   1,   0,   2,   1,   0,   1,   0,   3,   0,   2, 
+    2,   3,   0,   0,   2,   1,   0,   1,   0,   0,   0,   2,   2,   3,   2,   0,   3,   3,   2,   1, 
+    0,   0,   3,   1,   2,   3,   3,   1,   0,   3,   1,   1,   0,   3,   3,   3,   2,   2,   2,   0, 
+    1,   2,   0,   3,   0,   1,   0,   1,   1,   0,   1,   2,   0,   3,   2,   0,   1,   2,   2,   0, 
+    2,   0,   0,   1,   0,   3,   0,   3,   2,   1,   1,   1,   1,   3,   2,   1,   1,   1,   1,   0, 
+    2,   1,   1,   3,   2,   0,   2,   1,   1,   0,   2,   2,   1,   3,   0,   2,   1,   0,   1,   2, 
+    0,   1,   3,   2,   3,   2,   1,   0,   2,   0,   2,   2,   3,   1,   1,   3,   2,   3,   2,   2, 
+    0,   2,   0,   0,   0,   3,   2,   0,   2,   2,   3,   3,   3,   2,   1,   2,   0,   0,   3,   0, 
+    2,   0,   3,   2,   2,   3,   0,   3,   2,   1,   2,   2,   1,   2,   0,   0,   3,   1,   2,   0, 
+    2,   3,   2,   2,   1,   1,   1,   3,   3,   3,   3,   3,   1,   3,   0,   1,   3,   2,   2,   1, 
+    0,   1,   1,   2,   1,   2,   3,   1,   2,   2,   1,   2,   1,   1,   0,   3,   3,   1,   1,   3, 
+    2,   0,   0,   1,   2,   0,   1,   3,   1,   0,   0,   2,   2,   3,   3,   0,   2,   3,   2,   1, 
+    1,   3,   0,   2,   2,   3,   3,   1,   2,   3,   3,   3,   1,   3,   0,   3,   1,   1,   2,   2, 
+    2,   1,   0,   3,   2,   3,   0,   2,   3,   2,   3,   1,   2,   3,   3,   1,   2,   1,   0,   0, 
+    0,   3,   3,   3,   3,   0,   3,   3,   3,   3,   2,   1,   0,   3,   0,   3,   2,   3,   1,   0, 
+    0,   1,   3,   1,   0,   2,   2,   3,   1,   0,   2,   1,   1,   3,   1,   1,   3,   1,   2,   1, 
+    0,   0,   3,   2,   1,   1,   1,   1,   3,   2,   1,   3,   3,   1,   0,   3,   1,   1,   2,   0, 
+    0,   0,   2,   3,   3,   2,   2,   3,   0,   2,   3,   1,   3,   3,   0,   2,   1,   2,   2,   2, 
+    1,   0,   1,   3,   2,   3,   1,   1,   2,   1,   1,   0,   0,   2,   3,   2,   1,   0,   3,   1, 
+    3,   0,   1,   1,   2,   2,   1,   3,   3,   1,   1,   0,   0,   3,   3,   0,   0,   0,   0,   0, 
+    3,   1,   3,   0,   0,   0,   3,   3,   2,   1,   3,   0,   1,   3,   1,   1,   1,   0,   1,   0, 
+    1,   2,   2,   2,   3,   3,   0,   2,   3,   2,   1,   3,   3,   1,   1,   3,   0,   3,   3,   2, 
+    1,   1,   2,   0,   3,   0,   1,   2,   1,   1,   0,   0,   1,   2,   2,   0,   3,   1,   1,   1, 
+    3,   3,   3,   1,   0,   3,   3,   2,   2,   2,   1,   2,   0,   1,   1,   3,   0,   3,   1,   0, 
+    2,   2,   0,   1,   2,   3,   2,   1,   2,   0,   3,   2,   1,   3,   0,   1,   2,   0,   3,   0, 
+    1,   1,   2,   1
+};
+
+static data_t verify_data[ARRAY_SIZE] = 
+{
+   72,  75,  88, 101,  80,  88,  73,  75,  80,  81,  58,  75,  86,  65,  60,  80,  84,  83,  87,  83, 
+  108,  93,  85,  76,  72,  98,  79,  86,  80,  96,  91,  85,  72,  64,  70,  83,  68,  92,  51,  54, 
+   85,  85,  60,  58,  90,  64,  55,  69,  72,  48,  94,  77,  91,  83,  70,  69,  67,  77,  59,  50, 
+   67,  74,  77,  67,  67,  62,  72,  71,  68,  79,  54,  61,  67,  61,  55,  62,  78,  60,  53,  64, 
+   67,  69,  99,  68,  88,  60,  66,  63,  70,  62,  65,  50,  53,  66,  70,  72,  75,  78,  85,  95, 
+   71,  89,  70,  68,  86,  88,  58,  77,  84,  70,  65,  68,  73,  75,  91,  96, 105,  92,  76,  68, 
+   86,  69,  80,  59,  73,  83,  88,  75,  64,  63,  71,  99,  77,  77,  69,  55,  80,  73,  54,  73, 
+   87,  78,  60,  69,  65,  78,  86,  89,  95,  92,  63,  69,  89,  61,  80,  65,  70,  77,  89,  77, 
+   79,  79,  73,  92,  64,  81,  60,  78,  81,  80,  61,  63,  89,  65,  56,  83,  77,  65, 102,  70, 
+   98,  86,  96,  68,  72,  89,  73,  73,  70,  89,  84,  76,  48,  61,  63,  70,  70,  79,  50,  53, 
+   64,  63,  43,  51,  59,  62,  43,  63,  55,  77,  79,  74,  75,  74,  64,  44,  65,  69,  72,  66, 
+   54,  71,  74,  72,  69,  76,  68,  89,  94,  75,  65,  53,  85,  79,  65,  74,  82,  73,  58,  70, 
+   84,  77,  99,  72,  92,  84,  78,  62,  59,  83,  71,  74,  63,  85,  80,  78,  71,  72,  79,  83, 
+   73,  82,  60,  85,  76,  82,  60,  70,  82,  68,  54,  85,  84,  70,  86,  74, 100,  88,  98,  68, 
+   67,  87,  69,  73,  68,  88,  76,  71,  47,  43,  47,  80,  54,  65,  40,  37,  59,  53,  33,  48, 
+   62,  40,  36,  55,  36,  62,  53,  57,  70,  69,  45,  43,  53,  61,  42,  57,  56,  63,  51,  47, 
+   59,  75,  64,  89,  83,  75,  59,  75,  91,  92,  58,  64,  83,  74,  58,  60,  76,  66,  97,  69, 
+   90,  95,  92,  64,  78,  75,  77,  73,  65,  78,  82,  75,  47,  54,  59,  71,  59,  56,  53,  42, 
+   60,  55,  40,  51,  60,  46,  36,  59,  46,  57,  67,  43,  51,  53,  53,  38,  54,  56,  55,  48, 
+   41,  46,  63,  63,  80,  77,  89, 102,  89,  98,  74,  86,  98,  93,  63,  76,  98,  77,  48, 101, 
+   86,  88, 100,  82, 102,  90,  95,  75,  86, 103,  83,  98,  80, 104,  98,  86,  71,  74,  80,  90, 
+   86,  87,  73,  70,  81,  83,  55,  66,  90,  66,  58,  84,  77,  84,  93,  72,  99,  75,  85,  65, 
+   70,  89,  71,  82,  64,  79,  82,  80,  67,  73,  86, 101,  78,  97,  66,  64,  84,  80,  55,  64, 
+   79,  73,  51,  79,  89,  68,  94,  77, 109, 102,  82,  61,  66,  93,  88,  70,  82,  82,  85,  69, 
+   69,  72,  66,  97,  85,  90,  70,  59,  76,  89,  53,  56,  90,  79,  71,  64,  70,  67, 100,  92, 
+  106,  89,  83,  78,  73,  80,  70,  72,  65,  70,  92,  88,  57,  76,  55,  85,  66,  80,  61,  63, 
+   63,  78,  54,  58,  71,  73,  54,  63,  63,  62,  89,  76,  86,  81,  83,  54,  70,  81,  78,  64, 
+   56,  72,  74,  81,  75,  63,  68,  89,  65,  77,  58,  68,  75,  83,  52,  62,  82,  63,  55,  75, 
+   51,  70,  95,  66,  83,  77,  86,  61,  64,  77,  48,  70,  66,  82,  72,  75,  79,  71,  72,  89, 
+   78,  78,  66,  59,  91,  80,  55,  64,  79,  68,  54,  71,  67,  75,  87,  84, 100, 101,  76,  58, 
+   74,  82,  61,  74,  75,  97,  85,  79,  61,  55,  69,  68,  72,  65,  52,  64,  80,  73,  48,  54, 
+   71,  66,  42,  61,  66,  63,  92,  64,  85,  77,  73,  54,  74,  73,  76,  66,  62,  79,  85,  70, 
+   71,  84,  87,  81,  88,  86,  77,  77,  93,  88,  78,  71, 101,  89,  58,  84,  95,  81,  89,  97, 
+  104,  79,  83,  76,  90,  81,  91,  74,  70,  76,  91,  80,  51,  48,  56,  69,  47,  63,  54,  42, 
+   63,  63,  42,  52,  66,  56,  39,  59,  61,  52,  59,  63,  62,  68,  57,  35,  67,  58,  56,  52, 
+   61,  63,  60,  47,  85,  75,  89, 106,  88,  95,  74,  82, 107, 107,  64,  78,  98,  90,  62,  91, 
+   79,  87, 111,  84, 104, 106,  96,  68,  94,  99,  81,  89,  79, 105,  95,  86,  65,  63,  77,  89, 
+   66,  88,  56,  73,  82,  92,  41,  62,  85,  66,  50,  81,  57,  71,  77,  78,  86,  89,  77,  53, 
+   67,  78,  61,  63,  72,  82,  69,  66,  59,  46,  55,  70,  56,  64,  45,  50,  65,  64,  42,  56, 
+   78,  49,  51,  52,  38,  56,  72,  55,  73,  72,  61,  50,  63,  60,  47,  57,  55,  73,  53,  68, 
+   85,  88,  91,  96,  82,  89,  73,  76,  87,  86,  67,  69,  96,  84,  57,  89,  87,  89,  99,  88, 
+  104,  90,  85,  75,  88,  92,  85,  75,  74,  87, 103,  94,  55,  48,  56,  65,  72,  50,  45,  51, 
+   63,  62,  47,  57,  79,  53,  36,  63,  54,  68,  71,  59,  63,  61,  63,  41,  50,  73,  57,  59, 
+   56,  76,  73,  65,  61,  64,  61,  79,  53,  73,  57,  44,  61,  59,  59,  56,  81,  59,  49,  62, 
+   65,  55,  69,  72,  79,  70,  58,  57,  68,  61,  62,  50,  57,  60,  66,  66,  63,  77,  81,  89, 
+   85,  81,  76,  73,  78,  95,  59,  70,  81,  77,  46,  79,  78,  79,  83,  81,  84,  82,  85,  48, 
+   74,  85,  85,  74,  74,  80,  80,  74,  60,  76,  80,  97,  88,  93,  66,  66,  73,  84,  56,  70, 
+   90,  63,  58,  78,  73,  93,  90,  78,  94,  88,  82,  67,  85,  70,  81,  86,  74,  82,  88,  82, 
+   68,  73,  75,  91,  78,  97,  71,  66,  74,  85,  50,  59,  86,  77,  70,  74,  75,  74,  99,  82, 
+   99,  91,  86,  65,  80,  77,  72,  69,  60,  78,  90,  87,  79,  69,  74,  98,  70,  86,  81,  67, 
+   69,  78,  48,  65,  88,  70,  70,  70,  69,  72,  96,  90,  99,  82,  81,  76,  98,  73,  74,  71, 
+   69,  73,  94,  89
+};
+
diff --git a/benchmarks/mt-matmul/matmul_gendata.pl b/benchmarks/mt-matmul/matmul_gendata.pl
new file mode 100755 (executable)
index 0000000..f21bb46
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# matmul_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the matmul benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: matmul_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "static data_t ".$arrayName."[ARRAY_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3d",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+
+
+#--------------------------------------------------------------------------
+# Matmul
+#--------------------------------------------------------------------------
+
+# http://answers.oreilly.com/topic/418-how-to-multiply-matrices-in-perl/
+
+sub mmult {
+    my ($m1,$m2) = @_;
+    my ($m1rows,$m1cols) = matdim($m1);
+    my ($m2rows,$m2cols) = matdim($m2);
+
+    my $result = [  ];
+    my ($i, $j, $k);
+
+    for $i (range($m1rows)) {
+        for $j (range($m2cols)) {
+            for $k (range($m1cols)) {
+                $result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j];
+            }
+        }
+    }
+    return $result;
+}
+
+sub range { 0 .. ($_[0] - 1) }
+
+
+sub veclen {
+    my $ary_ref = $_[0];
+    my $type = ref $ary_ref;
+    if ($type ne "ARRAY") { die "$type is bad array ref for $ary_ref" }
+    return scalar(@$ary_ref);
+}
+
+sub matdim {
+    my $matrix = $_[0];
+    my $rows = veclen($matrix);
+    my $cols = veclen($matrix->[0]);
+    return ($rows, $cols);
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  # create random input arrays
+  my $mat_values1;
+  my $mat_values2;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
+      $mat_values1->[$i][$j] = int(rand(4));
+      $mat_values2->[$i][$j] = int(rand(4));
+    }
+  }
+
+  # perform matmul
+  my $mat_results = mmult( $mat_values1, $mat_values2 );
+  
+  # translate 2d arrays to 1d-somethings (I don't know how to code in perl - Chris)
+  my @values1;
+  my @values2;
+  my @results;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
+    my $value1 = $mat_values1->[$i][$j];
+    my $value2 = $mat_values2->[$i][$j];
+    my $result = $mat_results->[$i][$j];
+    push( @values1, $value1 );
+    push( @values2, $value2 );
+    push( @results, $result );
+    }
+  }
+
+  print "\n\#define ARRAY_SIZE ".($opts{"size"}*$opts{"size"})." \n\n";
+  print "\n\#define DIM_SIZE ".$opts{"size"}." \n\n";
+   
+  printArray( "input1_data", \@values1 );
+  printArray( "input2_data", \@values2 );
+  printArray( "verify_data", \@results);
+}
+
+main();
+
diff --git a/benchmarks/mt-matmul/mt-matmul.c b/benchmarks/mt-matmul/mt-matmul.c
new file mode 100644 (file)
index 0000000..93f8ea9
--- /dev/null
@@ -0,0 +1,167 @@
+//**************************************************************************
+// Multi-threaded Matrix Multiply benchmark
+//--------------------------------------------------------------------------
+// TA     : Christopher Celio
+// Student: 
+//
+//
+// This benchmark multiplies two 2-D arrays together and writes the results to
+// a third vector. The input data (and reference data) should be generated
+// using the matmul_gendata.pl perl script and dumped to a file named
+// dataset.h. 
+
+
+// print out arrays, etc.
+//#define DEBUG
+
+//--------------------------------------------------------------------------
+// Includes 
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+typedef float data_t;
+#include "dataset.h"
+  
+//--------------------------------------------------------------------------
+// Basic Utilities and Multi-thread Support
+
+__thread unsigned long coreid;
+unsigned long ncores;
+
+#include "util.h"
+   
+#define stringify_1(s) #s
+#define stringify(s) stringify_1(s)
+#define stats(code) do { \
+    unsigned long _c = -rdcycle(), _i = -rdinstret(); \
+    code; \
+    _c += rdcycle(), _i += rdinstret(); \
+    if (coreid == 0) \
+      printf("%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \
+             stringify(code), _c, _c/DIM_SIZE/DIM_SIZE/DIM_SIZE, 10*_c/DIM_SIZE/DIM_SIZE/DIM_SIZE%10, _c/_i, 10*_c/_i%10); \
+  } while(0)
+
+//--------------------------------------------------------------------------
+// Helper functions
+    
+void printArray( char name[], int n, data_t arr[] )
+{
+   int i;
+   if (coreid != 0)
+      return;
+  
+   printf( " %10s :", name );
+   for ( i = 0; i < n; i++ )
+      printf( " %3ld ", (long) arr[i] );
+   printf( "\n" );
+}
+      
+void __attribute__((noinline)) verify(size_t n, const data_t* test, const data_t* correct)
+{
+   if (coreid != 0)
+      return;
+
+   size_t i;
+   for (i = 0; i < n; i++)
+   {
+      if (test[i] != correct[i])
+      {
+         printf("FAILED test[%d]= %3ld, correct[%d]= %3ld\n", 
+            i, (long)test[i], i, (long)correct[i]);
+         exit(-1);
+      }
+   }
+   
+   return;
+}
+//--------------------------------------------------------------------------
+// matmul function
+// single-thread, naive version
+void __attribute__((noinline)) matmul_naive(const int lda,  const data_t A[], const data_t B[], data_t C[] )
+{
+   int i, j, k;
+
+   if (coreid > 0)
+      return;
+  
+   for ( i = 0; i < lda; i++ )
+      for ( j = 0; j < lda; j++ )  
+      {
+         for ( k = 0; k < lda; k++ ) 
+         {
+            C[i + j*lda] += A[j*lda + k] * B[k*lda + i];
+         }
+      }
+
+}
+
+
+void __attribute__((noinline)) matmul(const int lda,  const data_t A[], const data_t B[], data_t C[] )
+{
+   
+   // ***************************** //
+   // **** ADD YOUR CODE HERE ***** //
+   // ***************************** //
+   //
+   // feel free to make a separate function for MI and MSI versions.
+}
+
+//--------------------------------------------------------------------------
+// Main
+//
+// all threads start executing thread_entry(). Use their "coreid" to
+// differentiate between threads (each thread is running on a separate core).
+  
+void thread_entry(int cid, int nc)
+{
+   coreid = cid;
+   ncores = nc;
+
+   // static allocates data in the binary, which is visible to both threads
+   static data_t results_data[ARRAY_SIZE];
+
+
+   // Execute the provided, naive matmul
+   barrier();
+   stats(matmul_naive(DIM_SIZE, input1_data, input2_data, results_data); barrier());
+   
+   // verify
+   verify(ARRAY_SIZE, results_data, verify_data);
+   
+   // clear results from the first trial
+   size_t i;
+   if (coreid == 0) 
+      for (i=0; i < ARRAY_SIZE; i++)
+         results_data[i] = 0;
+   barrier();
+
+   
+   // Execute your faster matmul
+   barrier();
+   stats(matmul(DIM_SIZE, input1_data, input2_data, results_data); barrier());
+#ifdef DEBUG
+   printArray("results:", ARRAY_SIZE, results_data);
+   printArray("verify :", ARRAY_SIZE, verify_data);
+#endif
+   
+   // verify
+   verify(ARRAY_SIZE, results_data, verify_data);
+   barrier();
+
+   exit(0);
+}
+
diff --git a/benchmarks/mt-vvadd/bmark.mk b/benchmarks/mt-vvadd/bmark.mk
new file mode 100644 (file)
index 0000000..0ab2504
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+mt_vvadd_c_src = \
+       mt-vvadd.c \
+
+mt_vvadd_riscv_src = \
+       crt-mt.S \
+
+mt_vvadd_c_objs     = $(patsubst %.c, %.o, $(mt_vvadd_c_src))
+mt_vvadd_riscv_objs = $(patsubst %.S, %.o, $(mt_vvadd_riscv_src))
+
+mt_vvadd_host_bin = mt-vvadd.host
+$(mt_vvadd_host_bin) : $(mt_vvadd_c_src)
+       $(HOST_COMP) $^ -o $(mt_vvadd_host_bin)
+
+mt_vvadd_riscv_bin = mt-vvadd.riscv
+$(mt_vvadd_riscv_bin) : $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs)
+       $(RISCV_LINK_MT) $(RISCV_LINK_SYSCALL) $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs) -o $(mt_vvadd_riscv_bin)
+
+junk += $(mt_vvadd_c_objs) $(mt_vvadd_riscv_objs) \
+        $(mt_vvadd_host_bin) $(mt_vvadd_riscv_bin)
diff --git a/benchmarks/mt-vvadd/dataset.h b/benchmarks/mt-vvadd/dataset.h
new file mode 100644 (file)
index 0000000..ce9f936
--- /dev/null
@@ -0,0 +1,165 @@
+
+#define DATA_SIZE 1000 
+
+static data_t input1_data[DATA_SIZE] = 
+{
+  0.00, 15.00, 10.00, 3.00, 14.00, 6.00, 2.00, 18.00, 11.00, 15.00, 11.00, 0.00, 17.00, 16.00, 7.00, 13.00, 18.00, 2.00, 2.00, 5.00, 
+  8.00, 5.00, 12.00, 14.00, 6.00, 12.00, 16.00, 7.00, 9.00, 17.00, 10.00, 10.00, 3.00, 5.00, 14.00, 11.00, 9.00, 12.00, 3.00, 1.00, 
+  5.00, 4.00, 6.00, 17.00, 17.00, 4.00, 17.00, 15.00, 17.00, 18.00, 3.00, 18.00, 10.00, 6.00, 12.00, 12.00, 3.00, 2.00, 16.00, 1.00, 
+  5.00, 6.00, 2.00, 17.00, 16.00, 5.00, 10.00, 18.00, 14.00, 4.00, 9.00, 9.00, 7.00, 4.00, 8.00, 13.00, 12.00, 6.00, 4.00, 17.00, 
+  5.00, 2.00, 11.00, 11.00, 7.00, 6.00, 8.00, 5.00, 6.00, 6.00, 11.00, 1.00, 18.00, 7.00, 6.00, 9.00, 10.00, 17.00, 14.00, 4.00, 
+  14.00, 11.00, 2.00, 0.00, 2.00, 17.00, 17.00, 15.00, 10.00, 8.00, 12.00, 18.00, 5.00, 0.00, 0.00, 1.00, 1.00, 8.00, 11.00, 11.00, 
+  7.00, 5.00, 15.00, 18.00, 15.00, 6.00, 8.00, 9.00, 18.00, 6.00, 15.00, 16.00, 10.00, 18.00, 13.00, 6.00, 10.00, 16.00, 0.00, 10.00, 
+  12.00, 8.00, 8.00, 3.00, 0.00, 1.00, 4.00, 0.00, 8.00, 15.00, 16.00, 9.00, 7.00, 7.00, 10.00, 9.00, 16.00, 12.00, 5.00, 5.00, 
+  9.00, 5.00, 17.00, 4.00, 13.00, 13.00, 4.00, 14.00, 10.00, 5.00, 10.00, 10.00, 6.00, 18.00, 5.00, 15.00, 5.00, 15.00, 13.00, 18.00, 
+  6.00, 13.00, 5.00, 18.00, 12.00, 14.00, 1.00, 7.00, 2.00, 1.00, 7.00, 12.00, 15.00, 15.00, 6.00, 2.00, 1.00, 2.00, 18.00, 6.00, 
+  10.00, 14.00, 9.00, 15.00, 11.00, 0.00, 3.00, 1.00, 2.00, 2.00, 14.00, 7.00, 18.00, 0.00, 2.00, 2.00, 16.00, 8.00, 4.00, 5.00, 
+  7.00, 11.00, 7.00, 10.00, 14.00, 10.00, 3.00, 0.00, 13.00, 9.00, 14.00, 0.00, 14.00, 1.00, 3.00, 16.00, 2.00, 14.00, 6.00, 17.00, 
+  17.00, 6.00, 9.00, 8.00, 9.00, 12.00, 5.00, 14.00, 2.00, 16.00, 17.00, 5.00, 4.00, 0.00, 14.00, 10.00, 6.00, 15.00, 15.00, 14.00, 
+  5.00, 1.00, 8.00, 8.00, 13.00, 8.00, 0.00, 4.00, 7.00, 9.00, 13.00, 16.00, 9.00, 14.00, 9.00, 13.00, 0.00, 7.00, 16.00, 17.00, 
+  18.00, 10.00, 13.00, 8.00, 4.00, 9.00, 13.00, 0.00, 6.00, 4.00, 6.00, 4.00, 10.00, 14.00, 14.00, 9.00, 15.00, 15.00, 3.00, 3.00, 
+  12.00, 0.00, 3.00, 2.00, 16.00, 1.00, 7.00, 2.00, 16.00, 2.00, 2.00, 0.00, 14.00, 3.00, 3.00, 10.00, 4.00, 10.00, 3.00, 4.00, 
+  13.00, 14.00, 13.00, 0.00, 1.00, 15.00, 16.00, 9.00, 7.00, 9.00, 0.00, 11.00, 1.00, 1.00, 15.00, 17.00, 12.00, 16.00, 15.00, 4.00, 
+  8.00, 2.00, 10.00, 10.00, 0.00, 18.00, 17.00, 7.00, 7.00, 2.00, 10.00, 17.00, 9.00, 7.00, 5.00, 3.00, 8.00, 11.00, 6.00, 9.00, 
+  13.00, 0.00, 3.00, 5.00, 2.00, 5.00, 7.00, 4.00, 9.00, 2.00, 13.00, 17.00, 14.00, 12.00, 1.00, 3.00, 7.00, 17.00, 0.00, 14.00, 
+  16.00, 2.00, 2.00, 1.00, 2.00, 15.00, 16.00, 8.00, 2.00, 4.00, 15.00, 15.00, 10.00, 6.00, 11.00, 9.00, 15.00, 17.00, 3.00, 8.00, 
+  15.00, 3.00, 10.00, 15.00, 8.00, 14.00, 16.00, 15.00, 15.00, 14.00, 1.00, 7.00, 4.00, 18.00, 2.00, 13.00, 11.00, 15.00, 7.00, 10.00, 
+  13.00, 10.00, 7.00, 14.00, 18.00, 4.00, 18.00, 4.00, 3.00, 9.00, 1.00, 13.00, 15.00, 2.00, 5.00, 15.00, 12.00, 10.00, 2.00, 0.00, 
+  10.00, 15.00, 0.00, 11.00, 14.00, 11.00, 14.00, 9.00, 1.00, 18.00, 14.00, 18.00, 15.00, 5.00, 1.00, 15.00, 18.00, 14.00, 3.00, 15.00, 
+  11.00, 2.00, 15.00, 0.00, 13.00, 1.00, 4.00, 14.00, 14.00, 5.00, 2.00, 13.00, 17.00, 8.00, 7.00, 6.00, 5.00, 10.00, 14.00, 14.00, 
+  17.00, 0.00, 0.00, 17.00, 18.00, 15.00, 10.00, 16.00, 18.00, 5.00, 9.00, 10.00, 18.00, 7.00, 11.00, 5.00, 4.00, 16.00, 2.00, 8.00, 
+  13.00, 1.00, 12.00, 3.00, 4.00, 6.00, 15.00, 12.00, 0.00, 6.00, 18.00, 12.00, 14.00, 18.00, 3.00, 2.00, 3.00, 5.00, 3.00, 14.00, 
+  18.00, 12.00, 10.00, 11.00, 8.00, 4.00, 10.00, 10.00, 9.00, 18.00, 14.00, 3.00, 7.00, 17.00, 12.00, 0.00, 10.00, 9.00, 17.00, 3.00, 
+  0.00, 4.00, 6.00, 16.00, 14.00, 12.00, 13.00, 13.00, 18.00, 7.00, 0.00, 1.00, 9.00, 7.00, 12.00, 6.00, 18.00, 8.00, 9.00, 13.00, 
+  13.00, 17.00, 10.00, 16.00, 1.00, 10.00, 17.00, 16.00, 2.00, 18.00, 4.00, 2.00, 6.00, 1.00, 1.00, 1.00, 8.00, 14.00, 6.00, 6.00, 
+  13.00, 14.00, 13.00, 6.00, 5.00, 10.00, 11.00, 11.00, 16.00, 1.00, 5.00, 9.00, 13.00, 8.00, 10.00, 2.00, 12.00, 15.00, 5.00, 14.00, 
+  3.00, 7.00, 9.00, 18.00, 2.00, 11.00, 16.00, 4.00, 5.00, 10.00, 17.00, 10.00, 3.00, 4.00, 14.00, 18.00, 13.00, 6.00, 8.00, 11.00, 
+  14.00, 3.00, 5.00, 6.00, 6.00, 5.00, 13.00, 0.00, 9.00, 9.00, 1.00, 7.00, 5.00, 5.00, 1.00, 6.00, 18.00, 11.00, 17.00, 7.00, 
+  1.00, 10.00, 5.00, 12.00, 6.00, 16.00, 16.00, 5.00, 1.00, 10.00, 10.00, 15.00, 7.00, 18.00, 8.00, 17.00, 3.00, 5.00, 3.00, 14.00, 
+  0.00, 16.00, 12.00, 0.00, 14.00, 17.00, 16.00, 2.00, 18.00, 13.00, 10.00, 13.00, 4.00, 14.00, 2.00, 3.00, 4.00, 8.00, 17.00, 0.00, 
+  6.00, 11.00, 5.00, 3.00, 3.00, 2.00, 15.00, 13.00, 10.00, 4.00, 1.00, 11.00, 6.00, 17.00, 1.00, 0.00, 18.00, 3.00, 3.00, 11.00, 
+  7.00, 7.00, 11.00, 14.00, 7.00, 16.00, 11.00, 10.00, 8.00, 6.00, 11.00, 5.00, 17.00, 10.00, 7.00, 8.00, 14.00, 2.00, 9.00, 17.00, 
+  15.00, 13.00, 10.00, 6.00, 0.00, 15.00, 11.00, 10.00, 11.00, 18.00, 2.00, 5.00, 17.00, 18.00, 11.00, 15.00, 3.00, 17.00, 9.00, 17.00, 
+  8.00, 6.00, 2.00, 4.00, 2.00, 11.00, 15.00, 2.00, 18.00, 3.00, 9.00, 7.00, 15.00, 9.00, 14.00, 10.00, 9.00, 6.00, 13.00, 8.00, 
+  15.00, 14.00, 0.00, 11.00, 5.00, 2.00, 12.00, 14.00, 10.00, 16.00, 9.00, 7.00, 9.00, 17.00, 4.00, 4.00, 7.00, 8.00, 4.00, 4.00, 
+  9.00, 7.00, 3.00, 5.00, 11.00, 11.00, 10.00, 13.00, 3.00, 14.00, 15.00, 8.00, 1.00, 1.00, 3.00, 0.00, 16.00, 9.00, 6.00, 1.00, 
+  0.00, 2.00, 0.00, 6.00, 13.00, 12.00, 5.00, 18.00, 1.00, 11.00, 17.00, 11.00, 16.00, 14.00, 14.00, 9.00, 11.00, 9.00, 17.00, 15.00, 
+  5.00, 18.00, 2.00, 11.00, 10.00, 16.00, 18.00, 5.00, 11.00, 12.00, 11.00, 18.00, 7.00, 6.00, 8.00, 3.00, 4.00, 3.00, 16.00, 4.00, 
+  6.00, 2.00, 15.00, 6.00, 7.00, 16.00, 0.00, 7.00, 11.00, 10.00, 3.00, 0.00, 14.00, 16.00, 15.00, 15.00, 12.00, 7.00, 1.00, 4.00, 
+  8.00, 4.00, 12.00, 0.00, 7.00, 8.00, 1.00, 1.00, 14.00, 15.00, 9.00, 8.00, 6.00, 6.00, 4.00, 7.00, 8.00, 13.00, 10.00, 5.00, 
+  8.00, 11.00, 2.00, 16.00, 7.00, 17.00, 5.00, 2.00, 17.00, 0.00, 18.00, 6.00, 7.00, 4.00, 4.00, 12.00, 0.00, 18.00, 8.00, 4.00, 
+  7.00, 0.00, 11.00, 1.00, 11.00, 17.00, 18.00, 15.00, 8.00, 11.00, 15.00, 9.00, 12.00, 1.00, 5.00, 6.00, 1.00, 18.00, 14.00, 7.00, 
+  16.00, 16.00, 10.00, 3.00, 13.00, 0.00, 12.00, 9.00, 18.00, 14.00, 15.00, 4.00, 11.00, 15.00, 15.00, 8.00, 16.00, 11.00, 13.00, 12.00, 
+  1.00, 13.00, 14.00, 2.00, 11.00, 0.00, 17.00, 11.00, 12.00, 6.00, 4.00, 4.00, 11.00, 13.00, 10.00, 2.00, 10.00, 14.00, 0.00, 6.00, 
+  18.00, 10.00, 7.00, 14.00, 12.00, 9.00, 4.00, 16.00, 17.00, 8.00, 14.00, 9.00, 0.00, 4.00, 15.00, 13.00, 8.00, 13.00, 13.00, 8.00, 
+  15.00, 6.00, 11.00, 4.00, 2.00, 6.00, 5.00, 14.00, 5.00, 17.00, 12.00, 11.00, 17.00, 4.00, 13.00, 7.00, 16.00, 12.00, 7.00, 18.00
+};
+
+static data_t input2_data[DATA_SIZE] = 
+{
+  8.00, 6.00, 0.00, 18.00, 6.00, 10.00, 1.00, 2.00, 4.00, 2.00, 4.00, 10.00, 6.00, 11.00, 17.00, 4.00, 0.00, 16.00, 14.00, 12.00, 
+  9.00, 8.00, 13.00, 15.00, 18.00, 2.00, 13.00, 10.00, 5.00, 4.00, 12.00, 9.00, 1.00, 13.00, 12.00, 7.00, 10.00, 17.00, 11.00, 10.00, 
+  18.00, 15.00, 11.00, 12.00, 7.00, 9.00, 6.00, 5.00, 11.00, 7.00, 10.00, 12.00, 18.00, 18.00, 15.00, 1.00, 3.00, 18.00, 11.00, 16.00, 
+  13.00, 18.00, 4.00, 13.00, 8.00, 7.00, 10.00, 13.00, 0.00, 9.00, 1.00, 16.00, 13.00, 7.00, 5.00, 5.00, 11.00, 1.00, 6.00, 10.00, 
+  12.00, 3.00, 10.00, 5.00, 15.00, 15.00, 13.00, 14.00, 14.00, 1.00, 18.00, 5.00, 16.00, 14.00, 10.00, 4.00, 8.00, 4.00, 6.00, 6.00, 
+  13.00, 14.00, 8.00, 5.00, 14.00, 10.00, 9.00, 10.00, 17.00, 15.00, 6.00, 16.00, 12.00, 9.00, 10.00, 16.00, 16.00, 8.00, 1.00, 12.00, 
+  7.00, 0.00, 0.00, 3.00, 5.00, 7.00, 10.00, 3.00, 17.00, 10.00, 18.00, 16.00, 1.00, 11.00, 18.00, 9.00, 2.00, 0.00, 12.00, 6.00, 
+  13.00, 1.00, 13.00, 5.00, 7.00, 13.00, 17.00, 9.00, 15.00, 13.00, 5.00, 2.00, 4.00, 4.00, 3.00, 0.00, 9.00, 11.00, 3.00, 12.00, 
+  6.00, 11.00, 1.00, 16.00, 12.00, 11.00, 2.00, 2.00, 15.00, 12.00, 8.00, 9.00, 14.00, 2.00, 11.00, 0.00, 0.00, 7.00, 2.00, 13.00, 
+  15.00, 18.00, 7.00, 16.00, 16.00, 1.00, 1.00, 12.00, 12.00, 2.00, 2.00, 1.00, 7.00, 4.00, 0.00, 8.00, 18.00, 4.00, 11.00, 6.00, 
+  17.00, 13.00, 12.00, 5.00, 16.00, 12.00, 0.00, 9.00, 10.00, 10.00, 18.00, 12.00, 8.00, 7.00, 5.00, 8.00, 16.00, 3.00, 9.00, 18.00, 
+  12.00, 13.00, 18.00, 6.00, 8.00, 12.00, 2.00, 12.00, 8.00, 8.00, 9.00, 18.00, 8.00, 0.00, 9.00, 2.00, 6.00, 7.00, 0.00, 3.00, 
+  11.00, 2.00, 18.00, 2.00, 16.00, 1.00, 16.00, 11.00, 11.00, 16.00, 16.00, 11.00, 7.00, 4.00, 14.00, 10.00, 5.00, 8.00, 4.00, 14.00, 
+  17.00, 13.00, 13.00, 3.00, 1.00, 14.00, 1.00, 7.00, 0.00, 2.00, 7.00, 14.00, 4.00, 9.00, 14.00, 3.00, 9.00, 13.00, 13.00, 3.00, 
+  3.00, 17.00, 0.00, 18.00, 4.00, 8.00, 6.00, 9.00, 4.00, 2.00, 0.00, 14.00, 3.00, 3.00, 14.00, 8.00, 6.00, 7.00, 2.00, 12.00, 
+  5.00, 14.00, 6.00, 12.00, 2.00, 16.00, 1.00, 15.00, 7.00, 18.00, 0.00, 0.00, 13.00, 13.00, 12.00, 11.00, 16.00, 15.00, 14.00, 8.00, 
+  9.00, 10.00, 8.00, 8.00, 13.00, 13.00, 13.00, 10.00, 1.00, 15.00, 4.00, 0.00, 12.00, 1.00, 8.00, 12.00, 1.00, 18.00, 12.00, 18.00, 
+  9.00, 1.00, 11.00, 5.00, 13.00, 7.00, 1.00, 13.00, 5.00, 8.00, 17.00, 11.00, 13.00, 15.00, 9.00, 3.00, 17.00, 18.00, 9.00, 3.00, 
+  15.00, 11.00, 12.00, 0.00, 2.00, 15.00, 3.00, 0.00, 13.00, 1.00, 14.00, 14.00, 15.00, 8.00, 6.00, 0.00, 0.00, 11.00, 17.00, 0.00, 
+  1.00, 8.00, 6.00, 6.00, 10.00, 6.00, 18.00, 12.00, 7.00, 18.00, 4.00, 6.00, 15.00, 18.00, 7.00, 5.00, 8.00, 6.00, 6.00, 7.00, 
+  4.00, 4.00, 10.00, 17.00, 12.00, 13.00, 11.00, 15.00, 12.00, 18.00, 7.00, 12.00, 17.00, 10.00, 14.00, 12.00, 2.00, 7.00, 17.00, 3.00, 
+  8.00, 6.00, 3.00, 9.00, 3.00, 7.00, 7.00, 15.00, 18.00, 5.00, 13.00, 13.00, 15.00, 10.00, 0.00, 11.00, 10.00, 1.00, 5.00, 16.00, 
+  2.00, 7.00, 14.00, 12.00, 7.00, 17.00, 17.00, 11.00, 0.00, 5.00, 16.00, 14.00, 1.00, 9.00, 8.00, 8.00, 3.00, 17.00, 0.00, 8.00, 
+  6.00, 5.00, 7.00, 6.00, 17.00, 3.00, 3.00, 8.00, 3.00, 12.00, 17.00, 5.00, 14.00, 3.00, 11.00, 5.00, 17.00, 2.00, 15.00, 1.00, 
+  18.00, 11.00, 12.00, 0.00, 0.00, 14.00, 7.00, 17.00, 15.00, 10.00, 18.00, 10.00, 11.00, 7.00, 12.00, 10.00, 17.00, 2.00, 18.00, 9.00, 
+  11.00, 4.00, 17.00, 10.00, 15.00, 12.00, 4.00, 1.00, 5.00, 10.00, 4.00, 2.00, 11.00, 3.00, 4.00, 15.00, 16.00, 10.00, 2.00, 2.00, 
+  15.00, 16.00, 0.00, 13.00, 16.00, 9.00, 1.00, 7.00, 3.00, 10.00, 7.00, 2.00, 12.00, 8.00, 1.00, 5.00, 0.00, 16.00, 4.00, 14.00, 
+  13.00, 16.00, 3.00, 0.00, 10.00, 6.00, 3.00, 9.00, 1.00, 3.00, 0.00, 13.00, 12.00, 17.00, 11.00, 4.00, 15.00, 15.00, 12.00, 4.00, 
+  4.00, 2.00, 16.00, 6.00, 11.00, 17.00, 14.00, 7.00, 4.00, 14.00, 8.00, 8.00, 3.00, 18.00, 17.00, 17.00, 12.00, 10.00, 11.00, 1.00, 
+  8.00, 13.00, 1.00, 14.00, 0.00, 9.00, 0.00, 7.00, 9.00, 0.00, 7.00, 12.00, 0.00, 18.00, 10.00, 1.00, 5.00, 13.00, 13.00, 2.00, 
+  10.00, 4.00, 2.00, 6.00, 0.00, 16.00, 2.00, 15.00, 13.00, 6.00, 8.00, 5.00, 6.00, 15.00, 12.00, 6.00, 6.00, 7.00, 8.00, 1.00, 
+  11.00, 9.00, 7.00, 18.00, 14.00, 4.00, 9.00, 6.00, 4.00, 2.00, 10.00, 13.00, 6.00, 17.00, 2.00, 11.00, 7.00, 3.00, 8.00, 9.00, 
+  2.00, 6.00, 18.00, 12.00, 18.00, 13.00, 8.00, 1.00, 11.00, 4.00, 13.00, 14.00, 16.00, 8.00, 6.00, 18.00, 14.00, 15.00, 9.00, 11.00, 
+  2.00, 13.00, 4.00, 3.00, 3.00, 15.00, 14.00, 3.00, 13.00, 12.00, 14.00, 16.00, 18.00, 12.00, 5.00, 11.00, 2.00, 3.00, 15.00, 1.00, 
+  12.00, 1.00, 15.00, 13.00, 12.00, 18.00, 4.00, 17.00, 13.00, 7.00, 11.00, 13.00, 7.00, 10.00, 1.00, 3.00, 18.00, 6.00, 10.00, 3.00, 
+  9.00, 16.00, 12.00, 10.00, 6.00, 6.00, 7.00, 16.00, 16.00, 16.00, 17.00, 18.00, 8.00, 18.00, 0.00, 6.00, 17.00, 13.00, 14.00, 8.00, 
+  0.00, 7.00, 5.00, 13.00, 8.00, 12.00, 14.00, 9.00, 10.00, 10.00, 9.00, 9.00, 8.00, 6.00, 0.00, 14.00, 16.00, 8.00, 7.00, 16.00, 
+  10.00, 3.00, 1.00, 9.00, 11.00, 2.00, 6.00, 18.00, 5.00, 4.00, 2.00, 11.00, 10.00, 17.00, 16.00, 2.00, 12.00, 15.00, 14.00, 6.00, 
+  6.00, 17.00, 3.00, 10.00, 9.00, 18.00, 18.00, 6.00, 11.00, 16.00, 18.00, 17.00, 7.00, 14.00, 1.00, 16.00, 7.00, 9.00, 11.00, 12.00, 
+  10.00, 6.00, 1.00, 16.00, 9.00, 18.00, 0.00, 9.00, 16.00, 10.00, 14.00, 6.00, 9.00, 14.00, 15.00, 7.00, 12.00, 8.00, 1.00, 1.00, 
+  1.00, 17.00, 17.00, 17.00, 18.00, 1.00, 15.00, 18.00, 16.00, 16.00, 11.00, 7.00, 4.00, 15.00, 3.00, 14.00, 13.00, 14.00, 9.00, 2.00, 
+  4.00, 8.00, 14.00, 7.00, 0.00, 12.00, 14.00, 15.00, 8.00, 2.00, 11.00, 5.00, 6.00, 16.00, 6.00, 4.00, 16.00, 7.00, 9.00, 5.00, 
+  1.00, 0.00, 16.00, 10.00, 9.00, 6.00, 5.00, 8.00, 15.00, 13.00, 7.00, 18.00, 18.00, 8.00, 0.00, 15.00, 4.00, 6.00, 14.00, 3.00, 
+  3.00, 2.00, 9.00, 14.00, 18.00, 13.00, 10.00, 15.00, 0.00, 11.00, 16.00, 7.00, 16.00, 18.00, 0.00, 12.00, 6.00, 13.00, 12.00, 12.00, 
+  5.00, 3.00, 5.00, 16.00, 13.00, 16.00, 8.00, 5.00, 12.00, 8.00, 8.00, 0.00, 2.00, 9.00, 18.00, 11.00, 8.00, 4.00, 14.00, 6.00, 
+  17.00, 2.00, 6.00, 8.00, 11.00, 13.00, 6.00, 18.00, 17.00, 6.00, 8.00, 0.00, 1.00, 14.00, 18.00, 4.00, 0.00, 4.00, 3.00, 3.00, 
+  16.00, 8.00, 16.00, 1.00, 2.00, 0.00, 15.00, 14.00, 10.00, 9.00, 15.00, 3.00, 5.00, 18.00, 5.00, 6.00, 7.00, 3.00, 7.00, 2.00, 
+  6.00, 12.00, 10.00, 10.00, 18.00, 16.00, 0.00, 9.00, 17.00, 10.00, 9.00, 14.00, 15.00, 5.00, 8.00, 15.00, 3.00, 15.00, 14.00, 11.00, 
+  6.00, 6.00, 14.00, 0.00, 14.00, 0.00, 7.00, 12.00, 8.00, 7.00, 1.00, 3.00, 6.00, 10.00, 12.00, 1.00, 16.00, 5.00, 5.00, 6.00, 
+  17.00, 15.00, 15.00, 9.00, 4.00, 18.00, 17.00, 13.00, 12.00, 9.00, 7.00, 10.00, 2.00, 5.00, 8.00, 18.00, 1.00, 15.00, 8.00, 0.00
+};
+
+static data_t verify_data[DATA_SIZE] = 
+{
+  8.00, 21.00, 10.00, 21.00, 20.00, 16.00, 3.00, 20.00, 15.00, 17.00, 15.00, 10.00, 23.00, 27.00, 24.00, 17.00, 18.00, 18.00, 16.00, 17.00, 
+  17.00, 13.00, 25.00, 29.00, 24.00, 14.00, 29.00, 17.00, 14.00, 21.00, 22.00, 19.00, 4.00, 18.00, 26.00, 18.00, 19.00, 29.00, 14.00, 11.00, 
+  23.00, 19.00, 17.00, 29.00, 24.00, 13.00, 23.00, 20.00, 28.00, 25.00, 13.00, 30.00, 28.00, 24.00, 27.00, 13.00, 6.00, 20.00, 27.00, 17.00, 
+  18.00, 24.00, 6.00, 30.00, 24.00, 12.00, 20.00, 31.00, 14.00, 13.00, 10.00, 25.00, 20.00, 11.00, 13.00, 18.00, 23.00, 7.00, 10.00, 27.00, 
+  17.00, 5.00, 21.00, 16.00, 22.00, 21.00, 21.00, 19.00, 20.00, 7.00, 29.00, 6.00, 34.00, 21.00, 16.00, 13.00, 18.00, 21.00, 20.00, 10.00, 
+  27.00, 25.00, 10.00, 5.00, 16.00, 27.00, 26.00, 25.00, 27.00, 23.00, 18.00, 34.00, 17.00, 9.00, 10.00, 17.00, 17.00, 16.00, 12.00, 23.00, 
+  14.00, 5.00, 15.00, 21.00, 20.00, 13.00, 18.00, 12.00, 35.00, 16.00, 33.00, 32.00, 11.00, 29.00, 31.00, 15.00, 12.00, 16.00, 12.00, 16.00, 
+  25.00, 9.00, 21.00, 8.00, 7.00, 14.00, 21.00, 9.00, 23.00, 28.00, 21.00, 11.00, 11.00, 11.00, 13.00, 9.00, 25.00, 23.00, 8.00, 17.00, 
+  15.00, 16.00, 18.00, 20.00, 25.00, 24.00, 6.00, 16.00, 25.00, 17.00, 18.00, 19.00, 20.00, 20.00, 16.00, 15.00, 5.00, 22.00, 15.00, 31.00, 
+  21.00, 31.00, 12.00, 34.00, 28.00, 15.00, 2.00, 19.00, 14.00, 3.00, 9.00, 13.00, 22.00, 19.00, 6.00, 10.00, 19.00, 6.00, 29.00, 12.00, 
+  27.00, 27.00, 21.00, 20.00, 27.00, 12.00, 3.00, 10.00, 12.00, 12.00, 32.00, 19.00, 26.00, 7.00, 7.00, 10.00, 32.00, 11.00, 13.00, 23.00, 
+  19.00, 24.00, 25.00, 16.00, 22.00, 22.00, 5.00, 12.00, 21.00, 17.00, 23.00, 18.00, 22.00, 1.00, 12.00, 18.00, 8.00, 21.00, 6.00, 20.00, 
+  28.00, 8.00, 27.00, 10.00, 25.00, 13.00, 21.00, 25.00, 13.00, 32.00, 33.00, 16.00, 11.00, 4.00, 28.00, 20.00, 11.00, 23.00, 19.00, 28.00, 
+  22.00, 14.00, 21.00, 11.00, 14.00, 22.00, 1.00, 11.00, 7.00, 11.00, 20.00, 30.00, 13.00, 23.00, 23.00, 16.00, 9.00, 20.00, 29.00, 20.00, 
+  21.00, 27.00, 13.00, 26.00, 8.00, 17.00, 19.00, 9.00, 10.00, 6.00, 6.00, 18.00, 13.00, 17.00, 28.00, 17.00, 21.00, 22.00, 5.00, 15.00, 
+  17.00, 14.00, 9.00, 14.00, 18.00, 17.00, 8.00, 17.00, 23.00, 20.00, 2.00, 0.00, 27.00, 16.00, 15.00, 21.00, 20.00, 25.00, 17.00, 12.00, 
+  22.00, 24.00, 21.00, 8.00, 14.00, 28.00, 29.00, 19.00, 8.00, 24.00, 4.00, 11.00, 13.00, 2.00, 23.00, 29.00, 13.00, 34.00, 27.00, 22.00, 
+  17.00, 3.00, 21.00, 15.00, 13.00, 25.00, 18.00, 20.00, 12.00, 10.00, 27.00, 28.00, 22.00, 22.00, 14.00, 6.00, 25.00, 29.00, 15.00, 12.00, 
+  28.00, 11.00, 15.00, 5.00, 4.00, 20.00, 10.00, 4.00, 22.00, 3.00, 27.00, 31.00, 29.00, 20.00, 7.00, 3.00, 7.00, 28.00, 17.00, 14.00, 
+  17.00, 10.00, 8.00, 7.00, 12.00, 21.00, 34.00, 20.00, 9.00, 22.00, 19.00, 21.00, 25.00, 24.00, 18.00, 14.00, 23.00, 23.00, 9.00, 15.00, 
+  19.00, 7.00, 20.00, 32.00, 20.00, 27.00, 27.00, 30.00, 27.00, 32.00, 8.00, 19.00, 21.00, 28.00, 16.00, 25.00, 13.00, 22.00, 24.00, 13.00, 
+  21.00, 16.00, 10.00, 23.00, 21.00, 11.00, 25.00, 19.00, 21.00, 14.00, 14.00, 26.00, 30.00, 12.00, 5.00, 26.00, 22.00, 11.00, 7.00, 16.00, 
+  12.00, 22.00, 14.00, 23.00, 21.00, 28.00, 31.00, 20.00, 1.00, 23.00, 30.00, 32.00, 16.00, 14.00, 9.00, 23.00, 21.00, 31.00, 3.00, 23.00, 
+  17.00, 7.00, 22.00, 6.00, 30.00, 4.00, 7.00, 22.00, 17.00, 17.00, 19.00, 18.00, 31.00, 11.00, 18.00, 11.00, 22.00, 12.00, 29.00, 15.00, 
+  35.00, 11.00, 12.00, 17.00, 18.00, 29.00, 17.00, 33.00, 33.00, 15.00, 27.00, 20.00, 29.00, 14.00, 23.00, 15.00, 21.00, 18.00, 20.00, 17.00, 
+  24.00, 5.00, 29.00, 13.00, 19.00, 18.00, 19.00, 13.00, 5.00, 16.00, 22.00, 14.00, 25.00, 21.00, 7.00, 17.00, 19.00, 15.00, 5.00, 16.00, 
+  33.00, 28.00, 10.00, 24.00, 24.00, 13.00, 11.00, 17.00, 12.00, 28.00, 21.00, 5.00, 19.00, 25.00, 13.00, 5.00, 10.00, 25.00, 21.00, 17.00, 
+  13.00, 20.00, 9.00, 16.00, 24.00, 18.00, 16.00, 22.00, 19.00, 10.00, 0.00, 14.00, 21.00, 24.00, 23.00, 10.00, 33.00, 23.00, 21.00, 17.00, 
+  17.00, 19.00, 26.00, 22.00, 12.00, 27.00, 31.00, 23.00, 6.00, 32.00, 12.00, 10.00, 9.00, 19.00, 18.00, 18.00, 20.00, 24.00, 17.00, 7.00, 
+  21.00, 27.00, 14.00, 20.00, 5.00, 19.00, 11.00, 18.00, 25.00, 1.00, 12.00, 21.00, 13.00, 26.00, 20.00, 3.00, 17.00, 28.00, 18.00, 16.00, 
+  13.00, 11.00, 11.00, 24.00, 2.00, 27.00, 18.00, 19.00, 18.00, 16.00, 25.00, 15.00, 9.00, 19.00, 26.00, 24.00, 19.00, 13.00, 16.00, 12.00, 
+  25.00, 12.00, 12.00, 24.00, 20.00, 9.00, 22.00, 6.00, 13.00, 11.00, 11.00, 20.00, 11.00, 22.00, 3.00, 17.00, 25.00, 14.00, 25.00, 16.00, 
+  3.00, 16.00, 23.00, 24.00, 24.00, 29.00, 24.00, 6.00, 12.00, 14.00, 23.00, 29.00, 23.00, 26.00, 14.00, 35.00, 17.00, 20.00, 12.00, 25.00, 
+  2.00, 29.00, 16.00, 3.00, 17.00, 32.00, 30.00, 5.00, 31.00, 25.00, 24.00, 29.00, 22.00, 26.00, 7.00, 14.00, 6.00, 11.00, 32.00, 1.00, 
+  18.00, 12.00, 20.00, 16.00, 15.00, 20.00, 19.00, 30.00, 23.00, 11.00, 12.00, 24.00, 13.00, 27.00, 2.00, 3.00, 36.00, 9.00, 13.00, 14.00, 
+  16.00, 23.00, 23.00, 24.00, 13.00, 22.00, 18.00, 26.00, 24.00, 22.00, 28.00, 23.00, 25.00, 28.00, 7.00, 14.00, 31.00, 15.00, 23.00, 25.00, 
+  15.00, 20.00, 15.00, 19.00, 8.00, 27.00, 25.00, 19.00, 21.00, 28.00, 11.00, 14.00, 25.00, 24.00, 11.00, 29.00, 19.00, 25.00, 16.00, 33.00, 
+  18.00, 9.00, 3.00, 13.00, 13.00, 13.00, 21.00, 20.00, 23.00, 7.00, 11.00, 18.00, 25.00, 26.00, 30.00, 12.00, 21.00, 21.00, 27.00, 14.00, 
+  21.00, 31.00, 3.00, 21.00, 14.00, 20.00, 30.00, 20.00, 21.00, 32.00, 27.00, 24.00, 16.00, 31.00, 5.00, 20.00, 14.00, 17.00, 15.00, 16.00, 
+  19.00, 13.00, 4.00, 21.00, 20.00, 29.00, 10.00, 22.00, 19.00, 24.00, 29.00, 14.00, 10.00, 15.00, 18.00, 7.00, 28.00, 17.00, 7.00, 2.00, 
+  1.00, 19.00, 17.00, 23.00, 31.00, 13.00, 20.00, 36.00, 17.00, 27.00, 28.00, 18.00, 20.00, 29.00, 17.00, 23.00, 24.00, 23.00, 26.00, 17.00, 
+  9.00, 26.00, 16.00, 18.00, 10.00, 28.00, 32.00, 20.00, 19.00, 14.00, 22.00, 23.00, 13.00, 22.00, 14.00, 7.00, 20.00, 10.00, 25.00, 9.00, 
+  7.00, 2.00, 31.00, 16.00, 16.00, 22.00, 5.00, 15.00, 26.00, 23.00, 10.00, 18.00, 32.00, 24.00, 15.00, 30.00, 16.00, 13.00, 15.00, 7.00, 
+  11.00, 6.00, 21.00, 14.00, 25.00, 21.00, 11.00, 16.00, 14.00, 26.00, 25.00, 15.00, 22.00, 24.00, 4.00, 19.00, 14.00, 26.00, 22.00, 17.00, 
+  13.00, 14.00, 7.00, 32.00, 20.00, 33.00, 13.00, 7.00, 29.00, 8.00, 26.00, 6.00, 9.00, 13.00, 22.00, 23.00, 8.00, 22.00, 22.00, 10.00, 
+  24.00, 2.00, 17.00, 9.00, 22.00, 30.00, 24.00, 33.00, 25.00, 17.00, 23.00, 9.00, 13.00, 15.00, 23.00, 10.00, 1.00, 22.00, 17.00, 10.00, 
+  32.00, 24.00, 26.00, 4.00, 15.00, 0.00, 27.00, 23.00, 28.00, 23.00, 30.00, 7.00, 16.00, 33.00, 20.00, 14.00, 23.00, 14.00, 20.00, 14.00, 
+  7.00, 25.00, 24.00, 12.00, 29.00, 16.00, 17.00, 20.00, 29.00, 16.00, 13.00, 18.00, 26.00, 18.00, 18.00, 17.00, 13.00, 29.00, 14.00, 17.00, 
+  24.00, 16.00, 21.00, 14.00, 26.00, 9.00, 11.00, 28.00, 25.00, 15.00, 15.00, 12.00, 6.00, 14.00, 27.00, 14.00, 24.00, 18.00, 18.00, 14.00, 
+  32.00, 21.00, 26.00, 13.00, 6.00, 24.00, 22.00, 27.00, 17.00, 26.00, 19.00, 21.00, 19.00, 9.00, 21.00, 25.00, 17.00, 27.00, 15.00, 18.00
+};
+
diff --git a/benchmarks/mt-vvadd/mt-vvadd.c b/benchmarks/mt-vvadd/mt-vvadd.c
new file mode 100644 (file)
index 0000000..497b9bb
--- /dev/null
@@ -0,0 +1,165 @@
+//**************************************************************************
+// Vector-vector add benchmark
+//--------------------------------------------------------------------------
+// Author  : Andrew Waterman
+// TA      : Christopher Celio
+// Student : 
+//
+// This benchmark adds two vectors and writes the results to a
+// third vector. The input data (and reference data) should be
+// generated using the vvadd_gendata.pl perl script and dumped
+// to a file named dataset.h 
+
+// to print out arrays, etc.
+//#define DEBUG
+
+//--------------------------------------------------------------------------
+// Includes 
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+typedef float data_t;
+#include "dataset.h"
+  
+//--------------------------------------------------------------------------
+// Basic Utilities and Multi-thread Support
+
+__thread unsigned long coreid;
+unsigned long ncores;
+
+#include "util.h"
+   
+#define stringify_1(s) #s
+#define stringify(s) stringify_1(s)
+#define stats(code) do { \
+    unsigned long _c = -rdcycle(), _i = -rdinstret(); \
+    code; \
+    _c += rdcycle(), _i += rdinstret(); \
+    if (coreid == 0) \
+      printf("%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \
+             stringify(code), _c, _c/DATA_SIZE, 10*_c/DATA_SIZE%10, _c/_i, 10*_c/_i%10); \
+  } while(0)
+
+//--------------------------------------------------------------------------
+// Helper functions
+void printArray( char name[], int n, data_t arr[] )
+{
+  int i;
+  if (coreid != 0)
+     return;
+
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %4ld ", (long) arr[i] );
+  printf( "\n" );
+}
+      
+void __attribute__((noinline)) verify(size_t n, const data_t* test, const data_t* correct)
+{
+   if (coreid != 0)
+      return;
+
+   size_t i;
+   for (i = 0; i < n; i++)
+   {
+      if (test[i] != correct[i])
+      {
+         printf("FAILED test[%d]= %4ld, correct[%d]= %4ld\n", 
+            i, (long) test[i], i, (long)correct[i]);
+         exit(-1);
+      }
+   }
+   
+   return;
+}
+//--------------------------------------------------------------------------
+// vvadd function
+
+//perform in-place vvadd
+void __attribute__((noinline)) vvadd(size_t n, data_t* __restrict__ x, const data_t* __restrict__ y)
+{
+   size_t i;
+
+   // interleave accesses
+   for (i = coreid; i < n; i+=ncores)
+   {
+      x[i] = x[i] + y[i];
+   }
+}
+
+void __attribute__((noinline)) vvadd_opt(size_t n, data_t* __restrict__ x, const data_t* __restrict__ y)
+{
+   // ***************************** //
+   // **** ADD YOUR CODE HERE ***** //
+   // ***************************** //
+}
+
+//--------------------------------------------------------------------------
+// Main
+//
+// all threads start executing thread_entry(). Use their "coreid" to
+// differentiate between threads (each thread is running on a separate core).
+  
+void thread_entry(int cid, int nc)
+{
+   coreid = cid;
+   ncores = nc;
+
+   // static allocates data in the binary, which is visible to both threads
+   static data_t results_data[DATA_SIZE];
+   
+   // because we're going to perform an in-place vvadd (and we're going to run
+   // it a couple of times) let's copy the input data to a temporary results
+   // array
+   
+   size_t i;
+   if (coreid == 0)
+   {
+      for (i = 0; i < DATA_SIZE; i++)
+         results_data[i] = input1_data[i];
+   }
+
+
+   // Execute the provided, terrible vvadd
+   barrier();
+   stats(vvadd(DATA_SIZE, results_data, input2_data); barrier());
+   
+   // verify
+   verify(DATA_SIZE, results_data, verify_data);
+   
+   // reset results from the first trial
+   if (coreid == 0) 
+   {
+      for (i=0; i < DATA_SIZE; i++)
+         results_data[i] = input1_data[i];
+   }
+   barrier();
+                                            
+   
+   // Execute your faster vvadd
+   barrier();
+   stats(vvadd_opt(DATA_SIZE, results_data, input2_data); barrier());
+
+#ifdef DEBUG
+   printArray("results: ", DATA_SIZE, results_data);
+   printArray("verify : ", DATA_SIZE, verify_data);
+#endif
+   
+   // verify
+   verify(DATA_SIZE, results_data, verify_data);
+   barrier();
+
+   exit(0);
+}
+
diff --git a/benchmarks/mt-vvadd/vvadd_gendata.pl b/benchmarks/mt-vvadd/vvadd_gendata.pl
new file mode 100755 (executable)
index 0000000..a9fceac
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# vvadd_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the vvadd benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: vvadd_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "static data_t ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3.2f",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values1;
+  my @values2;
+  my @sum;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    my $value1 = int(rand(19));
+    my $value2 = int(rand(19));
+    push( @values1, $value1 );
+    push( @values2, $value2 );
+    push( @sum, $value1 + $value2 );
+  }
+
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input1_data", \@values1 );
+  printArray( "input2_data", \@values2 );
+  printArray( "verify_data", \@sum );
+
+}
+
+main();
+
diff --git a/benchmarks/multiply/bmark.mk b/benchmarks/multiply/bmark.mk
new file mode 100644 (file)
index 0000000..d6114a1
--- /dev/null
@@ -0,0 +1,30 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which 
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include 
+# the benchmark name as a prefix so that they are unique.
+#
+
+multiply_c_src = \
+       multiply_main.c \
+       multiply.c \
+
+multiply_riscv_src = \
+       crt.S \
+
+multiply_c_objs     = $(patsubst %.c, %.o, $(multiply_c_src))
+multiply_riscv_objs = $(patsubst %.S, %.o, $(multiply_riscv_src))
+
+multiply_host_bin = multiply.host
+$(multiply_host_bin): $(multiply_c_src)
+       $(HOST_COMP) $^ -o $(multiply_host_bin)
+
+multiply_riscv_bin = multiply.riscv
+$(multiply_riscv_bin): $(multiply_c_objs) $(multiply_riscv_objs)
+       $(RISCV_LINK) $(multiply_c_objs) $(multiply_riscv_objs) -o $(multiply_riscv_bin)
+
+junk += $(multiply_c_objs) $(multiply_riscv_objs) \
+        $(multiply_host_bin) $(multiply_riscv_bin)
diff --git a/benchmarks/multiply/dataset1.h b/benchmarks/multiply/dataset1.h
new file mode 100644 (file)
index 0000000..292ad7f
--- /dev/null
@@ -0,0 +1,30 @@
+
+#define DATA_SIZE 100 
+
+int input_data1[DATA_SIZE] = 
+{
+   41, 454, 833, 335, 564,   1, 187, 989, 749, 365, 350, 572, 132,  64, 949, 153, 584, 216, 805, 140, 
+  621, 210,   6, 572, 931, 339, 890, 593, 392, 898, 694, 228, 961,  12, 110, 883, 116, 750, 296, 646, 
+  426, 500, 314, 436, 659, 701, 774, 812, 319, 981, 678, 150, 875, 696, 376, 564, 474, 272, 938, 258, 
+  539, 647, 569, 509, 203,  88, 280, 703, 759, 669, 606, 375, 511, 551, 657, 936, 195, 592,  81, 569, 
+  267, 952, 229, 800, 337, 584, 944, 643, 902, 368, 241, 489, 913, 328, 826, 313, 933, 592, 985, 388
+};
+
+int input_data2[DATA_SIZE] = 
+{
+  195, 543, 960, 649, 566, 979, 350, 997, 649, 814, 657,  79, 181, 208, 111, 998, 859, 629,  65, 847, 
+  288, 704, 349, 997, 141, 253, 905, 715, 886, 430, 264, 415, 576, 538, 979, 700, 761,   4, 241, 494, 
+  478, 100, 499, 864, 403, 693, 222, 416, 444, 296, 721, 285, 676, 620, 317,  78, 224, 351, 937, 540, 
+  288, 646, 119, 169, 615, 527, 606, 289, 389, 796, 351, 801, 455, 720, 278, 758, 367, 745, 358,  92, 
+  584, 989,  62, 271, 985, 853, 403, 788, 346, 531, 517, 222, 559, 461, 908, 241, 775, 358, 255, 332
+};
+
+int verify_data[DATA_SIZE] = 
+{
+  7995, 246522, 799680, 217415, 319224, 979, 65450, 986033, 486101, 297110, 229950, 45188, 23892, 13312, 105339, 152694, 501656, 135864, 52325, 118580, 
+  178848, 147840, 2094, 570284, 131271, 85767, 805450, 423995, 347312, 386140, 183216, 94620, 553536, 6456, 107690, 618100, 88276, 3000, 71336, 319124, 
+  203628, 50000, 156686, 376704, 265577, 485793, 171828, 337792, 141636, 290376, 488838, 42750, 591500, 431520, 119192, 43992, 106176, 95472, 878906, 139320, 
+  155232, 417962, 67711, 86021, 124845, 46376, 169680, 203167, 295251, 532524, 212706, 300375, 232505, 396720, 182646, 709488, 71565, 441040, 28998, 52348, 
+  155928, 941528, 14198, 216800, 331945, 498152, 380432, 506684, 312092, 195408, 124597, 108558, 510367, 151208, 750008, 75433, 723075, 211936, 251175, 128816
+};
+
diff --git a/benchmarks/multiply/multiply.c b/benchmarks/multiply/multiply.c
new file mode 100644 (file)
index 0000000..98b279b
--- /dev/null
@@ -0,0 +1,22 @@
+// *************************************************************************
+// multiply function (c version)
+// -------------------------------------------------------------------------
+
+int multiply( int x, int y )
+{
+
+ int i;
+ int result = 0;
+
+ for (i = 0; i < 32; i++) {
+   if ((x & 0x1) == 1)
+     result = result + y;
+       
+   x = x >> 1;
+   y = y << 1;
+ } 
+ return result;
+
+}
+
diff --git a/benchmarks/multiply/multiply.h b/benchmarks/multiply/multiply.h
new file mode 100644 (file)
index 0000000..6d27795
--- /dev/null
@@ -0,0 +1,9 @@
+//**************************************************************************
+// Software multiply function
+//--------------------------------------------------------------------------
+
+// Simple C version
+int multiply(int x, int y);
+
+// Simple assembly version
+int multiply_asm(int x, int y);
diff --git a/benchmarks/multiply/multiply_gendata.pl b/benchmarks/multiply/multiply_gendata.pl
new file mode 100755 (executable)
index 0000000..b8d8ed5
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# multiply_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : May 9, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data 
+# for the multiply benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: multiply_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [750]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 750;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "int ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3d",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+  
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+  
+  my @values1;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    push( @values1, int(rand(999)) );
+  }
+  
+  my @values2;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    push( @values2, int(rand(999)) );
+  }
+
+  my @multiply;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    $multiply[$i] = $values1[$i] * $values2[$i];
+  }
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input_data1", \@values1 );
+  printArray( "input_data2", \@values2 );
+  printArray( "verify_data", \@multiply );
+
+}
+
+main();
+
diff --git a/benchmarks/multiply/multiply_main.c b/benchmarks/multiply/multiply_main.c
new file mode 100644 (file)
index 0000000..fcb6b27
--- /dev/null
@@ -0,0 +1,147 @@
+// *************************************************************************
+// multiply filter bencmark
+// -------------------------------------------------------------------------
+//
+// This benchmark tests the software multiply implemenation. The
+// input data (and reference data) should be generated using the
+// multiply_gendata.pl perl script and dumped to a file named
+// dataset1.h You should not change anything except the
+// HOST_DEBUG and VERIFY macros for your timing run.
+
+#include "multiply.h"
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host 
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG 
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set VERIFY to 1 if you want the program to check that the sort
+// function returns the right answer. When you are doing your 
+// benchmarking you should set this to 0 so that the verification
+// is not included in your timing.
+
+#ifndef VERIFY
+#define VERIFY     1
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, int test[], int correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, int arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %3d ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  int i;
+  int results_data[DATA_SIZE];
+
+  // Output the input arrays
+
+#if HOST_DEBUG
+  printArray( "input1",  DATA_SIZE, input_data1  );
+  printArray( "input2",  DATA_SIZE, input_data2  );
+  printArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+#if ( !HOST_DEBUG && PREALLOCATE )
+  for (i = 0; i < DATA_SIZE; i++)
+  {
+    results_data[i] = multiply( input_data1[i], input_data2[i] );
+  }
+#endif
+
+#if HOST_DEBUG
+  for (i = 0; i < DATA_SIZE; i++)
+  {
+    results_data[i] = multiply( input_data1[i], input_data2[i] );
+  }
+#else
+  setStats(1);
+  for (i = 0; i < DATA_SIZE; i++)
+  {
+    results_data[i] = multiply( input_data1[i], input_data2[i] );
+  }
+  setStats(0);
+#endif
+  
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", DATA_SIZE, results_data );
+#endif
+
+  // Check the results
+
+  finishTest(verify( DATA_SIZE, results_data, verify_data ));
+
+}
diff --git a/benchmarks/qsort/bmark.mk b/benchmarks/qsort/bmark.mk
new file mode 100644 (file)
index 0000000..cdc0545
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+qsort_c_src = \
+       qsort_main.c \
+
+qsort_riscv_src = \
+       crt.S \
+
+qsort_c_objs     = $(patsubst %.c, %.o, $(qsort_c_src))
+qsort_riscv_objs = $(patsubst %.S, %.o, $(qsort_riscv_src))
+
+qsort_host_bin = qsort.host
+$(qsort_host_bin) : $(qsort_c_src)
+       $(HOST_COMP) $^ -o $(qsort_host_bin)
+
+qsort_riscv_bin = qsort.riscv
+$(qsort_riscv_bin) : $(qsort_c_objs) $(qsort_riscv_objs)
+       $(RISCV_LINK) $(qsort_c_objs) $(qsort_riscv_objs) -o $(qsort_riscv_bin)
+
+junk += $(qsort_c_objs) $(qsort_riscv_objs) \
+        $(qsort_host_bin) $(qsort_riscv_bin)
diff --git a/benchmarks/qsort/dataset1.h b/benchmarks/qsort/dataset1.h
new file mode 100644 (file)
index 0000000..c4d99e2
--- /dev/null
@@ -0,0 +1,37 @@
+
+#define DATA_SIZE 250
+
+int input_data[DATA_SIZE] =
+{
+   41, 454, 833, 335, 564,   1, 187, 989, 749, 365, 350, 572, 132,  64, 949, 153, 584, 216, 805, 140,
+  621, 210,   6, 572, 931, 339, 890, 593, 392, 898, 694, 228, 961,  12, 110, 883, 116, 750, 296, 646,
+  426, 500, 314, 436, 659, 701, 774, 812, 319, 981, 678, 150, 875, 696, 376, 564, 474, 272, 938, 258,
+  539, 647, 569, 509, 203,  88, 280, 703, 759, 669, 606, 375, 511, 551, 657, 936, 195, 592,  81, 569,
+  267, 952, 229, 800, 337, 584, 944, 643, 902, 368, 241, 489, 913, 328, 826, 313, 933, 592, 985, 388,
+  195, 543, 960, 649, 566, 979, 350, 997, 649, 814, 657,  79, 181, 208, 111, 998, 859, 629,  65, 847,
+  288, 704, 349, 997, 141, 253, 905, 715, 886, 430, 264, 415, 576, 538, 979, 700, 761,   4, 241, 494,
+  478, 100, 499, 864, 403, 693, 222, 416, 444, 296, 721, 285, 676, 620, 317,  78, 224, 351, 937, 540,
+  288, 646, 119, 169, 615, 527, 606, 289, 389, 796, 351, 801, 455, 720, 278, 758, 367, 745, 358,  92,
+  584, 989,  62, 271, 985, 853, 403, 788, 346, 531, 517, 222, 559, 461, 908, 241, 775, 358, 255, 332,
+  778, 684, 598, 740, 143, 446,  33, 311, 125, 743, 941, 557, 933, 479, 799, 557, 553, 925, 431, 796,
+  648, 357, 952, 891, 287, 666,  19, 514,  49, 557,  86, 870,  95, 853, 441, 440, 587,  61, 614, 678,
+  382, 396, 280,   9, 808,  17, 971, 170, 819, 291
+};
+
+int verify_data[DATA_SIZE] =
+{
+    1,   4,   6,   9,  12,  17,  19,  33,  41,  49,  61,  62,  64,  65,  78,  79,  81,  86,  88,  92,
+   95, 100, 110, 111, 116, 119, 125, 132, 140, 141, 143, 150, 153, 169, 170, 181, 187, 195, 195, 203,
+  208, 210, 216, 222, 222, 224, 228, 229, 241, 241, 241, 253, 255, 258, 264, 267, 271, 272, 278, 280,
+  280, 285, 287, 288, 288, 289, 291, 296, 296, 311, 313, 314, 317, 319, 328, 332, 335, 337, 339, 346,
+  349, 350, 350, 351, 351, 357, 358, 358, 365, 367, 368, 375, 376, 382, 388, 389, 392, 396, 403, 403,
+  415, 416, 426, 430, 431, 436, 440, 441, 444, 446, 454, 455, 461, 474, 478, 479, 489, 494, 499, 500,
+  509, 511, 514, 517, 527, 531, 538, 539, 540, 543, 551, 553, 557, 557, 557, 559, 564, 564, 566, 569,
+  569, 572, 572, 576, 584, 584, 584, 587, 592, 592, 593, 598, 606, 606, 614, 615, 620, 621, 629, 643,
+  646, 646, 647, 648, 649, 649, 657, 657, 659, 666, 669, 676, 678, 678, 684, 693, 694, 696, 700, 701,
+  703, 704, 715, 720, 721, 740, 743, 745, 749, 750, 758, 759, 761, 774, 775, 778, 788, 796, 796, 799,
+  800, 801, 805, 808, 812, 814, 819, 826, 833, 847, 853, 853, 859, 864, 870, 875, 883, 886, 890, 891,
+  898, 902, 905, 908, 913, 925, 931, 933, 933, 936, 937, 938, 941, 944, 949, 952, 952, 960, 961, 971,
+  979, 979, 981, 985, 985, 989, 989, 997, 997, 998
+};
+
diff --git a/benchmarks/qsort/qsort_gendata.pl b/benchmarks/qsort/qsort_gendata.pl
new file mode 100755 (executable)
index 0000000..0a1af61
--- /dev/null
@@ -0,0 +1,132 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# qsort_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the qsort benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: qsort_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [250]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 250;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "int ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3d",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    push( @values, int(rand(999)) );
+  }
+  my @sorted = sort { $a <=> $b } @values;
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input_data", \@values );
+  printArray( "verify_data", \@sorted );
+
+}
+
+main();
+
diff --git a/benchmarks/qsort/qsort_main.c b/benchmarks/qsort/qsort_main.c
new file mode 100644 (file)
index 0000000..6de1613
--- /dev/null
@@ -0,0 +1,239 @@
+//**************************************************************************
+// Quicksort benchmark
+//--------------------------------------------------------------------------
+//
+// This benchmark uses quicksort to sort an array of integers. The
+// implementation is largely adapted from Numerical Recipes for C. The
+// input data (and reference data) should be generated using the
+// qsort_gendata.pl perl script and dumped to a file named
+// dataset1.h The smips-gcc toolchain does not support system calls
+// so printf's can only be used on a host system, not on the smips
+// processor simulator itself. You should not change anything except
+// the HOST_DEBUG and PREALLOCATE macros for your timing run.
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+// The INSERTION_THRESHOLD is the size of the subarray when the
+// algorithm switches to using an insertion sort instead of
+// quick sort.
+
+#define INSERTION_THRESHOLD 7
+
+// NSTACK is the required auxiliary storage.
+// It must be at least 2*lg(DATA_SIZE)
+
+#define NSTACK 50
+
+// Swap macro for swapping two values.
+
+#define SWAP(a,b) temp=(a);(a)=(b);(b)=temp;
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, int test[], int correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, int arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %3d ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// Quicksort function
+
+void sort( int n, int arr[] )
+{
+  int i,j,k;
+  int ir = n;
+  int l = 1;
+  int jstack = 0;
+  int a, temp;
+
+  int istack[NSTACK];
+
+  for (;;) {
+
+#if HOST_DEBUG
+    printArray( "", n, arr );
+#endif
+
+    // Insertion sort when subarray small enough.
+    if ( ir-l < INSERTION_THRESHOLD ) {
+
+      for ( j = l+1; j <= ir; j++ ) {
+        a = arr[j-1];
+        for ( i = j-1; i >= l; i-- ) {
+          if ( arr[i-1] <= a ) break;
+          arr[i] = arr[i-1];
+        }
+        arr[i] = a;
+      }
+
+      if ( jstack == 0 ) break;
+
+      // Pop stack and begin a new round of partitioning.
+      ir = istack[jstack--];
+      l = istack[jstack--];
+
+    }
+    else {
+
+      // Choose median of left, center, and right elements as
+      // partitioning element a. Also rearrange so that a[l-1] <= a[l] <= a[ir-].
+
+      k = (l+ir) >> 1;
+      SWAP(arr[k-1],arr[l])
+      if ( arr[l-1] > arr[ir-1] ) {
+        SWAP(arr[l-1],arr[ir-1])
+      }
+      if ( arr[l] > arr[ir-1] ) {
+        SWAP(arr[l],arr[ir-1])
+      }
+      if ( arr[l-1] > arr[l] ) {
+        SWAP(arr[l-1],arr[l])
+      }
+
+      // Initialize pointers for partitioning.
+      i = l+1;
+      j = ir;
+
+      // Partitioning element.
+      a = arr[l];
+
+      for (;;) {                       // Beginning of innermost loop.
+        do i++; while (arr[i-1] < a);  // Scan up to find element > a.
+        do j--; while (arr[j-1] > a);  // Scan down to find element < a.
+        if (j < i) break;              // Pointers crossed. Partitioning complete.
+        SWAP(arr[i-1],arr[j-1]);       // Exchange elements.
+      }                                // End of innermost loop.
+
+      // Insert partitioning element.
+      arr[l] = arr[j-1];
+      arr[j-1] = a;
+      jstack += 2;
+
+      // Push pointers to larger subarray on stack,
+      // process smaller subarray immediately.
+
+#if HOST_DEBUG
+      if ( jstack > NSTACK ) { printf("NSTACK too small in sort.\n"); exit(1); }
+#endif
+
+      if ( ir-i+1 >= j-l ) {
+        istack[jstack]   = ir;
+        istack[jstack-1] = i;
+        ir = j-1;
+      }
+      else {
+        istack[jstack]   = j-1;
+        istack[jstack-1] = l;
+        l = i;
+      }
+    }
+
+  }
+
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input", DATA_SIZE, input_data );
+  printArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+  sort( DATA_SIZE, input_data );
+#endif
+
+  // Do the sort
+
+  setStats(1);
+  sort( DATA_SIZE, input_data );
+  setStats(0);
+
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "test", DATA_SIZE, input_data );
+#endif
+
+  // Check the results
+
+  finishTest(verify( DATA_SIZE, input_data, verify_data ));
+
+}
diff --git a/benchmarks/readme.txt b/benchmarks/readme.txt
new file mode 100644 (file)
index 0000000..a14780f
--- /dev/null
@@ -0,0 +1,55 @@
+*************************************************************************
+Benchmarks for RISCV Processor
+-------------------------------------------------------------------------
+
+The benchmarks make use of the RISCV C compiler toolchain. You will need
+to include a bmark.mk makefile fragment in each benchmark directory. The
+fragment should include the object files and a rule to actually link
+these object files into an executable. There are a couple important
+points to make about the toolchain.
+
+ + The toolchain sets the stack pointer to memory address 0x20000 so your
+   main memory _must_ be larger than 0x20000 bytes or else the stack will
+   get wrapped around and overwrite program data.
+
+ + The stack grows down from 0x20000 and your program is loaded at 0x1000.
+   If you have a very large program and have lots of very big arrays
+   declared on the stack your stack could overwrite your program. Be aware.
+
+ + You cannot use standard clib functions (like memcopy or strcat). You
+   cannot use system calls and thus cannot use printf.
+
+ + You cannot access the simulated command line - ie you cannot use argc
+   and argv within main.
+
+ + You may have to increase the timeout check in your test harness to
+   allow longer programs to run (you can do this from the command line
+   option +max-cycles with the standard test harness)
+
+ + The compiler loads the program at 0x1000. It does not insert exception
+   setup code. So if you are careful with what C you use it will only
+   generate code in the riscv lab1 subset. If you use multiplies, shorts,
+   and chars it could generate mul, lh, and lb instructions. Be aware.
+
+ + You can write assembly in C - you need to do this to write tohost to 1
+   to indicate when the benchmark is done. Look at the example
+   benchmarks to see how this is done. You can find more information
+   about how to write assembly in C here:
+   http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
+
+ + If you look at the example benchmarks you will see that I have two
+   important macros HOST_DEBUG and VERIFY. Use HOST_DEBUG to compile the
+   benchmark on your host workstation (ie use standard gcc on Athena/Linux
+   box) and then debug the benchmark. Since you are using standard gcc you
+   can use printf's to make sure that your benchmark actually works before
+   trying it out on your RISCV processor.
+
+ + Debugging C compiled code on the RISCV processor is a real pain. It is
+   hard to associate the assembly with the C code and there is no
+   debugger. So if you encounter a bug in your processor when running a C
+   benchmark you can try to debug it, but you might have better luck
+   adding more assembly tests to your test suite.
+
+ + To avoid having the compiler try and use a global pointer (ie using
+   register 28 to point to a space where small global variables are
+   stored) you need to use the -G 0 command line option.
diff --git a/benchmarks/spmv/bmark.mk b/benchmarks/spmv/bmark.mk
new file mode 100644 (file)
index 0000000..5ab9cc0
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+spmv_c_src = \
+       spmv_main.c \
+
+spmv_riscv_src = \
+       crt.S \
+
+spmv_c_objs     = $(patsubst %.c, %.o, $(spmv_c_src))
+spmv_riscv_objs = $(patsubst %.S, %.o, $(spmv_riscv_src))
+
+spmv_host_bin = spmv.host
+$(spmv_host_bin) : $(spmv_c_src)
+       $(HOST_COMP) $^ -o $(spmv_host_bin)
+
+spmv_riscv_bin = spmv.riscv
+$(spmv_riscv_bin) : $(spmv_c_objs) $(spmv_riscv_objs)
+       $(RISCV_LINK) $(spmv_c_objs) $(spmv_riscv_objs) -o $(spmv_riscv_bin)
+
+junk += $(spmv_c_objs) $(spmv_riscv_objs) \
+        $(spmv_host_bin) $(spmv_riscv_bin)
diff --git a/benchmarks/spmv/dataset1.h b/benchmarks/spmv/dataset1.h
new file mode 100644 (file)
index 0000000..ebdf7ff
--- /dev/null
@@ -0,0 +1,23022 @@
+#define R 1000
+#define C 1000
+#define NNZ 10004
+const double val[10004] = {
+  658,
+  279,
+  587,
+  255,
+  359,
+  844,
+  905,
+  456,
+  897,
+  837,
+  652,
+  398,
+  885,
+  21,
+  669,
+  738,
+  365,
+  928,
+  713,
+  771,
+  536,
+  987,
+  917,
+  823,
+  544,
+  40,
+  80,
+  636,
+  263,
+  929,
+  757,
+  677,
+  151,
+  500,
+  875,
+  720,
+  205,
+  292,
+  859,
+  980,
+  97,
+  608,
+  813,
+  840,
+  397,
+  765,
+  294,
+  718,
+  751,
+  7,
+  482,
+  166,
+  653,
+  172,
+  187,
+  79,
+  228,
+  857,
+  540,
+  760,
+  509,
+  190,
+  396,
+  765,
+  37,
+  85,
+  866,
+  981,
+  999,
+  793,
+  921,
+  664,
+  208,
+  856,
+  528,
+  782,
+  318,
+  170,
+  521,
+  691,
+  726,
+  996,
+  947,
+  326,
+  825,
+  77,
+  823,
+  752,
+  266,
+  834,
+  196,
+  58,
+  430,
+  764,
+  807,
+  568,
+  665,
+  583,
+  178,
+  250,
+  273,
+  654,
+  487,
+  504,
+  729,
+  338,
+  866,
+  981,
+  852,
+  842,
+  785,
+  13,
+  588,
+  44,
+  432,
+  408,
+  374,
+  761,
+  653,
+  752,
+  684,
+  6,
+  357,
+  703,
+  447,
+  966,
+  457,
+  738,
+  646,
+  646,
+  217,
+  522,
+  839,
+  417,
+  506,
+  801,
+  233,
+  929,
+  487,
+  353,
+  660,
+  751,
+  738,
+  512,
+  566,
+  130,
+  61,
+  128,
+  698,
+  467,
+  362,
+  867,
+  639,
+  289,
+  371,
+  427,
+  650,
+  16,
+  878,
+  967,
+  369,
+  517,
+  161,
+  330,
+  294,
+  396,
+  606,
+  638,
+  171,
+  602,
+  531,
+  14,
+  968,
+  15,
+  193,
+  225,
+  863,
+  171,
+  254,
+  714,
+  256,
+  873,
+  353,
+  35,
+  910,
+  849,
+  658,
+  546,
+  389,
+  239,
+  355,
+  540,
+  494,
+  968,
+  319,
+  590,
+  608,
+  445,
+  806,
+  51,
+  117,
+  401,
+  314,
+  280,
+  334,
+  44,
+  17,
+  107,
+  108,
+  650,
+  807,
+  385,
+  748,
+  942,
+  719,
+  110,
+  630,
+  559,
+  717,
+  375,
+  963,
+  45,
+  403,
+  476,
+  408,
+  732,
+  87,
+  874,
+  635,
+  119,
+  190,
+  949,
+  777,
+  201,
+  503,
+  658,
+  777,
+  564,
+  830,
+  122,
+  929,
+  68,
+  11,
+  354,
+  395,
+  213,
+  766,
+  40,
+  995,
+  577,
+  514,
+  568,
+  56,
+  439,
+  91,
+  148,
+  612,
+  717,
+  157,
+  538,
+  682,
+  190,
+  571,
+  847,
+  275,
+  190,
+  824,
+  985,
+  29,
+  426,
+  173,
+  898,
+  297,
+  156,
+  936,
+  1,
+  455,
+  812,
+  173,
+  131,
+  376,
+  947,
+  596,
+  783,
+  800,
+  361,
+  798,
+  598,
+  710,
+  86,
+  149,
+  457,
+  129,
+  437,
+  352,
+  933,
+  320,
+  709,
+  167,
+  793,
+  46,
+  49,
+  305,
+  704,
+  577,
+  855,
+  336,
+  978,
+  206,
+  662,
+  230,
+  93,
+  898,
+  368,
+  422,
+  689,
+  351,
+  87,
+  465,
+  576,
+  33,
+  884,
+  675,
+  548,
+  116,
+  730,
+  385,
+  483,
+  340,
+  809,
+  938,
+  342,
+  576,
+  887,
+  479,
+  455,
+  820,
+  521,
+  320,
+  488,
+  506,
+  591,
+  901,
+  505,
+  525,
+  5,
+  133,
+  705,
+  561,
+  285,
+  95,
+  918,
+  410,
+  578,
+  347,
+  375,
+  735,
+  624,
+  491,
+  494,
+  931,
+  655,
+  819,
+  883,
+  328,
+  527,
+  194,
+  580,
+  584,
+  837,
+  700,
+  681,
+  249,
+  643,
+  958,
+  363,
+  316,
+  397,
+  638,
+  261,
+  459,
+  960,
+  636,
+  458,
+  84,
+  797,
+  696,
+  782,
+  831,
+  419,
+  393,
+  649,
+  312,
+  811,
+  703,
+  70,
+  688,
+  285,
+  39,
+  617,
+  935,
+  495,
+  392,
+  143,
+  734,
+  166,
+  406,
+  464,
+  732,
+  709,
+  379,
+  143,
+  527,
+  514,
+  709,
+  130,
+  965,
+  632,
+  448,
+  836,
+  62,
+  567,
+  600,
+  520,
+  519,
+  16,
+  394,
+  705,
+  438,
+  548,
+  696,
+  140,
+  573,
+  509,
+  968,
+  935,
+  165,
+  868,
+  577,
+  451,
+  865,
+  304,
+  777,
+  828,
+  147,
+  704,
+  821,
+  641,
+  783,
+  376,
+  757,
+  391,
+  170,
+  592,
+  235,
+  920,
+  846,
+  683,
+  249,
+  697,
+  253,
+  386,
+  244,
+  889,
+  607,
+  768,
+  88,
+  836,
+  259,
+  945,
+  33,
+  352,
+  70,
+  83,
+  996,
+  791,
+  18,
+  599,
+  488,
+  43,
+  582,
+  993,
+  692,
+  841,
+  558,
+  530,
+  350,
+  187,
+  295,
+  215,
+  869,
+  593,
+  385,
+  722,
+  724,
+  282,
+  681,
+  534,
+  788,
+  836,
+  378,
+  825,
+  93,
+  539,
+  120,
+  794,
+  384,
+  798,
+  505,
+  833,
+  27,
+  181,
+  951,
+  966,
+  498,
+  375,
+  22,
+  545,
+  62,
+  816,
+  119,
+  712,
+  813,
+  783,
+  655,
+  832,
+  143,
+  501,
+  519,
+  43,
+  760,
+  17,
+  896,
+  96,
+  390,
+  121,
+  458,
+  736,
+  649,
+  227,
+  778,
+  283,
+  657,
+  434,
+  214,
+  123,
+  929,
+  548,
+  206,
+  993,
+  463,
+  824,
+  369,
+  260,
+  868,
+  645,
+  857,
+  184,
+  198,
+  349,
+  652,
+  522,
+  23,
+  208,
+  968,
+  290,
+  770,
+  109,
+  978,
+  513,
+  298,
+  675,
+  306,
+  866,
+  927,
+  822,
+  495,
+  653,
+  134,
+  702,
+  147,
+  366,
+  947,
+  65,
+  586,
+  412,
+  638,
+  760,
+  541,
+  118,
+  551,
+  574,
+  85,
+  736,
+  999,
+  917,
+  478,
+  35,
+  629,
+  963,
+  898,
+  826,
+  113,
+  298,
+  606,
+  568,
+  152,
+  926,
+  277,
+  984,
+  549,
+  279,
+  839,
+  348,
+  672,
+  278,
+  94,
+  455,
+  590,
+  843,
+  85,
+  222,
+  901,
+  621,
+  30,
+  880,
+  914,
+  27,
+  974,
+  399,
+  873,
+  968,
+  870,
+  479,
+  696,
+  964,
+  929,
+  499,
+  121,
+  812,
+  933,
+  799,
+  506,
+  412,
+  712,
+  791,
+  426,
+  835,
+  488,
+  910,
+  522,
+  332,
+  967,
+  380,
+  61,
+  5,
+  282,
+  119,
+  22,
+  136,
+  436,
+  730,
+  341,
+  687,
+  371,
+  19,
+  893,
+  20,
+  327,
+  221,
+  221,
+  966,
+  354,
+  198,
+  985,
+  56,
+  305,
+  691,
+  980,
+  12,
+  790,
+  64,
+  484,
+  621,
+  214,
+  332,
+  898,
+  898,
+  318,
+  416,
+  445,
+  350,
+  317,
+  336,
+  714,
+  788,
+  541,
+  890,
+  42,
+  111,
+  596,
+  164,
+  424,
+  448,
+  666,
+  362,
+  429,
+  617,
+  910,
+  917,
+  970,
+  526,
+  321,
+  551,
+  481,
+  83,
+  46,
+  146,
+  569,
+  856,
+  85,
+  192,
+  724,
+  378,
+  299,
+  13,
+  422,
+  411,
+  552,
+  569,
+  100,
+  849,
+  484,
+  906,
+  47,
+  532,
+  742,
+  415,
+  228,
+  897,
+  715,
+  807,
+  329,
+  244,
+  312,
+  903,
+  758,
+  34,
+  172,
+  18,
+  917,
+  700,
+  108,
+  611,
+  567,
+  616,
+  572,
+  174,
+  925,
+  553,
+  903,
+  268,
+  544,
+  998,
+  708,
+  133,
+  717,
+  584,
+  517,
+  608,
+  680,
+  597,
+  316,
+  470,
+  764,
+  530,
+  221,
+  405,
+  133,
+  406,
+  506,
+  56,
+  458,
+  721,
+  935,
+  356,
+  130,
+  99,
+  395,
+  117,
+  34,
+  881,
+  231,
+  214,
+  248,
+  458,
+  246,
+  632,
+  471,
+  279,
+  385,
+  594,
+  855,
+  305,
+  30,
+  542,
+  144,
+  509,
+  548,
+  364,
+  171,
+  386,
+  382,
+  616,
+  997,
+  28,
+  361,
+  855,
+  449,
+  992,
+  956,
+  439,
+  569,
+  383,
+  523,
+  852,
+  337,
+  112,
+  24,
+  902,
+  352,
+  542,
+  231,
+  664,
+  411,
+  457,
+  572,
+  52,
+  760,
+  88,
+  907,
+  345,
+  284,
+  636,
+  219,
+  975,
+  713,
+  231,
+  888,
+  49,
+  624,
+  179,
+  579,
+  401,
+  694,
+  984,
+  905,
+  673,
+  414,
+  773,
+  165,
+  349,
+  436,
+  128,
+  186,
+  487,
+  17,
+  552,
+  833,
+  98,
+  424,
+  791,
+  220,
+  352,
+  75,
+  470,
+  405,
+  679,
+  939,
+  792,
+  653,
+  142,
+  226,
+  208,
+  629,
+  429,
+  55,
+  455,
+  362,
+  210,
+  765,
+  693,
+  113,
+  656,
+  824,
+  441,
+  191,
+  50,
+  957,
+  99,
+  27,
+  582,
+  461,
+  279,
+  299,
+  492,
+  678,
+  452,
+  640,
+  349,
+  758,
+  298,
+  903,
+  361,
+  333,
+  339,
+  60,
+  824,
+  773,
+  184,
+  621,
+  66,
+  49,
+  228,
+  608,
+  523,
+  591,
+  533,
+  234,
+  566,
+  291,
+  646,
+  93,
+  42,
+  810,
+  154,
+  846,
+  426,
+  32,
+  828,
+  360,
+  917,
+  182,
+  50,
+  40,
+  182,
+  19,
+  127,
+  614,
+  951,
+  662,
+  591,
+  140,
+  110,
+  685,
+  549,
+  6,
+  346,
+  766,
+  689,
+  743,
+  414,
+  135,
+  61,
+  548,
+  363,
+  915,
+  462,
+  526,
+  405,
+  524,
+  192,
+  754,
+  796,
+  616,
+  98,
+  341,
+  786,
+  778,
+  929,
+  6,
+  388,
+  293,
+  513,
+  148,
+  298,
+  311,
+  29,
+  456,
+  960,
+  560,
+  895,
+  121,
+  511,
+  141,
+  732,
+  762,
+  774,
+  261,
+  287,
+  314,
+  801,
+  320,
+  173,
+  616,
+  356,
+  783,
+  256,
+  129,
+  513,
+  212,
+  293,
+  168,
+  813,
+  279,
+  65,
+  784,
+  360,
+  921,
+  320,
+  177,
+  923,
+  385,
+  142,
+  380,
+  772,
+  929,
+  718,
+  277,
+  61,
+  620,
+  575,
+  772,
+  356,
+  414,
+  775,
+  392,
+  523,
+  760,
+  192,
+  905,
+  606,
+  134,
+  695,
+  784,
+  540,
+  63,
+  939,
+  941,
+  887,
+  217,
+  290,
+  893,
+  206,
+  662,
+  63,
+  102,
+  74,
+  943,
+  288,
+  8,
+  254,
+  131,
+  420,
+  841,
+  79,
+  139,
+  362,
+  221,
+  915,
+  6,
+  28,
+  417,
+  846,
+  996,
+  794,
+  522,
+  391,
+  513,
+  715,
+  87,
+  449,
+  801,
+  823,
+  16,
+  485,
+  874,
+  8,
+  601,
+  885,
+  146,
+  886,
+  318,
+  235,
+  390,
+  561,
+  869,
+  640,
+  860,
+  433,
+  651,
+  145,
+  149,
+  682,
+  612,
+  580,
+  946,
+  572,
+  155,
+  736,
+  898,
+  774,
+  81,
+  882,
+  286,
+  362,
+  982,
+  788,
+  658,
+  452,
+  889,
+  688,
+  384,
+  948,
+  342,
+  402,
+  777,
+  403,
+  547,
+  123,
+  187,
+  394,
+  470,
+  978,
+  234,
+  461,
+  127,
+  349,
+  476,
+  927,
+  837,
+  997,
+  494,
+  167,
+  920,
+  911,
+  84,
+  432,
+  339,
+  87,
+  841,
+  535,
+  972,
+  671,
+  395,
+  445,
+  681,
+  494,
+  737,
+  492,
+  96,
+  84,
+  261,
+  871,
+  91,
+  696,
+  960,
+  346,
+  430,
+  796,
+  326,
+  272,
+  982,
+  25,
+  927,
+  923,
+  528,
+  924,
+  215,
+  789,
+  691,
+  898,
+  811,
+  189,
+  284,
+  856,
+  200,
+  278,
+  436,
+  354,
+  114,
+  978,
+  648,
+  797,
+  437,
+  916,
+  220,
+  449,
+  740,
+  179,
+  484,
+  470,
+  332,
+  178,
+  65,
+  807,
+  860,
+  180,
+  421,
+  148,
+  563,
+  253,
+  691,
+  121,
+  837,
+  851,
+  341,
+  948,
+  563,
+  635,
+  780,
+  148,
+  567,
+  713,
+  118,
+  877,
+  505,
+  519,
+  975,
+  504,
+  745,
+  190,
+  958,
+  134,
+  898,
+  723,
+  546,
+  781,
+  46,
+  760,
+  530,
+  572,
+  163,
+  227,
+  886,
+  408,
+  586,
+  4,
+  901,
+  233,
+  753,
+  720,
+  203,
+  575,
+  748,
+  443,
+  207,
+  838,
+  492,
+  290,
+  223,
+  256,
+  715,
+  830,
+  432,
+  97,
+  99,
+  477,
+  725,
+  574,
+  91,
+  746,
+  731,
+  615,
+  629,
+  437,
+  320,
+  843,
+  559,
+  13,
+  902,
+  779,
+  564,
+  689,
+  207,
+  599,
+  726,
+  598,
+  606,
+  148,
+  58,
+  115,
+  536,
+  319,
+  279,
+  944,
+  485,
+  699,
+  948,
+  13,
+  895,
+  766,
+  582,
+  559,
+  998,
+  250,
+  788,
+  869,
+  877,
+  23,
+  647,
+  488,
+  164,
+  845,
+  344,
+  545,
+  307,
+  991,
+  0,
+  805,
+  152,
+  412,
+  534,
+  323,
+  614,
+  415,
+  865,
+  847,
+  210,
+  743,
+  122,
+  943,
+  594,
+  320,
+  268,
+  154,
+  253,
+  816,
+  347,
+  768,
+  953,
+  982,
+  606,
+  131,
+  813,
+  92,
+  339,
+  5,
+  707,
+  517,
+  526,
+  469,
+  537,
+  89,
+  141,
+  537,
+  557,
+  190,
+  659,
+  87,
+  659,
+  401,
+  367,
+  414,
+  460,
+  34,
+  96,
+  895,
+  740,
+  694,
+  352,
+  537,
+  592,
+  877,
+  137,
+  922,
+  915,
+  99,
+  216,
+  969,
+  716,
+  44,
+  869,
+  856,
+  853,
+  352,
+  556,
+  216,
+  426,
+  231,
+  259,
+  172,
+  67,
+  694,
+  488,
+  311,
+  712,
+  767,
+  279,
+  962,
+  265,
+  615,
+  141,
+  454,
+  711,
+  384,
+  452,
+  135,
+  90,
+  391,
+  787,
+  665,
+  528,
+  296,
+  824,
+  820,
+  455,
+  885,
+  301,
+  155,
+  647,
+  6,
+  973,
+  627,
+  663,
+  922,
+  969,
+  799,
+  698,
+  523,
+  404,
+  784,
+  422,
+  128,
+  103,
+  233,
+  601,
+  812,
+  281,
+  600,
+  336,
+  11,
+  743,
+  288,
+  925,
+  181,
+  228,
+  508,
+  308,
+  3,
+  141,
+  711,
+  602,
+  71,
+  868,
+  255,
+  307,
+  24,
+  862,
+  567,
+  134,
+  74,
+  755,
+  947,
+  111,
+  812,
+  42,
+  295,
+  650,
+  859,
+  78,
+  128,
+  462,
+  308,
+  290,
+  372,
+  166,
+  111,
+  364,
+  469,
+  591,
+  127,
+  56,
+  840,
+  758,
+  781,
+  756,
+  548,
+  658,
+  412,
+  851,
+  134,
+  233,
+  432,
+  257,
+  138,
+  210,
+  184,
+  986,
+  51,
+  806,
+  442,
+  711,
+  243,
+  571,
+  861,
+  550,
+  111,
+  798,
+  138,
+  316,
+  746,
+  549,
+  276,
+  458,
+  866,
+  335,
+  334,
+  178,
+  191,
+  473,
+  452,
+  764,
+  487,
+  525,
+  273,
+  457,
+  902,
+  888,
+  519,
+  203,
+  891,
+  497,
+  998,
+  535,
+  382,
+  673,
+  787,
+  112,
+  846,
+  836,
+  898,
+  681,
+  607,
+  546,
+  863,
+  639,
+  896,
+  281,
+  845,
+  305,
+  410,
+  835,
+  985,
+  245,
+  781,
+  208,
+  337,
+  248,
+  205,
+  264,
+  198,
+  305,
+  665,
+  351,
+  609,
+  186,
+  444,
+  589,
+  130,
+  292,
+  668,
+  617,
+  611,
+  111,
+  80,
+  9,
+  267,
+  275,
+  135,
+  201,
+  926,
+  789,
+  835,
+  221,
+  290,
+  297,
+  93,
+  437,
+  892,
+  921,
+  994,
+  748,
+  321,
+  23,
+  394,
+  725,
+  377,
+  581,
+  57,
+  219,
+  461,
+  54,
+  183,
+  506,
+  889,
+  920,
+  714,
+  639,
+  836,
+  585,
+  787,
+  929,
+  597,
+  307,
+  678,
+  35,
+  296,
+  46,
+  459,
+  368,
+  342,
+  200,
+  609,
+  265,
+  11,
+  315,
+  10,
+  29,
+  32,
+  339,
+  250,
+  974,
+  736,
+  834,
+  281,
+  332,
+  656,
+  530,
+  384,
+  96,
+  544,
+  775,
+  208,
+  375,
+  230,
+  31,
+  589,
+  385,
+  130,
+  718,
+  82,
+  909,
+  267,
+  482,
+  503,
+  875,
+  824,
+  488,
+  837,
+  757,
+  19,
+  121,
+  129,
+  531,
+  712,
+  76,
+  183,
+  137,
+  764,
+  617,
+  846,
+  64,
+  65,
+  775,
+  593,
+  526,
+  53,
+  923,
+  142,
+  330,
+  153,
+  199,
+  71,
+  584,
+  423,
+  770,
+  318,
+  965,
+  493,
+  953,
+  238,
+  416,
+  471,
+  978,
+  436,
+  501,
+  505,
+  264,
+  789,
+  199,
+  241,
+  800,
+  168,
+  34,
+  291,
+  399,
+  972,
+  890,
+  462,
+  670,
+  628,
+  19,
+  204,
+  99,
+  751,
+  742,
+  231,
+  397,
+  5,
+  204,
+  886,
+  763,
+  706,
+  218,
+  775,
+  730,
+  231,
+  425,
+  118,
+  778,
+  886,
+  537,
+  364,
+  691,
+  19,
+  114,
+  195,
+  665,
+  675,
+  359,
+  653,
+  185,
+  76,
+  351,
+  221,
+  695,
+  147,
+  1,
+  109,
+  790,
+  749,
+  299,
+  358,
+  11,
+  581,
+  511,
+  614,
+  950,
+  916,
+  923,
+  764,
+  245,
+  487,
+  508,
+  471,
+  71,
+  482,
+  614,
+  660,
+  834,
+  875,
+  433,
+  470,
+  650,
+  753,
+  828,
+  360,
+  551,
+  946,
+  215,
+  358,
+  689,
+  468,
+  280,
+  98,
+  363,
+  451,
+  20,
+  842,
+  913,
+  105,
+  575,
+  798,
+  199,
+  612,
+  778,
+  959,
+  295,
+  322,
+  760,
+  963,
+  854,
+  191,
+  629,
+  165,
+  420,
+  127,
+  515,
+  858,
+  783,
+  487,
+  499,
+  534,
+  451,
+  373,
+  116,
+  973,
+  576,
+  184,
+  587,
+  765,
+  975,
+  945,
+  960,
+  801,
+  802,
+  793,
+  32,
+  608,
+  312,
+  533,
+  916,
+  92,
+  625,
+  661,
+  374,
+  967,
+  332,
+  554,
+  259,
+  838,
+  475,
+  765,
+  833,
+  74,
+  39,
+  780,
+  446,
+  132,
+  270,
+  583,
+  378,
+  677,
+  805,
+  921,
+  723,
+  624,
+  67,
+  434,
+  875,
+  847,
+  149,
+  881,
+  104,
+  729,
+  327,
+  239,
+  791,
+  22,
+  717,
+  647,
+  118,
+  353,
+  791,
+  129,
+  253,
+  60,
+  938,
+  533,
+  408,
+  994,
+  849,
+  789,
+  764,
+  797,
+  687,
+  892,
+  203,
+  880,
+  903,
+  946,
+  294,
+  830,
+  698,
+  297,
+  478,
+  305,
+  452,
+  258,
+  30,
+  799,
+  756,
+  793,
+  937,
+  775,
+  14,
+  383,
+  276,
+  481,
+  215,
+  317,
+  879,
+  52,
+  628,
+  654,
+  429,
+  753,
+  848,
+  606,
+  629,
+  748,
+  832,
+  335,
+  733,
+  90,
+  396,
+  690,
+  482,
+  54,
+  12,
+  306,
+  535,
+  750,
+  116,
+  524,
+  383,
+  475,
+  214,
+  178,
+  784,
+  798,
+  563,
+  935,
+  806,
+  949,
+  53,
+  694,
+  273,
+  124,
+  284,
+  619,
+  45,
+  521,
+  715,
+  851,
+  132,
+  424,
+  438,
+  319,
+  538,
+  981,
+  802,
+  986,
+  340,
+  600,
+  353,
+  980,
+  637,
+  505,
+  17,
+  280,
+  855,
+  237,
+  432,
+  184,
+  955,
+  538,
+  935,
+  480,
+  421,
+  580,
+  423,
+  928,
+  926,
+  930,
+  732,
+  210,
+  351,
+  346,
+  469,
+  100,
+  288,
+  353,
+  788,
+  232,
+  130,
+  79,
+  360,
+  870,
+  439,
+  47,
+  661,
+  595,
+  636,
+  52,
+  389,
+  986,
+  159,
+  454,
+  317,
+  961,
+  915,
+  76,
+  342,
+  895,
+  53,
+  396,
+  15,
+  66,
+  139,
+  310,
+  636,
+  549,
+  440,
+  926,
+  132,
+  734,
+  726,
+  696,
+  332,
+  229,
+  896,
+  486,
+  316,
+  840,
+  403,
+  557,
+  963,
+  67,
+  401,
+  318,
+  13,
+  109,
+  745,
+  296,
+  653,
+  711,
+  718,
+  2,
+  951,
+  853,
+  130,
+  22,
+  879,
+  878,
+  759,
+  466,
+  520,
+  25,
+  403,
+  952,
+  914,
+  29,
+  133,
+  156,
+  467,
+  435,
+  896,
+  78,
+  488,
+  55,
+  739,
+  861,
+  521,
+  904,
+  498,
+  748,
+  703,
+  489,
+  21,
+  377,
+  322,
+  248,
+  818,
+  176,
+  531,
+  564,
+  1,
+  694,
+  362,
+  876,
+  165,
+  881,
+  325,
+  475,
+  810,
+  181,
+  30,
+  455,
+  255,
+  673,
+  320,
+  600,
+  602,
+  568,
+  974,
+  350,
+  826,
+  212,
+  504,
+  91,
+  21,
+  317,
+  275,
+  775,
+  422,
+  278,
+  795,
+  826,
+  818,
+  377,
+  295,
+  165,
+  496,
+  753,
+  425,
+  554,
+  243,
+  964,
+  169,
+  281,
+  109,
+  884,
+  334,
+  692,
+  641,
+  411,
+  352,
+  66,
+  765,
+  196,
+  508,
+  696,
+  866,
+  369,
+  725,
+  838,
+  82,
+  62,
+  300,
+  637,
+  29,
+  108,
+  859,
+  222,
+  768,
+  442,
+  891,
+  38,
+  523,
+  158,
+  856,
+  949,
+  852,
+  145,
+  630,
+  686,
+  109,
+  577,
+  371,
+  673,
+  807,
+  224,
+  169,
+  148,
+  890,
+  329,
+  653,
+  720,
+  898,
+  771,
+  65,
+  712,
+  735,
+  606,
+  578,
+  836,
+  17,
+  498,
+  31,
+  275,
+  54,
+  494,
+  831,
+  255,
+  266,
+  574,
+  693,
+  418,
+  226,
+  351,
+  867,
+  287,
+  717,
+  708,
+  104,
+  131,
+  863,
+  474,
+  600,
+  323,
+  235,
+  80,
+  710,
+  719,
+  924,
+  168,
+  168,
+  979,
+  24,
+  755,
+  935,
+  78,
+  386,
+  41,
+  546,
+  155,
+  306,
+  366,
+  814,
+  445,
+  883,
+  504,
+  332,
+  920,
+  265,
+  484,
+  591,
+  98,
+  981,
+  576,
+  392,
+  905,
+  927,
+  715,
+  264,
+  598,
+  847,
+  753,
+  329,
+  350,
+  983,
+  179,
+  993,
+  810,
+  809,
+  155,
+  508,
+  564,
+  896,
+  733,
+  734,
+  714,
+  637,
+  560,
+  186,
+  751,
+  601,
+  636,
+  361,
+  916,
+  10,
+  542,
+  258,
+  286,
+  756,
+  471,
+  858,
+  97,
+  373,
+  699,
+  1,
+  707,
+  260,
+  900,
+  145,
+  979,
+  143,
+  487,
+  427,
+  863,
+  472,
+  638,
+  672,
+  309,
+  980,
+  332,
+  480,
+  26,
+  184,
+  40,
+  723,
+  102,
+  856,
+  785,
+  298,
+  816,
+  525,
+  160,
+  897,
+  421,
+  697,
+  122,
+  571,
+  372,
+  138,
+  892,
+  370,
+  805,
+  754,
+  113,
+  993,
+  448,
+  471,
+  423,
+  96,
+  331,
+  419,
+  144,
+  172,
+  987,
+  170,
+  788,
+  400,
+  346,
+  139,
+  676,
+  380,
+  257,
+  350,
+  89,
+  592,
+  501,
+  664,
+  19,
+  957,
+  462,
+  302,
+  430,
+  880,
+  869,
+  99,
+  70,
+  356,
+  931,
+  751,
+  43,
+  531,
+  790,
+  559,
+  455,
+  64,
+  846,
+  139,
+  685,
+  876,
+  166,
+  361,
+  28,
+  876,
+  223,
+  147,
+  928,
+  619,
+  734,
+  870,
+  738,
+  393,
+  293,
+  722,
+  301,
+  936,
+  566,
+  57,
+  881,
+  398,
+  796,
+  134,
+  566,
+  932,
+  756,
+  860,
+  638,
+  546,
+  33,
+  144,
+  29,
+  628,
+  254,
+  764,
+  604,
+  357,
+  987,
+  552,
+  400,
+  663,
+  874,
+  727,
+  586,
+  988,
+  684,
+  867,
+  343,
+  733,
+  349,
+  534,
+  976,
+  708,
+  998,
+  871,
+  564,
+  271,
+  105,
+  397,
+  40,
+  884,
+  62,
+  43,
+  361,
+  451,
+  188,
+  520,
+  953,
+  709,
+  796,
+  522,
+  365,
+  263,
+  807,
+  14,
+  439,
+  395,
+  800,
+  614,
+  831,
+  675,
+  532,
+  95,
+  332,
+  538,
+  318,
+  526,
+  1,
+  689,
+  111,
+  487,
+  370,
+  203,
+  211,
+  642,
+  549,
+  158,
+  206,
+  298,
+  846,
+  87,
+  717,
+  363,
+  83,
+  200,
+  769,
+  504,
+  670,
+  536,
+  349,
+  294,
+  441,
+  239,
+  721,
+  400,
+  355,
+  212,
+  120,
+  623,
+  664,
+  94,
+  116,
+  126,
+  904,
+  947,
+  938,
+  152,
+  542,
+  464,
+  735,
+  926,
+  112,
+  590,
+  1,
+  209,
+  102,
+  237,
+  258,
+  552,
+  427,
+  808,
+  319,
+  631,
+  769,
+  884,
+  24,
+  132,
+  697,
+  878,
+  344,
+  335,
+  391,
+  384,
+  27,
+  533,
+  900,
+  96,
+  279,
+  121,
+  998,
+  558,
+  987,
+  848,
+  426,
+  191,
+  925,
+  623,
+  850,
+  163,
+  184,
+  819,
+  881,
+  279,
+  850,
+  517,
+  178,
+  727,
+  603,
+  152,
+  657,
+  412,
+  17,
+  120,
+  241,
+  718,
+  785,
+  921,
+  237,
+  982,
+  936,
+  745,
+  810,
+  507,
+  207,
+  267,
+  17,
+  967,
+  133,
+  73,
+  627,
+  20,
+  158,
+  69,
+  829,
+  769,
+  457,
+  436,
+  986,
+  723,
+  248,
+  784,
+  704,
+  146,
+  408,
+  0,
+  170,
+  209,
+  720,
+  958,
+  149,
+  321,
+  919,
+  924,
+  223,
+  35,
+  326,
+  196,
+  513,
+  992,
+  884,
+  467,
+  877,
+  695,
+  432,
+  281,
+  722,
+  633,
+  209,
+  616,
+  140,
+  93,
+  274,
+  31,
+  401,
+  971,
+  177,
+  946,
+  782,
+  271,
+  934,
+  159,
+  416,
+  861,
+  9,
+  607,
+  415,
+  747,
+  444,
+  487,
+  701,
+  191,
+  88,
+  850,
+  580,
+  93,
+  59,
+  309,
+  477,
+  613,
+  974,
+  126,
+  348,
+  256,
+  573,
+  578,
+  865,
+  805,
+  280,
+  90,
+  858,
+  924,
+  455,
+  681,
+  307,
+  581,
+  714,
+  156,
+  224,
+  534,
+  198,
+  63,
+  489,
+  144,
+  123,
+  288,
+  500,
+  221,
+  618,
+  674,
+  233,
+  440,
+  788,
+  569,
+  70,
+  472,
+  166,
+  12,
+  979,
+  722,
+  929,
+  108,
+  736,
+  666,
+  525,
+  631,
+  554,
+  287,
+  742,
+  65,
+  324,
+  248,
+  710,
+  489,
+  834,
+  199,
+  338,
+  851,
+  793,
+  960,
+  761,
+  383,
+  891,
+  973,
+  943,
+  853,
+  422,
+  178,
+  600,
+  890,
+  732,
+  384,
+  431,
+  476,
+  237,
+  104,
+  622,
+  839,
+  904,
+  805,
+  512,
+  57,
+  17,
+  630,
+  378,
+  32,
+  996,
+  247,
+  209,
+  254,
+  119,
+  396,
+  565,
+  630,
+  782,
+  633,
+  138,
+  318,
+  112,
+  545,
+  743,
+  616,
+  663,
+  89,
+  367,
+  495,
+  845,
+  127,
+  597,
+  434,
+  129,
+  692,
+  109,
+  168,
+  953,
+  668,
+  590,
+  177,
+  578,
+  46,
+  707,
+  413,
+  115,
+  788,
+  513,
+  243,
+  935,
+  953,
+  58,
+  584,
+  64,
+  569,
+  367,
+  978,
+  249,
+  290,
+  125,
+  183,
+  852,
+  485,
+  847,
+  895,
+  835,
+  25,
+  289,
+  995,
+  226,
+  156,
+  980,
+  520,
+  656,
+  255,
+  37,
+  852,
+  719,
+  493,
+  473,
+  900,
+  417,
+  647,
+  363,
+  759,
+  778,
+  735,
+  349,
+  627,
+  525,
+  255,
+  13,
+  58,
+  399,
+  222,
+  70,
+  304,
+  663,
+  158,
+  152,
+  788,
+  103,
+  693,
+  274,
+  873,
+  116,
+  837,
+  876,
+  367,
+  272,
+  778,
+  65,
+  363,
+  625,
+  696,
+  809,
+  16,
+  491,
+  615,
+  196,
+  88,
+  0,
+  204,
+  418,
+  203,
+  952,
+  205,
+  240,
+  962,
+  899,
+  872,
+  222,
+  961,
+  363,
+  920,
+  659,
+  935,
+  943,
+  198,
+  385,
+  475,
+  298,
+  936,
+  22,
+  204,
+  947,
+  776,
+  911,
+  581,
+  661,
+  340,
+  433,
+  188,
+  622,
+  117,
+  154,
+  150,
+  388,
+  214,
+  513,
+  625,
+  875,
+  779,
+  262,
+  972,
+  396,
+  803,
+  396,
+  991,
+  976,
+  900,
+  387,
+  371,
+  522,
+  162,
+  234,
+  733,
+  314,
+  331,
+  666,
+  44,
+  205,
+  66,
+  422,
+  780,
+  978,
+  661,
+  775,
+  647,
+  511,
+  670,
+  515,
+  88,
+  714,
+  579,
+  133,
+  499,
+  837,
+  506,
+  904,
+  172,
+  248,
+  476,
+  836,
+  898,
+  514,
+  396,
+  852,
+  568,
+  706,
+  533,
+  54,
+  72,
+  167,
+  493,
+  809,
+  588,
+  792,
+  34,
+  325,
+  827,
+  878,
+  440,
+  708,
+  348,
+  589,
+  708,
+  271,
+  577,
+  857,
+  999,
+  547,
+  579,
+  502,
+  298,
+  330,
+  790,
+  687,
+  99,
+  245,
+  721,
+  264,
+  826,
+  487,
+  501,
+  783,
+  194,
+  469,
+  991,
+  653,
+  87,
+  946,
+  556,
+  707,
+  104,
+  879,
+  160,
+  15,
+  1,
+  95,
+  323,
+  870,
+  521,
+  897,
+  840,
+  699,
+  410,
+  751,
+  42,
+  342,
+  802,
+  547,
+  862,
+  168,
+  5,
+  561,
+  488,
+  170,
+  237,
+  655,
+  179,
+  909,
+  847,
+  536,
+  360,
+  44,
+  371,
+  9,
+  473,
+  253,
+  400,
+  563,
+  683,
+  471,
+  625,
+  823,
+  414,
+  590,
+  312,
+  407,
+  971,
+  929,
+  614,
+  705,
+  249,
+  69,
+  348,
+  527,
+  915,
+  978,
+  728,
+  593,
+  641,
+  627,
+  144,
+  653,
+  818,
+  763,
+  116,
+  676,
+  611,
+  451,
+  203,
+  589,
+  62,
+  984,
+  165,
+  631,
+  42,
+  873,
+  56,
+  256,
+  459,
+  134,
+  722,
+  235,
+  798,
+  291,
+  977,
+  646,
+  36,
+  156,
+  546,
+  113,
+  96,
+  964,
+  156,
+  570,
+  366,
+  718,
+  816,
+  726,
+  385,
+  188,
+  184,
+  154,
+  921,
+  821,
+  329,
+  928,
+  176,
+  688,
+  942,
+  204,
+  240,
+  423,
+  498,
+  422,
+  115,
+  696,
+  1,
+  850,
+  309,
+  733,
+  628,
+  595,
+  930,
+  467,
+  888,
+  638,
+  448,
+  895,
+  10,
+  938,
+  848,
+  116,
+  193,
+  390,
+  415,
+  330,
+  359,
+  115,
+  371,
+  432,
+  229,
+  264,
+  141,
+  162,
+  491,
+  397,
+  2,
+  141,
+  761,
+  471,
+  68,
+  55,
+  628,
+  593,
+  891,
+  84,
+  808,
+  740,
+  196,
+  196,
+  511,
+  901,
+  324,
+  464,
+  627,
+  461,
+  900,
+  995,
+  118,
+  486,
+  960,
+  709,
+  451,
+  432,
+  997,
+  785,
+  480,
+  20,
+  351,
+  25,
+  955,
+  40,
+  788,
+  56,
+  254,
+  329,
+  601,
+  293,
+  704,
+  639,
+  743,
+  983,
+  177,
+  722,
+  193,
+  708,
+  34,
+  202,
+  364,
+  404,
+  487,
+  436,
+  867,
+  906,
+  442,
+  472,
+  718,
+  610,
+  366,
+  991,
+  639,
+  821,
+  604,
+  618,
+  538,
+  266,
+  781,
+  958,
+  542,
+  744,
+  116,
+  604,
+  835,
+  310,
+  847,
+  277,
+  138,
+  979,
+  930,
+  962,
+  3,
+  641,
+  976,
+  673,
+  928,
+  851,
+  456,
+  963,
+  604,
+  336,
+  360,
+  467,
+  374,
+  536,
+  56,
+  729,
+  272,
+  563,
+  205,
+  301,
+  583,
+  329,
+  632,
+  151,
+  678,
+  100,
+  234,
+  74,
+  315,
+  289,
+  759,
+  313,
+  854,
+  558,
+  997,
+  905,
+  186,
+  261,
+  863,
+  607,
+  41,
+  70,
+  234,
+  147,
+  448,
+  619,
+  179,
+  65,
+  716,
+  309,
+  858,
+  408,
+  143,
+  61,
+  760,
+  308,
+  115,
+  116,
+  233,
+  598,
+  170,
+  675,
+  117,
+  147,
+  511,
+  935,
+  857,
+  761,
+  397,
+  692,
+  940,
+  606,
+  235,
+  50,
+  297,
+  219,
+  216,
+  501,
+  489,
+  22,
+  792,
+  878,
+  722,
+  293,
+  667,
+  71,
+  663,
+  870,
+  294,
+  596,
+  885,
+  140,
+  169,
+  325,
+  8,
+  107,
+  780,
+  536,
+  320,
+  652,
+  975,
+  155,
+  371,
+  901,
+  716,
+  175,
+  240,
+  296,
+  355,
+  416,
+  277,
+  187,
+  178,
+  977,
+  254,
+  679,
+  799,
+  428,
+  123,
+  66,
+  195,
+  143,
+  700,
+  648,
+  653,
+  570,
+  363,
+  942,
+  352,
+  981,
+  175,
+  815,
+  618,
+  479,
+  760,
+  663,
+  298,
+  944,
+  716,
+  925,
+  796,
+  312,
+  509,
+  365,
+  165,
+  945,
+  52,
+  787,
+  270,
+  663,
+  358,
+  452,
+  103,
+  809,
+  345,
+  62,
+  545,
+  863,
+  116,
+  952,
+  951,
+  810,
+  297,
+  884,
+  386,
+  683,
+  991,
+  161,
+  48,
+  267,
+  672,
+  558,
+  977,
+  2,
+  827,
+  848,
+  293,
+  860,
+  247,
+  564,
+  141,
+  285,
+  134,
+  736,
+  604,
+  789,
+  441,
+  723,
+  714,
+  911,
+  957,
+  597,
+  510,
+  547,
+  274,
+  761,
+  684,
+  747,
+  652,
+  536,
+  114,
+  555,
+  176,
+  743,
+  923,
+  442,
+  629,
+  984,
+  703,
+  957,
+  620,
+  822,
+  47,
+  186,
+  669,
+  17,
+  168,
+  377,
+  271,
+  562,
+  420,
+  799,
+  820,
+  73,
+  439,
+  884,
+  919,
+  306,
+  164,
+  749,
+  123,
+  830,
+  461,
+  452,
+  353,
+  589,
+  305,
+  907,
+  949,
+  288,
+  733,
+  975,
+  454,
+  821,
+  394,
+  329,
+  776,
+  69,
+  134,
+  808,
+  888,
+  663,
+  594,
+  378,
+  691,
+  175,
+  951,
+  234,
+  635,
+  969,
+  838,
+  443,
+  447,
+  399,
+  563,
+  442,
+  750,
+  523,
+  909,
+  889,
+  768,
+  390,
+  61,
+  896,
+  865,
+  534,
+  72,
+  558,
+  267,
+  678,
+  930,
+  662,
+  655,
+  15,
+  153,
+  885,
+  631,
+  724,
+  475,
+  919,
+  691,
+  260,
+  925,
+  49,
+  798,
+  761,
+  314,
+  497,
+  116,
+  789,
+  548,
+  1,
+  258,
+  388,
+  137,
+  467,
+  706,
+  580,
+  717,
+  110,
+  290,
+  513,
+  408,
+  639,
+  72,
+  629,
+  772,
+  67,
+  460,
+  612,
+  46,
+  88,
+  330,
+  790,
+  854,
+  708,
+  610,
+  334,
+  180,
+  901,
+  718,
+  647,
+  281,
+  135,
+  80,
+  583,
+  591,
+  828,
+  405,
+  843,
+  30,
+  709,
+  657,
+  329,
+  53,
+  351,
+  336,
+  445,
+  249,
+  761,
+  14,
+  187,
+  628,
+  154,
+  381,
+  915,
+  589,
+  911,
+  849,
+  515,
+  39,
+  58,
+  17,
+  790,
+  825,
+  446,
+  99,
+  674,
+  155,
+  407,
+  324,
+  888,
+  447,
+  662,
+  324,
+  588,
+  659,
+  898,
+  234,
+  12,
+  418,
+  514,
+  833,
+  149,
+  241,
+  655,
+  350,
+  256,
+  869,
+  127,
+  629,
+  236,
+  334,
+  940,
+  175,
+  685,
+  224,
+  243,
+  866,
+  979,
+  495,
+  375,
+  525,
+  869,
+  524,
+  894,
+  919,
+  4,
+  184,
+  348,
+  75,
+  892,
+  379,
+  899,
+  177,
+  709,
+  762,
+  356,
+  612,
+  992,
+  723,
+  47,
+  227,
+  317,
+  542,
+  703,
+  279,
+  969,
+  946,
+  473,
+  208,
+  60,
+  872,
+  674,
+  116,
+  360,
+  616,
+  976,
+  253,
+  862,
+  119,
+  649,
+  710,
+  851,
+  690,
+  448,
+  714,
+  152,
+  489,
+  62,
+  833,
+  207,
+  594,
+  100,
+  375,
+  9,
+  497,
+  111,
+  442,
+  116,
+  818,
+  749,
+  177,
+  898,
+  403,
+  243,
+  228,
+  741,
+  680,
+  393,
+  292,
+  726,
+  628,
+  149,
+  127,
+  525,
+  320,
+  404,
+  831,
+  842,
+  852,
+  367,
+  849,
+  66,
+  448,
+  978,
+  941,
+  165,
+  565,
+  960,
+  631,
+  220,
+  220,
+  154,
+  584,
+  841,
+  386,
+  582,
+  233,
+  22,
+  608,
+  508,
+  454,
+  503,
+  267,
+  660,
+  899,
+  404,
+  660,
+  451,
+  86,
+  966,
+  694,
+  133,
+  320,
+  811,
+  966,
+  556,
+  377,
+  653,
+  244,
+  718,
+  255,
+  748,
+  6,
+  237,
+  11,
+  668,
+  411,
+  351,
+  360,
+  833,
+  91,
+  414,
+  264,
+  447,
+  816,
+  962,
+  197,
+  774,
+  504,
+  426,
+  161,
+  42,
+  714,
+  130,
+  699,
+  64,
+  307,
+  15,
+  719,
+  917,
+  452,
+  573,
+  184,
+  297,
+  10,
+  249,
+  628,
+  440,
+  761,
+  170,
+  588,
+  537,
+  318,
+  130,
+  207,
+  376,
+  696,
+  203,
+  202,
+  790,
+  737,
+  133,
+  966,
+  24,
+  127,
+  820,
+  109,
+  53,
+  185,
+  38,
+  946,
+  96,
+  352,
+  529,
+  349,
+  678,
+  309,
+  51,
+  680,
+  881,
+  489,
+  940,
+  962,
+  163,
+  900,
+  797,
+  461,
+  431,
+  973,
+  204,
+  597,
+  681,
+  483,
+  903,
+  351,
+  885,
+  646,
+  358,
+  891,
+  564,
+  405,
+  989,
+  656,
+  628,
+  749,
+  23,
+  243,
+  407,
+  178,
+  22,
+  132,
+  883,
+  365,
+  471,
+  941,
+  762,
+  226,
+  403,
+  87,
+  231,
+  589,
+  543,
+  346,
+  737,
+  817,
+  261,
+  857,
+  869,
+  996,
+  27,
+  280,
+  595,
+  538,
+  113,
+  628,
+  587,
+  677,
+  641,
+  421,
+  176,
+  262,
+  399,
+  786,
+  970,
+  330,
+  936,
+  633,
+  690,
+  156,
+  855,
+  313,
+  550,
+  707,
+  201,
+  910,
+  556,
+  248,
+  34,
+  432,
+  547,
+  622,
+  737,
+  233,
+  941,
+  694,
+  526,
+  409,
+  458,
+  133,
+  900,
+  248,
+  670,
+  109,
+  802,
+  295,
+  233,
+  117,
+  923,
+  139,
+  855,
+  382,
+  757,
+  399,
+  462,
+  115,
+  447,
+  444,
+  53,
+  235,
+  163,
+  232,
+  333,
+  335,
+  219,
+  625,
+  95,
+  674,
+  879,
+  204,
+  460,
+  370,
+  829,
+  943,
+  420,
+  10,
+  538,
+  863,
+  694,
+  537,
+  124,
+  406,
+  294,
+  131,
+  306,
+  420,
+  12,
+  385,
+  107,
+  33,
+  153,
+  815,
+  899,
+  989,
+  845,
+  875,
+  772,
+  172,
+  308,
+  285,
+  1,
+  721,
+  487,
+  495,
+  310,
+  222,
+  950,
+  874,
+  211,
+  837,
+  723,
+  834,
+  407,
+  327,
+  658,
+  647,
+  1,
+  278,
+  524,
+  266,
+  906,
+  312,
+  955,
+  632,
+  631,
+  515,
+  440,
+  334,
+  122,
+  559,
+  72,
+  785,
+  431,
+  621,
+  61,
+  584,
+  588,
+  594,
+  16,
+  217,
+  50,
+  831,
+  188,
+  52,
+  393,
+  993,
+  495,
+  848,
+  480,
+  456,
+  370,
+  424,
+  777,
+  718,
+  39,
+  186,
+  466,
+  773,
+  185,
+  508,
+  464,
+  989,
+  135,
+  971,
+  470,
+  682,
+  443,
+  97,
+  124,
+  838,
+  135,
+  186,
+  427,
+  544,
+  719,
+  411,
+  244,
+  64,
+  273,
+  568,
+  160,
+  173,
+  273,
+  185,
+  826,
+  238,
+  841,
+  840,
+  553,
+  33,
+  758,
+  873,
+  162,
+  707,
+  158,
+  166,
+  714,
+  461,
+  573,
+  566,
+  256,
+  903,
+  798,
+  242,
+  561,
+  763,
+  334,
+  164,
+  781,
+  73,
+  309,
+  228,
+  71,
+  643,
+  774,
+  672,
+  507,
+  676,
+  406,
+  695,
+  623,
+  993,
+  729,
+  898,
+  324,
+  420,
+  903,
+  599,
+  622,
+  129,
+  694,
+  716,
+  742,
+  632,
+  89,
+  740,
+  417,
+  606,
+  494,
+  697,
+  697,
+  655,
+  30,
+  87,
+  617,
+  604,
+  101,
+  537,
+  566,
+  828,
+  969,
+  570,
+  993,
+  883,
+  127,
+  625,
+  985,
+  804,
+  553,
+  874,
+  758,
+  396,
+  875,
+  133,
+  224,
+  853,
+  877,
+  710,
+  782,
+  155,
+  923,
+  416,
+  794,
+  663,
+  200,
+  30,
+  689,
+  77,
+  218,
+  632,
+  849,
+  60,
+  270,
+  446,
+  419,
+  697,
+  980,
+  892,
+  935,
+  24,
+  717,
+  178,
+  471,
+  497,
+  209,
+  743,
+  284,
+  3,
+  813,
+  234,
+  76,
+  527,
+  145,
+  684,
+  742,
+  500,
+  832,
+  533,
+  780,
+  226,
+  800,
+  897,
+  102,
+  309,
+  994,
+  775,
+  888,
+  944,
+  243,
+  54,
+  17,
+  107,
+  929,
+  52,
+  244,
+  843,
+  553,
+  701,
+  236,
+  53,
+  909,
+  972,
+  753,
+  927,
+  796,
+  81,
+  679,
+  394,
+  649,
+  991,
+  973,
+  903,
+  797,
+  321,
+  763,
+  37,
+  991,
+  544,
+  268,
+  236,
+  10,
+  923,
+  443,
+  394,
+  720,
+  76,
+  434,
+  280,
+  314,
+  91,
+  934,
+  848,
+  217,
+  697,
+  646,
+  53,
+  647,
+  723,
+  154,
+  894,
+  943,
+  217,
+  641,
+  64,
+  987,
+  58,
+  98,
+  191,
+  819,
+  510,
+  708,
+  33,
+  747,
+  400,
+  513,
+  360,
+  526,
+  173,
+  733,
+  234,
+  759,
+  525,
+  485,
+  463,
+  382,
+  261,
+  826,
+  870,
+  999,
+  655,
+  564,
+  947,
+  334,
+  479,
+  963,
+  641,
+  647,
+  554,
+  497,
+  688,
+  818,
+  941,
+  20,
+  235,
+  523,
+  847,
+  527,
+  290,
+  535,
+  244,
+  312,
+  703,
+  779,
+  768,
+  732,
+  734,
+  759,
+  228,
+  671,
+  245,
+  304,
+  191,
+  808,
+  502,
+  219,
+  948,
+  24,
+  398,
+  268,
+  540,
+  243,
+  691,
+  966,
+  768,
+  631,
+  38,
+  446,
+  446,
+  697,
+  82,
+  824,
+  893,
+  696,
+  553,
+  563,
+  502,
+  25,
+  34,
+  648,
+  753,
+  857,
+  8,
+  341,
+  801,
+  913,
+  802,
+  177,
+  805,
+  155,
+  242,
+  920,
+  148,
+  139,
+  517,
+  413,
+  252,
+  225,
+  766,
+  663,
+  767,
+  179,
+  615,
+  212,
+  299,
+  424,
+  125,
+  155,
+  717,
+  263,
+  174,
+  390,
+  849,
+  645,
+  242,
+  572,
+  768,
+  821,
+  739,
+  12,
+  398,
+  617,
+  875,
+  957,
+  14,
+  791,
+  633,
+  539,
+  221,
+  80,
+  487,
+  467,
+  88,
+  234,
+  770,
+  816,
+  947,
+  220,
+  967,
+  942,
+  344,
+  993,
+  79,
+  388,
+  415,
+  886,
+  335,
+  967,
+  560,
+  486,
+  606,
+  49,
+  114,
+  582,
+  891,
+  544,
+  623,
+  858,
+  875,
+  986,
+  486,
+  549,
+  196,
+  198,
+  108,
+  152,
+  545,
+  430,
+  569,
+  122,
+  123,
+  386,
+  163,
+  269,
+  400,
+  774,
+  65,
+  689,
+  802,
+  35,
+  629,
+  738,
+  662,
+  930,
+  494,
+  45,
+  816,
+  412,
+  401,
+  728,
+  336,
+  584,
+  876,
+  14,
+  27,
+  12,
+  224,
+  482,
+  304,
+  852,
+  352,
+  163,
+  300,
+  545,
+  554,
+  958,
+  621,
+  872,
+  192,
+  450,
+  400,
+  195,
+  339,
+  916,
+  344,
+  341,
+  814,
+  450,
+  292,
+  783,
+  818,
+  573,
+  187,
+  992,
+  219,
+  103,
+  894,
+  857,
+  262,
+  204,
+  570,
+  30,
+  293,
+  454,
+  72,
+  568,
+  273,
+  112,
+  923,
+  247,
+  251,
+  780,
+  590,
+  349,
+  311,
+  856,
+  583,
+  566,
+  965,
+  74,
+  260,
+  523,
+  413,
+  892,
+  640,
+  718,
+  646,
+  244,
+  2,
+  440,
+  492,
+  906,
+  619,
+  94,
+  124,
+  732,
+  250,
+  906,
+  669,
+  903,
+  885,
+  494,
+  972,
+  619,
+  414,
+  627,
+  131,
+  249,
+  528,
+  447,
+  992,
+  345,
+  940,
+  765,
+  238,
+  131,
+  900,
+  327,
+  554,
+  975,
+  547,
+  630,
+  428,
+  673,
+  144,
+  690,
+  200,
+  148,
+  405,
+  29,
+  680,
+  559,
+  896,
+  321,
+  736,
+  540,
+  197,
+  154,
+  373,
+  221,
+  78,
+  134,
+  443,
+  514,
+  40,
+  577,
+  529,
+  205,
+  83,
+  366,
+  475,
+  703,
+  166,
+  31,
+  340,
+  803,
+  940,
+  181,
+  134,
+  520,
+  159,
+  99,
+  168,
+  404,
+  343,
+  317,
+  298,
+  715,
+  303,
+  990,
+  32,
+  999,
+  653,
+  151,
+  913,
+  449,
+  884,
+  571,
+  139,
+  806,
+  296,
+  375,
+  476,
+  206,
+  45,
+  991,
+  607,
+  5,
+  851,
+  283,
+  642,
+  396,
+  370,
+  25,
+  24,
+  418,
+  679,
+  469,
+  607,
+  355,
+  600,
+  83,
+  32,
+  787,
+  834,
+  972,
+  351,
+  948,
+  356,
+  270,
+  606,
+  322,
+  279,
+  966,
+  138,
+  832,
+  428,
+  306,
+  889,
+  828,
+  34,
+  449,
+  879,
+  205,
+  227,
+  67,
+  132,
+  845,
+  506,
+  317,
+  867,
+  353,
+  804,
+  532,
+  41,
+  157,
+  400,
+  691,
+  424,
+  812,
+  523,
+  232,
+  584,
+  885,
+  556,
+  504,
+  985,
+  322,
+  969,
+  371,
+  391,
+  98,
+  941,
+  26,
+  178,
+  774,
+  463,
+  997,
+  240,
+  265,
+  783,
+  393,
+  970,
+  984,
+  767,
+  198,
+  352,
+  641,
+  75,
+  295,
+  130,
+  103,
+  967,
+  755,
+  140,
+  35,
+  36,
+  632,
+  140,
+  31,
+  343,
+  311,
+  875,
+  957,
+  214,
+  594,
+  102,
+  708,
+  704,
+  42,
+  385,
+  66,
+  207,
+  462,
+  7,
+  629,
+  996,
+  45,
+  239,
+  67,
+  320,
+  572,
+  870,
+  745,
+  491,
+  347,
+  526,
+  400,
+  699,
+  754,
+  976,
+  956,
+  954,
+  794,
+  539,
+  303,
+  659,
+  358,
+  240,
+  499,
+  659,
+  623,
+  633,
+  84,
+  969,
+  47,
+  38,
+  147,
+  473,
+  237,
+  108,
+  223,
+  587,
+  983,
+  835,
+  709,
+  650,
+  654,
+  290,
+  457,
+  508,
+  179,
+  41,
+  861,
+  141,
+  415,
+  338,
+  134,
+  768,
+  896,
+  332,
+  774,
+  619,
+  168,
+  326,
+  995,
+  974,
+  888,
+  405,
+  863,
+  48,
+  321,
+  634,
+  321,
+  270,
+  859,
+  323,
+  320,
+  737,
+  558,
+  628,
+  600,
+  523,
+  806,
+  90,
+  149,
+  997,
+  588,
+  708,
+  940,
+  616,
+  975,
+  302,
+  113,
+  670,
+  369,
+  987,
+  171,
+  900,
+  669,
+  758,
+  668,
+  439,
+  111,
+  749,
+  85,
+  423,
+  868,
+  299,
+  854,
+  861,
+  512,
+  673,
+  594,
+  180,
+  719,
+  880,
+  377,
+  927,
+  123,
+  93,
+  351,
+  135,
+  116,
+  681,
+  353,
+  159,
+  981,
+  788,
+  232,
+  670,
+  43,
+  414,
+  383,
+  448,
+  113,
+  401,
+  103,
+  514,
+  158,
+  22,
+  537,
+  72,
+  392,
+  763,
+  35,
+  420,
+  434,
+  526,
+  732,
+  53,
+  193,
+  681,
+  185,
+  586,
+  476,
+  362,
+  274,
+  409,
+  658,
+  165,
+  767,
+  233,
+  389,
+  776,
+  179,
+  432,
+  84,
+  27,
+  691,
+  946,
+  470,
+  906,
+  144,
+  423,
+  226,
+  616,
+  247,
+  503,
+  52,
+  921,
+  450,
+  596,
+  634,
+  189,
+  640,
+  812,
+  892,
+  964,
+  903,
+  866,
+  914,
+  506,
+  858,
+  104,
+  335,
+  545,
+  557,
+  515,
+  707,
+  797,
+  965,
+  331,
+  927,
+  376,
+  757,
+  886,
+  154,
+  827,
+  675,
+  744,
+  712,
+  717,
+  977,
+  168,
+  49,
+  739,
+  407,
+  50,
+  224,
+  180,
+  317,
+  364,
+  594,
+  696,
+  318,
+  336,
+  734,
+  293,
+  497,
+  469,
+  988,
+  653,
+  241,
+  114,
+  982,
+  927,
+  708,
+  609,
+  851,
+  256,
+  225,
+  51,
+  194,
+  14,
+  282,
+  557,
+  892,
+  905,
+  457,
+  759,
+  466,
+  622,
+  351,
+  245,
+  5,
+  449,
+  80,
+  548,
+  213,
+  711,
+  458,
+  106,
+  713,
+  94,
+  587,
+  650,
+  853,
+  41,
+  578,
+  515,
+  946,
+  3,
+  758,
+  437,
+  935,
+  967,
+  284,
+  783,
+  525,
+  306,
+  820,
+  175,
+  216,
+  350,
+  866,
+  535,
+  369,
+  843,
+  642,
+  848,
+  648,
+  44,
+  796,
+  390,
+  983,
+  292,
+  352,
+  992,
+  122,
+  715,
+  123,
+  2,
+  83,
+  193,
+  711,
+  329,
+  242,
+  453,
+  600,
+  770,
+  969,
+  90,
+  259,
+  71,
+  253,
+  311,
+  865,
+  679,
+  120,
+  409,
+  329,
+  113,
+  636,
+  784,
+  548,
+  5,
+  162,
+  555,
+  82,
+  479,
+  168,
+  984,
+  802,
+  681,
+  497,
+  996,
+  382,
+  339,
+  55,
+  947,
+  117,
+  162,
+  275,
+  493,
+  410,
+  234,
+  69,
+  54,
+  817,
+  985,
+  639,
+  479,
+  362,
+  394,
+  939,
+  494,
+  462,
+  642,
+  301,
+  983,
+  350,
+  923,
+  244,
+  565,
+  587,
+  811,
+  130,
+  2,
+  249,
+  56,
+  722,
+  814,
+  940,
+  346,
+  233,
+  575,
+  764,
+  917,
+  981,
+  350,
+  589,
+  969,
+  834,
+  506,
+  623,
+  448,
+  515,
+  715,
+  397,
+  395,
+  174,
+  196,
+  337,
+  713,
+  560,
+  686,
+  836,
+  837,
+  544,
+  582,
+  586,
+  883,
+  968,
+  810,
+  164,
+  568,
+  109,
+  333,
+  703,
+  3,
+  719,
+  500,
+  530,
+  11,
+  628,
+  164,
+  246,
+  446,
+  472,
+  883,
+  142,
+  978,
+  127,
+  127,
+  837,
+  156,
+  66,
+  142,
+  382,
+  852,
+  608,
+  956,
+  287,
+  553,
+  284,
+  347,
+  23,
+  358,
+  964,
+  746,
+  894,
+  32,
+  258,
+  788,
+  404,
+  75,
+  587,
+  955,
+  593,
+  640,
+  828,
+  977,
+  428,
+  189,
+  421,
+  587,
+  31,
+  41,
+  718,
+  490,
+  535,
+  330,
+  589,
+  256,
+  762,
+  629,
+  586,
+  916,
+  745,
+  353,
+  114,
+  385,
+  517,
+  1,
+  279,
+  673,
+  638,
+  516,
+  273,
+  953,
+  822,
+  323,
+  973,
+  946,
+  715,
+  414,
+  811,
+  28,
+  804,
+  139,
+  254,
+  110,
+  811,
+  684,
+  405,
+  174,
+  97,
+  444,
+  222,
+  329,
+  911,
+  670,
+  642,
+  424,
+  24,
+  129,
+  772,
+  432,
+  372,
+  124,
+  43,
+  396,
+  319,
+  386,
+  934,
+  153,
+  697,
+  562,
+  375,
+  838,
+  510,
+  574,
+  8,
+  870,
+  677,
+  326,
+  410,
+  19,
+  510,
+  433,
+  893,
+  768,
+  853,
+  775,
+  994,
+  851,
+  611,
+  885,
+  212,
+  885,
+  411,
+  597,
+  36,
+  951,
+  482,
+  530,
+  572,
+  492,
+  583,
+  749,
+  579,
+  293,
+  315,
+  783,
+  31,
+  789,
+  298,
+  772,
+  697,
+  113,
+  87,
+  624,
+  402,
+  939,
+  214,
+  569,
+  92,
+  324,
+  338,
+  680,
+  627,
+  979,
+  679,
+  685,
+  954,
+  247,
+  130,
+  718,
+  993,
+  444,
+  692,
+  459,
+  652,
+  877,
+  733,
+  689,
+  848,
+  63,
+  325,
+  90,
+  638,
+  494,
+  278,
+  454,
+  490,
+  807,
+  30,
+  904,
+  133,
+  648,
+  201,
+  990,
+  662,
+  647,
+  987,
+  94,
+  103,
+  886,
+  386,
+  578,
+  667,
+  536,
+  754,
+  56,
+  382,
+  963,
+  506,
+  825,
+  173,
+  850,
+  635,
+  796,
+  229,
+  893,
+  785,
+  30,
+  143,
+  375,
+  306,
+  367,
+  888,
+  996,
+  908,
+  332,
+  239,
+  925,
+  603,
+  189,
+  160,
+  738,
+  16,
+  403,
+  222,
+  546,
+  469,
+  416,
+  29,
+  914,
+  212,
+  666,
+  260,
+  352,
+  592,
+  389,
+  793,
+  834,
+  43,
+  260,
+  583,
+  984,
+  590,
+  508,
+  347,
+  115,
+  199,
+  309,
+  508,
+  400,
+  669,
+  110,
+  201,
+  5,
+  575,
+  500,
+  292,
+  759,
+  898,
+  671,
+  612,
+  438,
+  33,
+  561,
+  560,
+  205,
+  719,
+  987,
+  263,
+  313,
+  144,
+  189,
+  429,
+  366,
+  229,
+  618,
+  384,
+  865,
+  278,
+  926,
+  329,
+  869,
+  930,
+  789,
+  925,
+  797,
+  554,
+  442,
+  595,
+  979,
+  276,
+  72,
+  960,
+  883,
+  436,
+  816,
+  70,
+  631,
+  956,
+  704,
+  691,
+  775,
+  67,
+  196,
+  246,
+  324,
+  260,
+  252,
+  68,
+  442,
+  493,
+  266,
+  873,
+  264,
+  920,
+  686,
+  970,
+  661,
+  807,
+  496,
+  214,
+  225,
+  80,
+  505,
+  837,
+  965,
+  360,
+  494,
+  233,
+  584,
+  268,
+  618,
+  633,
+  894,
+  994,
+  110,
+  917,
+  711,
+  214,
+  832,
+  291,
+  354,
+  961,
+  142,
+  343,
+  548,
+  803,
+  661,
+  706,
+  969,
+  201,
+  938,
+  706,
+  438,
+  922,
+  228,
+  775,
+  736,
+  91,
+  948,
+  581,
+  564,
+  370,
+  995,
+  653,
+  252,
+  872,
+  70,
+  990,
+  323,
+  392,
+  48,
+  737,
+  957,
+  660,
+  405,
+  290,
+  886,
+  550,
+  86,
+  426,
+  678,
+  908,
+  325,
+  65,
+  845,
+  933,
+  918,
+  393,
+  504,
+  272,
+  785,
+  526,
+  480,
+  331,
+  400,
+  514,
+  940,
+  121,
+  9,
+  965,
+  907,
+  165,
+  521,
+  825,
+  40,
+  251,
+  227,
+  739,
+  370,
+  606,
+  572,
+  70,
+  118,
+  684,
+  236,
+  809,
+  947,
+  221,
+  588,
+  369,
+  826,
+  554,
+  206,
+  353,
+  168,
+  995,
+  549,
+  733,
+  42,
+  297,
+  346,
+  495,
+  684,
+  266,
+  672,
+  400,
+  150,
+  178,
+  45,
+  40,
+  723,
+  527,
+  349,
+  985,
+  279,
+  965,
+  668,
+  29,
+  684,
+  447,
+  152,
+  241,
+  801,
+  335,
+  777,
+  601,
+  968,
+  997,
+  614,
+  762,
+  586,
+  540,
+  429,
+  174,
+  626,
+  770,
+  855,
+  522,
+  250,
+  846,
+  878,
+  412,
+  566,
+  995,
+  715,
+  880,
+  819,
+  67,
+  152,
+  154,
+  331,
+  191,
+  879,
+  869,
+  201,
+  642,
+  229,
+  298,
+  251,
+  182,
+  871,
+  757,
+  905,
+  462,
+  7,
+  9,
+  896,
+  234,
+  51,
+  579,
+  603,
+  265,
+  850,
+  203,
+  62,
+  577,
+  812,
+  511,
+  816,
+  498,
+  805,
+  35,
+  358,
+  144,
+  77,
+  731,
+  198,
+  647,
+  679,
+  697,
+  766,
+  553,
+  980,
+  49,
+  337,
+  803,
+  387,
+  593,
+  459,
+  286,
+  352,
+  798,
+  154,
+  888,
+  494,
+  914,
+  961,
+  547,
+  154,
+  802,
+  889,
+  726,
+  638,
+  740,
+  710,
+  263,
+  126,
+  509,
+  220,
+  626,
+  650,
+  40,
+  821,
+  979,
+  240,
+  371,
+  936,
+  7,
+  926,
+  252,
+  142,
+  200,
+  1,
+  801,
+  252,
+  208,
+  605,
+  516,
+  777,
+  997,
+  370,
+  869,
+  523,
+  651,
+  799,
+  321,
+  938,
+  575,
+  397,
+  289,
+  704,
+  359,
+  99,
+  245,
+  635,
+  79,
+  849,
+  375,
+  753,
+  806,
+  315,
+  21,
+  871,
+  991,
+  828,
+  942,
+  478,
+  651,
+  532,
+  357,
+  482,
+  76,
+  536,
+  603,
+  8,
+  941,
+  541,
+  639,
+  924,
+  709,
+  648,
+  169,
+  84,
+  810,
+  836,
+  724,
+  997,
+  346,
+  945,
+  961,
+  296,
+  708,
+  790,
+  640,
+  0,
+  829,
+  692,
+  178,
+  258,
+  727,
+  958,
+  490,
+  169,
+  612,
+  232,
+  33,
+  526,
+  776,
+  947,
+  161,
+  697,
+  20,
+  930,
+  57,
+  630,
+  359,
+  716,
+  247,
+  214,
+  839,
+  662,
+  141,
+  401,
+  157,
+  436,
+  98,
+  173,
+  390,
+  620,
+  608,
+  14,
+  518,
+  880,
+  749,
+  218,
+  704,
+  902,
+  131,
+  663,
+  288,
+  797,
+  171,
+  316,
+  89,
+  806,
+  367,
+  513,
+  666,
+  917,
+  660,
+  891,
+  835,
+  610,
+  822,
+  88,
+  765,
+  760,
+  69,
+  579,
+  16,
+  202,
+  470,
+  973,
+  542,
+  21,
+  853,
+  905,
+  108,
+  62,
+  285,
+  313,
+  337,
+  488,
+  546,
+  482,
+  575,
+  385,
+  997,
+  73,
+  919,
+  939,
+  503,
+  888,
+  345,
+  666,
+  425,
+  722,
+  864,
+  831,
+  432,
+  542,
+  196,
+  536,
+  582,
+  275,
+  489,
+  793,
+  835,
+  457,
+  645,
+  275,
+  499,
+  7,
+  759,
+  959,
+  400,
+  983,
+  387,
+  768,
+  928,
+  858,
+  938,
+  938,
+  258,
+  457,
+  166,
+  547,
+  954,
+  505,
+  483,
+  868,
+  556,
+  994,
+  752,
+  163,
+  301,
+  340,
+  445,
+  641,
+  436,
+  439,
+  935,
+  91,
+  736,
+  277,
+  895,
+  935,
+  139,
+  582,
+  208,
+  309,
+  468,
+  784,
+  847,
+  991,
+  571,
+  561,
+  573,
+  143,
+  181,
+  99,
+  232,
+  691,
+  567,
+  634,
+  352,
+  775,
+  39,
+  173,
+  877,
+  688,
+  845,
+  102,
+  565,
+  760,
+  585,
+  920,
+  979,
+  563,
+  839,
+  324,
+  987,
+  541,
+  557,
+  904,
+  658,
+  830,
+  141,
+  77,
+  955,
+  19,
+  357,
+  939,
+  324,
+  793,
+  604,
+  731,
+  535,
+  848,
+  527,
+  392,
+  804,
+  771,
+  202,
+  955,
+  996,
+  904,
+  290,
+  762,
+  368,
+  552,
+  30,
+  277,
+  784,
+  204,
+  446,
+  829,
+  367,
+  857,
+  180,
+  880,
+  148,
+  946,
+  447,
+  309,
+  315,
+  858,
+  231,
+  664,
+  490,
+  946,
+  242,
+  443,
+  448,
+  309,
+  869,
+  650,
+  431,
+  141,
+  990,
+  745,
+  850,
+  593,
+  62,
+  580,
+  690,
+  158,
+  28,
+  98,
+  371,
+  567,
+  309,
+  647,
+  651,
+  602,
+  647,
+  949,
+  938,
+  848,
+  612,
+  239,
+  812,
+  521,
+  37,
+  121,
+  756,
+  674,
+  948,
+  735,
+  779,
+  668,
+  515,
+  320,
+  142,
+  154,
+  266,
+  582,
+  941,
+  887,
+  171,
+  277,
+  392,
+  489,
+  603,
+  654,
+  492,
+  670,
+  313,
+  768,
+  51,
+  545,
+  424,
+  497,
+  834,
+  457,
+  577,
+  798,
+  243,
+  695,
+  722,
+  429,
+  691,
+  209,
+  363,
+  179,
+  302,
+  152,
+  647,
+  743,
+  158,
+  234,
+  127,
+  993,
+  971,
+  477,
+  26,
+  345,
+  84,
+  737,
+  585,
+  496,
+  220,
+  465,
+  126,
+  125,
+  991,
+  870,
+  645,
+  502,
+  531,
+  63,
+  347,
+  616,
+  580,
+  96,
+  315,
+  286,
+  264,
+  230,
+  432,
+  274,
+  537,
+  733,
+  708,
+  931,
+  224,
+  871,
+  886,
+  843,
+  727,
+  249,
+  306,
+  691,
+  887,
+  763,
+  899,
+  717,
+  480,
+  411,
+  124,
+  990,
+  895,
+  767,
+  252,
+  398,
+  713,
+  893,
+  935,
+  773,
+  998,
+  625,
+  849,
+  380,
+  761,
+  627,
+  125,
+  541,
+  108,
+  177,
+  508,
+  824,
+  640,
+  320,
+  809,
+  788,
+  513,
+  115,
+  65,
+  270,
+  584,
+  422,
+  17,
+  840,
+  587,
+  778,
+  703,
+  433,
+  399,
+  92,
+  570,
+  325,
+  22,
+  452,
+  950,
+  105,
+  459,
+  671,
+  7,
+  357,
+  713,
+  106,
+  871,
+  94,
+  404,
+  948,
+  530,
+  631,
+  679,
+  806,
+  774,
+  371,
+  124,
+  529,
+  513,
+  26,
+  859,
+  172,
+  331,
+  566,
+  434,
+  1,
+  970,
+  56,
+  18,
+  411,
+  123,
+  316,
+  194,
+  574,
+  190,
+  302,
+  548,
+  643,
+  635,
+  871,
+  630,
+  207,
+  193,
+  984,
+  963,
+  623,
+  742,
+  257,
+  336,
+  153,
+  792,
+  967,
+  235,
+  506,
+  401,
+  408,
+  45,
+  648,
+  153,
+  364,
+  320,
+  619,
+  949,
+  354,
+  243,
+  437,
+  646,
+  675,
+  74,
+  658,
+  781,
+  24,
+  282,
+  902,
+  530,
+  403,
+  499,
+  962,
+  787,
+  980,
+  815,
+  163,
+  921,
+  355,
+  375,
+  103,
+  223,
+  556,
+  860,
+  636,
+  420,
+  212,
+  690,
+  559,
+  39,
+  222,
+  201,
+  70,
+  282,
+  83,
+  53,
+  83,
+  520,
+  716,
+  286,
+  149,
+  456,
+  277,
+  130,
+  500,
+  379,
+  495,
+  485,
+  729,
+  922,
+  762,
+  59,
+  880,
+  432,
+  6,
+  500,
+  19,
+  982,
+  612,
+  22,
+  812,
+  278,
+  222,
+  897,
+  854,
+  360,
+  719,
+  923,
+  264,
+  120,
+  760,
+  427,
+  520,
+  304,
+  800,
+  411,
+  720,
+  729,
+  399,
+  207,
+  336,
+  917,
+  368,
+  763,
+  560,
+  568,
+  609,
+  361,
+  359,
+  253,
+  672,
+  742,
+  141,
+  397,
+  292,
+  262,
+  881,
+  258,
+  564,
+  566,
+  72,
+  633,
+  920,
+  904,
+  419,
+  990,
+  10,
+  812,
+  547,
+  545,
+  232,
+  129,
+  284,
+  975,
+  178,
+  483,
+  75,
+  780,
+  562,
+  910,
+  277,
+  107,
+  836,
+  912,
+  638,
+  896,
+  204,
+  861,
+  507,
+  604,
+  103,
+  868,
+  644,
+  496,
+  215,
+  215,
+  553,
+  645,
+  398,
+  752,
+  352,
+  984,
+  6,
+  846,
+  49,
+  811,
+  354,
+  263,
+  286,
+  518,
+  269,
+  639,
+  74,
+  637,
+  917,
+  15,
+  244,
+  539,
+  595,
+  545,
+  856,
+  68,
+  354,
+  968,
+  10,
+  256,
+  106,
+  124,
+  864,
+  595,
+  936,
+  194,
+  956,
+  201,
+  612,
+  603,
+  546,
+  703,
+  582,
+  139,
+  436,
+  716,
+  605,
+  65,
+  832,
+  103,
+  742,
+  511,
+  26,
+  122,
+  309,
+  599,
+  251,
+  324,
+  507,
+  125,
+  294,
+  877,
+  45,
+  956,
+  27,
+  330,
+  36,
+  80,
+  298,
+  272,
+  438,
+  243,
+  437,
+  741,
+  121,
+  507,
+  674,
+  194,
+  263,
+  440,
+  772,
+  93,
+  3,
+  139,
+  173,
+  594,
+  174,
+  770,
+  954,
+  393,
+  549,
+  33,
+  435,
+  836,
+  75,
+  842,
+  469,
+  887,
+  919,
+  901,
+  326,
+  898,
+  346,
+  314,
+  389,
+  818,
+  663,
+  371,
+  843,
+  363,
+  959,
+  215,
+  802,
+  218,
+  776,
+  153,
+  648,
+  150,
+  257,
+  31,
+  711,
+  335,
+  516,
+  582,
+  317,
+  999,
+  393,
+  435,
+  371,
+  926,
+  507,
+  933,
+  925,
+  825,
+  554,
+  870,
+  845,
+  194,
+  588,
+  423,
+  819,
+  698,
+  312,
+  107,
+  541,
+  443,
+  833,
+  20,
+  79,
+  147,
+  331,
+  986,
+  784,
+  130,
+  261,
+  714,
+  537,
+  500,
+  363,
+  259,
+  122,
+  506,
+  550,
+  204,
+  466,
+  763,
+  650,
+  360,
+  826,
+  385,
+  189,
+  836,
+  807,
+  862,
+  943,
+  431,
+  547,
+  300,
+  682,
+  336,
+  71,
+  467,
+  871,
+  6,
+  207,
+  214,
+  482,
+  128,
+  42,
+  151,
+  788,
+  597,
+  644,
+  217,
+  507,
+  653,
+  330,
+  660,
+  696,
+  287,
+  513,
+  506,
+  124,
+  348,
+  195,
+  344,
+  480,
+  112,
+  839,
+  497,
+  751,
+  689,
+  579,
+  820,
+  490,
+  903,
+  809,
+  790,
+  409,
+  684,
+  708,
+  538,
+  177,
+  77,
+  702,
+  997,
+  846,
+  958,
+  767,
+  174,
+  206,
+  236,
+  340,
+  66,
+  495,
+  364,
+  833,
+  710,
+  598,
+  889,
+  36,
+  413,
+  485,
+  27,
+  824,
+  138,
+  864,
+  146,
+  890,
+  855,
+  133,
+  57,
+  788,
+  755,
+  597,
+  256,
+  76,
+  75,
+  795,
+  970,
+  384,
+  463,
+  528,
+  142,
+  232,
+  973,
+  961,
+  696,
+  231,
+  251,
+  918,
+  383,
+  264,
+  229,
+  103,
+  610,
+  505,
+  311,
+  725,
+  203,
+  414,
+  53,
+  258,
+  973,
+  293,
+  254,
+  782,
+  26,
+  490,
+  190,
+  927,
+  341,
+  479,
+  858,
+  804,
+  463,
+  457,
+  47,
+  718,
+  205,
+  521,
+  107,
+  171,
+  414,
+  845,
+  941,
+  865,
+  778,
+  315,
+  513,
+  236,
+  669,
+  681,
+  187,
+  964,
+  875,
+  548,
+  869,
+  157,
+  782,
+  876,
+  820,
+  436,
+  595,
+  304,
+  452,
+  667,
+  827,
+  803,
+  227,
+  466,
+  253,
+  874,
+  43,
+  987,
+  416,
+  64,
+  529,
+  943,
+  471,
+  753,
+  259,
+  81,
+  693,
+  231,
+  159,
+  143,
+  399,
+  492,
+  510,
+  257,
+  825,
+  557,
+  263,
+  536,
+  200,
+  71,
+  744,
+  132,
+  231,
+  842,
+  159,
+  49,
+  302,
+  806,
+  870,
+  999,
+  580,
+  941,
+  437,
+  261,
+  861,
+  423,
+  929,
+  994,
+  534,
+  396,
+  315,
+  783,
+  765,
+  930,
+  644,
+  756,
+  462,
+  195,
+  564,
+  22,
+  384,
+  521,
+  730,
+  505,
+  63,
+  457,
+  709,
+  976,
+  314,
+  282,
+  864,
+  118,
+  724,
+  440,
+  316,
+  776,
+  848,
+  506,
+  48,
+  233,
+  789,
+  380,
+  580,
+  889,
+  81,
+  697,
+  763,
+  59,
+  234,
+  408,
+  647,
+  306,
+  431,
+  170,
+  942,
+  7,
+  854,
+  406,
+  217,
+  257,
+  654,
+  945,
+  846,
+  874,
+  436,
+  621,
+  787,
+  538,
+  556,
+  245,
+  891,
+  675,
+  141,
+  746,
+  646,
+  56,
+  919,
+  717,
+  816,
+  234,
+  712,
+  458,
+  339,
+  680,
+  705,
+  485,
+  616,
+  610,
+  208,
+  251,
+  273,
+  242,
+  151,
+  560,
+  362,
+  520,
+  417,
+  760,
+  758,
+  89,
+  229,
+  964,
+  150,
+  683,
+  851,
+  620,
+  180,
+  304,
+  339,
+  923,
+  78,
+  12,
+  253,
+  307,
+  854,
+  692,
+  339,
+  854,
+  773,
+  925,
+  938,
+  926,
+  680,
+  358,
+  592,
+  522,
+  3,
+  916,
+  431,
+  61,
+  649,
+  448,
+  463,
+  508,
+  758,
+  646,
+  122,
+  644,
+  508,
+  85,
+  945,
+  934,
+  473,
+  86,
+  380,
+  856,
+  26,
+  642,
+  831,
+  889,
+  592,
+  669,
+  896,
+  665,
+  897,
+  497,
+  740,
+  987,
+  530,
+  217,
+  945,
+  800,
+  104,
+  267,
+  558,
+  688,
+  806,
+  944,
+  79,
+  119,
+  416,
+  715,
+  389,
+  267,
+  333,
+  579,
+  882,
+  278,
+  972,
+  767,
+  890,
+  412,
+  110,
+  525,
+  605,
+  273,
+  857,
+  312,
+  841,
+  312,
+  76,
+  596,
+  956,
+  484,
+  30,
+  230,
+  319,
+  789,
+  586,
+  44,
+  341,
+  434,
+  565,
+  238,
+  907,
+  581,
+  719,
+  944,
+  19,
+  447,
+  599,
+  966,
+  776,
+  472,
+  393,
+  179,
+  350,
+  59,
+  291,
+  317,
+  585,
+  868,
+  750,
+  464,
+  35,
+  79,
+  888,
+  245,
+  972,
+  150,
+  190,
+  511,
+  785,
+  79,
+  726,
+  51,
+  655,
+  456,
+  474,
+  441,
+  257,
+  664,
+  257,
+  683,
+  70,
+  763,
+  743,
+  208,
+  190,
+  857,
+  693,
+  574,
+  626,
+  411,
+  484,
+  434,
+  507,
+  779,
+  306,
+  549,
+  778,
+  512,
+  343,
+  549,
+  679,
+  259,
+  793,
+  492,
+  966,
+  281,
+  787,
+  858,
+  419,
+  580,
+  588,
+  626,
+  166,
+  360,
+  780,
+  747,
+  249,
+  856,
+  305,
+  861,
+  383,
+  938,
+  520,
+  78,
+  311,
+  334,
+  592,
+  8,
+  629,
+  606,
+  623,
+  217,
+  466,
+  378,
+  856,
+  551,
+  458,
+  243,
+  484,
+  294,
+  587,
+  953,
+  749,
+  287,
+  733,
+  796,
+  498,
+  534,
+  989,
+  379,
+  804,
+  560,
+  971,
+  333,
+  384,
+  367,
+  292,
+  898,
+  277,
+  508,
+  58,
+  636,
+  37,
+  312,
+  742,
+  879,
+  536,
+  239,
+  240,
+  730,
+  3,
+  593,
+  301,
+  66,
+  144,
+  62,
+  248,
+  634,
+  863,
+  14,
+  579,
+  120,
+  250,
+  322,
+  964,
+  447,
+  727,
+  322,
+  765,
+  268,
+  206,
+  364,
+  515,
+  471,
+  858,
+  438,
+  840,
+  968,
+  13,
+  264,
+  388,
+  75,
+  163,
+  137,
+  999,
+  866,
+  153,
+  356,
+  193,
+  854,
+  718,
+  606,
+  730,
+  162,
+  431,
+  375,
+  917,
+  548,
+  825,
+  99,
+  271,
+  0,
+  303,
+  228,
+  894,
+  370,
+  644,
+  38,
+  532,
+  512,
+  546,
+  303,
+  923,
+  170,
+  489,
+  40,
+  82,
+  479,
+  971,
+  452,
+  637,
+  557,
+  940,
+  132,
+  908,
+  268,
+  774,
+  932,
+  786,
+  976,
+  491,
+  710,
+  197,
+  554,
+  532,
+  265,
+  909,
+  18,
+  758,
+  213,
+  45,
+  698,
+  180,
+  990,
+  471,
+  610,
+  575,
+  659,
+  412,
+  595,
+  275,
+  498,
+  713,
+  306,
+  259,
+  1,
+  253,
+  316,
+  357,
+  155,
+  55,
+  520,
+  687,
+  350,
+  644,
+  974,
+  945,
+  277,
+  654,
+  850,
+  412,
+  847,
+  384,
+  820,
+  512,
+  979,
+  21,
+  823,
+  299,
+  93,
+  793,
+  204,
+  925,
+  130,
+  103,
+  314,
+  105,
+  564,
+  762,
+  524,
+  478,
+  178,
+  807,
+  56,
+  916,
+  711,
+  511,
+  111,
+  865,
+  110,
+  195,
+  982,
+  171,
+  631,
+  960,
+  640,
+  584,
+  600,
+  770,
+  669,
+  649,
+  51,
+  212,
+  828,
+  973,
+  448,
+  101,
+  856,
+  801,
+  679,
+  694,
+  242,
+  334,
+  620,
+  160,
+  667,
+  891,
+  791,
+  659,
+  107,
+  865,
+  126,
+  882,
+  675,
+  726,
+  234,
+  346,
+  875,
+  88,
+  115,
+  592,
+  729,
+  299,
+  177,
+  210,
+  456,
+  766,
+  928,
+  837,
+  417,
+  856,
+  631,
+  142,
+  640,
+  848,
+  805,
+  989,
+  509,
+  106,
+  440,
+  276,
+  581,
+  117,
+  187,
+  565,
+  620,
+  433,
+  475,
+  873,
+  626,
+  342,
+  455,
+  373,
+  767,
+  855,
+  866,
+  942,
+  108,
+  117,
+  799,
+  85,
+  936,
+  665,
+  975,
+  750,
+  35,
+  769,
+  889,
+  610,
+  210,
+  220,
+  359,
+  981,
+  728,
+  649,
+  0,
+  826,
+  950,
+  120,
+  648,
+  58,
+  383,
+  436,
+  737,
+  11,
+  714,
+  424,
+  251,
+  301,
+  204,
+  287,
+  183,
+  472,
+  265,
+  120,
+  780,
+  369,
+  695,
+  758,
+  740,
+  107,
+  831,
+  93,
+  535,
+  306,
+  777,
+  976,
+  562,
+  59,
+  956,
+  304,
+  83,
+  576,
+  399,
+  999,
+  899,
+  824,
+  350,
+  635,
+  896,
+  802,
+  332,
+  421,
+  878,
+  433,
+  193,
+  353,
+  802,
+  683,
+  456,
+  88,
+  211,
+  132,
+  432,
+  354,
+  421,
+  616,
+  53,
+  231,
+  915,
+  510,
+  106,
+  28,
+  32,
+  600,
+  461,
+  131,
+  594,
+  678,
+  744,
+  674,
+  620,
+  290,
+  535,
+  534,
+  543,
+  62,
+  971,
+  905,
+  180,
+  10,
+  234,
+  166,
+  272,
+  73,
+  128,
+  437,
+  613,
+  291,
+  638,
+  610,
+  225,
+  630,
+  309,
+  112,
+  868,
+  557,
+  439,
+  355,
+  555,
+  579,
+  443,
+  843,
+  20,
+  464,
+  987,
+  284,
+  302,
+  450,
+  355,
+  83,
+  407,
+  711,
+  752,
+  187,
+  249,
+  807,
+  883,
+  924,
+  858,
+  110,
+  409,
+  189,
+  998,
+  439,
+  120,
+  321,
+  875,
+  140,
+  640,
+  285,
+  561,
+  873,
+  371,
+  73,
+  4,
+  169,
+  771,
+  413,
+  447,
+  985,
+  206,
+  635,
+  943,
+  960,
+  240,
+  554,
+  209,
+  576,
+  254,
+  163,
+  977,
+  846,
+  610,
+  596,
+  920,
+  524,
+  608,
+  402,
+  249,
+  624,
+  180,
+  875,
+  240,
+  670,
+  421,
+  1,
+  911,
+  505,
+  474,
+  979,
+  623,
+  678,
+  952,
+  909,
+  751,
+  241,
+  269,
+  968,
+  396,
+  641,
+  516,
+  965,
+  406,
+  54,
+  853,
+  346,
+  650,
+  787,
+  400,
+  175,
+  929,
+  662,
+  870,
+  170,
+  468,
+  173,
+  620,
+  318,
+  170,
+  995,
+  525,
+  138,
+  520,
+  151,
+  851,
+  30,
+  596,
+  605,
+  802,
+  449,
+  174,
+  518,
+  633,
+  293,
+  652,
+  779,
+  606,
+  444,
+  472,
+  359,
+  204,
+  308,
+  104,
+  274,
+  707,
+  638,
+  193,
+  577,
+  125,
+  28,
+  537,
+  987,
+  521,
+  80,
+  56,
+  111,
+  589,
+  81,
+  794,
+  377,
+  36,
+  680,
+  476,
+  227,
+  778,
+  138,
+  24,
+  752,
+  160,
+  590,
+  855,
+  396,
+  289,
+  142,
+  785,
+  551,
+  696,
+  514,
+  268,
+  536,
+  547,
+  207,
+  943,
+  166,
+  0,
+  959,
+  114,
+  322,
+  906,
+  322,
+  892,
+  960,
+  152,
+  219,
+  944,
+  540,
+  874,
+  965,
+  269,
+  858,
+  681,
+  764,
+  673,
+  30,
+  954,
+  88,
+  521,
+  729,
+  159,
+  275,
+  56,
+  125,
+  755,
+  556,
+  505,
+  72,
+  919,
+  180,
+  714,
+  476,
+  557,
+  286,
+  639,
+  983,
+  152,
+  572,
+  584,
+  774,
+  510,
+  716,
+  601,
+  148,
+  732,
+  601,
+  940,
+  969,
+  20,
+  190,
+  364,
+  622,
+  685,
+  61,
+  344,
+  196,
+  7,
+  990,
+  899,
+  252,
+  754,
+  435,
+  284,
+  201,
+  722,
+  552,
+  343,
+  657,
+  969,
+  888,
+  215,
+  691,
+  409,
+  26,
+  814,
+  955,
+  756,
+  555,
+  490,
+  721,
+  618,
+  204,
+  30,
+  599,
+  134,
+  692,
+  978,
+  825,
+  270,
+  841,
+  504,
+  774,
+  525,
+  384,
+  45,
+  973,
+  630,
+  292,
+  407,
+  67,
+  655,
+  51,
+  321,
+  712,
+  920,
+  987,
+  848,
+  722,
+  54,
+  844,
+  881,
+  2,
+  745,
+  543,
+  18,
+  346,
+  886,
+  284,
+  553,
+  327,
+  745,
+  802,
+  253,
+  852,
+  636,
+  390,
+  455,
+  868,
+  740,
+  663,
+  964,
+  729,
+  838,
+  160,
+  466,
+  658,
+  934,
+  788,
+  92,
+  286,
+  175,
+  248,
+  540,
+  880,
+  948,
+  738,
+  221,
+  979,
+  785,
+  992,
+  482,
+  300,
+  55,
+  307,
+  541,
+  695,
+  226,
+  659,
+  648,
+  922,
+  441,
+  203,
+  794,
+  22,
+  970,
+  164,
+  46,
+  259,
+  951,
+  704,
+  886,
+  299,
+  673,
+  173,
+  240,
+  807,
+  719,
+  658,
+  194,
+  357,
+  971,
+  821,
+  711,
+  707,
+  225,
+  482,
+  734,
+  77,
+  917,
+  665,
+  867,
+  755,
+  544,
+  326,
+  524,
+  598,
+  78,
+  244,
+  906,
+  617,
+  928,
+  395,
+  658,
+  732,
+  601,
+  421,
+  359,
+  459,
+  727,
+  409,
+  806,
+  285,
+  943,
+  207,
+  630,
+  752,
+  85,
+  819,
+  81,
+  714,
+  599,
+  44,
+  892,
+  139,
+  813,
+  684,
+  175,
+  718,
+  720,
+  697,
+  401,
+  310,
+  84,
+  666,
+  259,
+  357,
+  939,
+  246,
+  527,
+  856,
+  455,
+  533,
+  717,
+  790,
+  923,
+  962,
+  105,
+  447,
+  598,
+  8,
+  941,
+  409,
+  510,
+  130,
+  823,
+  606,
+  773,
+  511,
+  574,
+  98,
+  731,
+  402,
+  862,
+  752,
+  623,
+  991,
+  46,
+  307,
+  347,
+  826,
+  698,
+  658,
+  35,
+  642,
+  770,
+  293,
+  385,
+  50,
+  470,
+  908,
+  177,
+  919,
+  460,
+  783,
+  812,
+  885,
+  144,
+  408,
+  659,
+  741,
+  639,
+  741,
+  234,
+  361,
+  975,
+  361,
+  934,
+  345,
+  46,
+  370,
+  804,
+  357,
+  22,
+  797,
+  24,
+  698,
+  274,
+  669,
+  711,
+  610,
+  104,
+  699,
+  121,
+  724,
+  99,
+  296,
+  870,
+  786,
+  907,
+  517,
+  300,
+  369,
+  115,
+  987,
+  98,
+  420,
+  792,
+  167,
+  589,
+  81,
+  929,
+  901,
+  444,
+  109,
+  382,
+  693,
+  593,
+  875,
+  545,
+  683,
+  487,
+  631,
+  35,
+  664,
+  35,
+  465,
+  381,
+  502,
+  512,
+  213,
+  325,
+  921,
+  435,
+  368,
+  265,
+  897,
+  888,
+  773,
+  659,
+  636,
+  822,
+  940,
+  704,
+  937,
+  990,
+  380,
+  22,
+  806,
+  443,
+  272,
+  226,
+  75,
+  390,
+  701,
+  604,
+  103,
+  834,
+  836,
+  128,
+  776,
+  390,
+  490,
+  761,
+  481,
+  372,
+  204,
+  99,
+  91,
+  22,
+  808,
+  253,
+  230,
+  576,
+  111,
+  530,
+  569,
+  205,
+  79,
+  723,
+  69,
+  129,
+  157,
+  690,
+  663,
+  960,
+  928,
+  549,
+  861,
+  858,
+  688,
+  269,
+  88,
+  740,
+  156,
+  907,
+  39,
+  916,
+  907,
+  334,
+  924,
+  489,
+  523,
+  243,
+  832,
+  196,
+  238,
+  353,
+  1,
+  7,
+  314,
+  127,
+  188,
+  96,
+  15,
+  805,
+  54,
+  9,
+  827,
+  404,
+  908,
+  152,
+  993,
+  739,
+  18,
+  830,
+  225,
+  119,
+  544,
+  559,
+  312,
+  438,
+  641,
+  301,
+  560,
+  392,
+  365,
+  576,
+  955,
+  898,
+  503,
+  118,
+  601,
+  848,
+  464,
+  83,
+  817,
+  190,
+  930,
+  333,
+  675,
+  660,
+  97,
+  975,
+  412,
+  292,
+  419,
+  456,
+  795,
+  937,
+  793,
+  775,
+  168,
+  22,
+  285,
+  446,
+  516,
+  479,
+  419,
+  80,
+  724,
+  440,
+  812,
+  799,
+  215,
+  257,
+  254,
+  998,
+  103,
+  914,
+  559,
+  536,
+  588,
+  833,
+  464,
+  188,
+  548,
+  869,
+  359,
+  478,
+  711,
+  413,
+  236,
+  826,
+  534,
+  811,
+  997,
+  919,
+  179,
+  790,
+  869,
+  958,
+  428,
+  792,
+  503,
+  118,
+  329,
+  350,
+  240,
+  390,
+  989,
+  365,
+  170,
+  270,
+  362,
+  823,
+  277,
+  978,
+  293,
+  777,
+  833,
+  515,
+  336,
+  976,
+  174,
+  532,
+  206,
+  600,
+  236,
+  270,
+  737,
+  513,
+  511,
+  672,
+  679,
+  854,
+  554,
+  295,
+  755,
+  523,
+  932,
+  750,
+  520,
+  450,
+  535,
+  586,
+  41,
+  2,
+  357,
+  349,
+  195,
+  5,
+  421,
+  165,
+  148,
+  341,
+  548,
+  200,
+  620,
+  554,
+  759,
+  518,
+  145,
+  722,
+  932,
+  586,
+  186,
+  189,
+  713,
+  830,
+  193,
+  436,
+  92,
+  883,
+  115,
+  46,
+  257,
+  114,
+  244,
+  303,
+  658,
+  66,
+  395,
+  469,
+  697,
+  430,
+  317,
+  184,
+  224,
+  362,
+  429,
+  493,
+  506,
+  218,
+  593,
+  279,
+  450,
+  567,
+  823,
+  411,
+  889,
+  871,
+  439,
+  366,
+  693,
+  160,
+  602,
+  813,
+  85,
+  824,
+  224,
+  144,
+  721,
+  540,
+  880,
+  444,
+  222,
+  843,
+  704,
+  285,
+  480,
+  71,
+  556,
+  404,
+  959,
+  31,
+  235,
+  826,
+  228,
+  372,
+  477,
+  993,
+  269,
+  254,
+  432,
+  643,
+  380,
+  81,
+  642,
+  794,
+  462,
+  386,
+  625,
+  787,
+  623,
+  528,
+  718,
+  472,
+  82,
+  225,
+  488,
+  488,
+  382,
+  114,
+  741,
+  356,
+  237,
+  434,
+  915,
+  593,
+  334,
+  875,
+  525,
+  846,
+  418,
+  726,
+  633,
+  9,
+  228,
+  131,
+  198,
+  922,
+  681,
+  218,
+  435,
+  803,
+  310,
+  641,
+  258,
+  90,
+  521,
+  538,
+  971,
+  301,
+  904,
+  31,
+  805,
+  745,
+  702,
+  285,
+  511,
+  591,
+  404,
+  739,
+  157,
+  12,
+  212,
+  69,
+  478,
+  627,
+  720,
+  177,
+  290,
+  417,
+  585,
+  965,
+  881,
+  508,
+  92,
+  443,
+  655,
+  217,
+  758,
+  203,
+  491,
+  497,
+  753,
+  347,
+  582,
+  15,
+  142,
+  301,
+  481,
+  728,
+  242,
+  325,
+  272,
+  127,
+  694,
+  174,
+  851,
+  309,
+  486,
+  520,
+  498,
+  794,
+  155,
+  671,
+  872,
+  698,
+  579,
+  771,
+  665,
+  591,
+  806,
+  984,
+  37,
+  886,
+  580,
+  305,
+  103,
+  585,
+  234,
+  918,
+  62,
+  857,
+  548,
+  295,
+  618,
+  901,
+  12,
+  20,
+  59,
+  291,
+  376,
+  299,
+  339,
+  10,
+  586,
+  540,
+  972,
+  682,
+  473,
+  340,
+  820,
+  752,
+  332,
+  93,
+  973,
+  434,
+  39,
+  526,
+  841,
+  955,
+  270,
+  116,
+  778,
+  140,
+  878,
+  509,
+  760,
+  216,
+  851,
+  836,
+  475,
+  33,
+  884,
+  382,
+  264,
+  324,
+  787,
+  640,
+  793,
+  686,
+  280,
+  115,
+  461,
+  258,
+  5,
+  461,
+  527,
+  672,
+  196,
+  813,
+  585,
+  387,
+  413,
+  339,
+  113,
+  767,
+  564,
+  10,
+  332,
+  500,
+  311,
+  282,
+  143,
+  108,
+  29,
+  966,
+  13,
+  837,
+  241,
+  431,
+  51,
+  564,
+  414,
+  835,
+  855,
+  71,
+  885,
+  990,
+  86,
+  340,
+  225,
+  179,
+  12,
+  795,
+  628,
+  615,
+  167,
+  756,
+  274,
+  154,
+  484,
+  607,
+  155,
+  522,
+  699,
+  407,
+  582,
+  710,
+  535,
+  153,
+  417,
+  349,
+  37,
+  743,
+  966,
+  840,
+  230,
+  83,
+  759,
+  610,
+  31,
+  962,
+  561,
+  19,
+  702,
+  56,
+  838,
+  235,
+  47,
+  393,
+  700,
+  873,
+  548,
+  419,
+  508,
+  320,
+  91,
+  70,
+  693,
+  587,
+  889,
+  716,
+  7,
+  213,
+  628,
+  603,
+  411,
+  351,
+  79,
+  220,
+  823,
+  919,
+  430,
+  423,
+  336,
+  265,
+  161,
+  357,
+  184,
+  821,
+  598,
+  529,
+  663,
+  197,
+  655,
+  620,
+  749,
+  488,
+  130,
+  45,
+  861,
+  912,
+  383,
+  273,
+  357,
+  285,
+  244,
+  860,
+  867,
+  156,
+  540,
+  428,
+  250,
+  383,
+  327,
+  125,
+  170,
+  226,
+  163,
+  295,
+  901,
+  703,
+  992,
+  625,
+  805,
+  143,
+  416,
+  488,
+  83,
+  838,
+  901,
+  832,
+  722,
+  33,
+  565,
+  957,
+  386,
+  255,
+  529,
+  22,
+  385,
+  641,
+  3,
+  975,
+  43,
+  360,
+  374,
+  26,
+  50,
+  513,
+  623,
+  498,
+  962,
+  47,
+  824,
+  955,
+  947,
+  877,
+  718,
+  305,
+  433,
+  838,
+  16,
+  971,
+  56,
+  315,
+  40,
+  251,
+  32,
+  776,
+  910,
+  502,
+  872,
+  404,
+  24,
+  266,
+  655,
+  444,
+  38,
+  433,
+  166,
+  251,
+  737,
+  585,
+  802,
+  879,
+  316,
+  909,
+  85,
+  530,
+  162,
+  819,
+  420,
+  995,
+  655,
+  546,
+  83,
+  666,
+  491,
+  224,
+  436,
+  981,
+  473,
+  206,
+  574,
+  977,
+  573,
+  905,
+  370,
+  928,
+  524,
+  974,
+  177,
+  667,
+  662,
+  121,
+  514,
+  916,
+  830,
+  801,
+  455,
+  43,
+  986,
+  364,
+  479,
+  667,
+  157,
+  546,
+  927,
+  120,
+  882,
+  184,
+  769,
+  480,
+  892,
+  324,
+  822,
+  947,
+  608,
+  704,
+  503,
+  888,
+  28,
+  741,
+  735,
+  189,
+  673,
+  549,
+  13,
+  594,
+  331,
+  965,
+  430,
+  323,
+  625,
+  845,
+  487,
+  704,
+  232,
+  774,
+  239,
+  323,
+  458,
+  415,
+  843,
+  822,
+  500,
+  699,
+  940,
+  198,
+  205,
+  274,
+  723,
+  728,
+  817,
+  307,
+  500,
+  942,
+  294,
+  475,
+  840,
+  245,
+  863,
+  692,
+  884,
+  15,
+  43,
+  589,
+  639,
+  584,
+  66,
+  194,
+  473,
+  487,
+  382,
+  984,
+  855,
+  19,
+  764,
+  751,
+  420,
+  783,
+  774,
+  692,
+  537,
+  467,
+  185,
+  506,
+  348,
+  617,
+  961,
+  109,
+  118,
+  833,
+  725,
+  706,
+  47,
+  641,
+  69,
+  382,
+  892,
+  613,
+  168,
+  546,
+  72,
+  287,
+  658,
+  280,
+  961,
+  11,
+  786,
+  468,
+  65,
+  25,
+  145,
+  746,
+  846,
+  911,
+  574,
+  392,
+  779,
+  746,
+  711,
+  935,
+  796,
+  482,
+  506,
+  772,
+  873,
+  712,
+  546,
+  93,
+  546,
+  28,
+  757,
+  858,
+  313,
+  663,
+  914,
+  858,
+  508,
+  945,
+  912,
+  223,
+  945,
+  200,
+  313,
+  367,
+  309,
+  487,
+  637,
+  824,
+  869,
+  534,
+  699,
+  79,
+  510,
+  860,
+  34,
+  420,
+  255,
+  493,
+  790,
+  310,
+  444,
+  113,
+  719,
+  695,
+  358,
+  148,
+  947,
+  483,
+  821,
+  59,
+  835,
+  434,
+  903,
+  41,
+  634,
+  592,
+  594,
+  150,
+  410,
+  598,
+  14,
+  961,
+  97,
+  942,
+  79,
+  466,
+  17,
+  112,
+  830,
+  751,
+  454,
+  84,
+  374,
+  264,
+  624,
+  963,
+  372,
+  81,
+  536,
+  775,
+  159,
+  372,
+  174,
+  707,
+  399,
+  984,
+  57,
+  648,
+  923,
+  258,
+  417,
+  86,
+  978,
+  982,
+  414,
+  147,
+  403,
+  610,
+  251,
+  571,
+  656,
+  151,
+  156,
+  812,
+  621,
+  669,
+  21,
+  148,
+  31,
+  74,
+  77,
+  49,
+  175,
+  263,
+  527,
+  797,
+  797,
+  775,
+  553,
+  981,
+  898,
+  725,
+  357,
+  116,
+  678,
+  297,
+  357,
+  496,
+  159,
+  750,
+  979,
+  145,
+  331,
+  691,
+  711,
+  921,
+  829,
+  284,
+  217,
+  581,
+  203,
+  124,
+  670,
+  62,
+  544,
+  289,
+  240,
+  308,
+  333,
+  829,
+  758,
+  48,
+  339,
+  468,
+  795,
+  844,
+  212,
+  623,
+  954,
+  946,
+  951,
+  531,
+  119,
+  806,
+  153,
+  382,
+  632,
+  472,
+  665,
+  241,
+  794,
+  786,
+  436,
+  323,
+  840,
+  594,
+  95,
+  175,
+  134,
+  796,
+  940,
+  747,
+  997,
+  360,
+  755,
+  467,
+  711,
+  275,
+  449,
+  291,
+  217,
+  677,
+  446,
+  422,
+  225,
+  302,
+  8,
+  957,
+  836,
+  901,
+  37,
+  919,
+  426,
+  623,
+  94,
+  105,
+  654,
+  752,
+  464,
+  323,
+  877,
+  954,
+  228,
+  375,
+  752,
+  743,
+  349,
+  350,
+  181,
+  532,
+  97,
+  777,
+  935,
+  148,
+  433,
+  153,
+  973,
+  525,
+  131,
+  947,
+  752,
+  692,
+  927,
+  84,
+  270,
+  152,
+  62,
+  676,
+  772,
+  301,
+  542,
+  874,
+  841,
+  976,
+  442,
+  540,
+  397,
+  922,
+  430,
+  729,
+  328,
+  779,
+  624,
+  430,
+  783,
+  852,
+  691,
+  657,
+  553,
+  216,
+  941,
+  965,
+  248,
+  656,
+  952,
+  514,
+  250,
+  890,
+  502,
+  392,
+  951,
+  357,
+  453,
+  744,
+  557,
+  940,
+  738,
+  207,
+  960,
+  612,
+  410,
+  688,
+  517,
+  612,
+  723,
+  773,
+  269,
+  176,
+  305,
+  210,
+  455,
+  178,
+  764,
+  414,
+  918,
+  958,
+  727,
+  54,
+  74,
+  191,
+  371,
+  376,
+  770,
+  275,
+  82,
+  913,
+  527,
+  249,
+  800,
+  675,
+  387,
+  810,
+  388,
+  503,
+  240,
+  491,
+  28,
+  491,
+  110,
+  133,
+  734,
+  720,
+  476,
+  943,
+  315,
+  810,
+  672,
+  761,
+  421,
+  269,
+  449,
+  677,
+  98,
+  912,
+  873,
+  36,
+  313,
+  585,
+  401,
+  35,
+  248,
+  301,
+  668,
+  136,
+  88,
+  514,
+  765,
+  68,
+  160,
+  267,
+  325,
+  663,
+  511,
+  927,
+  524,
+  243,
+  22,
+  126,
+  193,
+  846,
+  233,
+  289,
+  676,
+  783,
+  957,
+  845,
+  673,
+  692,
+  285,
+  763,
+  575,
+  742,
+  791,
+  744,
+  630,
+  650,
+  435,
+  748,
+  128,
+  612,
+  892,
+  729,
+  230,
+  818,
+  271,
+  634,
+  875,
+  930,
+  576,
+  333,
+  589,
+  849,
+  116,
+  143,
+  383,
+  705,
+  321,
+  218,
+  620,
+  142,
+  602,
+  477,
+  31,
+  550,
+  407,
+  552,
+  766,
+  851,
+  17,
+  123,
+  828,
+  678,
+  986,
+  66,
+  629,
+  393,
+  595,
+  319,
+  404,
+  352,
+  95,
+  140,
+  329,
+  357,
+  197,
+  571,
+  46,
+  8,
+  251,
+  628,
+  0,
+  327,
+  965,
+  938,
+  187,
+  95,
+  925,
+  514,
+  566,
+  95,
+  301,
+  153,
+  166,
+  526,
+  648,
+  41,
+  663,
+  145,
+  534,
+  712,
+  452,
+  770,
+  326,
+  518,
+  767,
+  743,
+  726,
+  560,
+  301,
+  198,
+  253,
+  702,
+  177,
+  619,
+  698,
+  645,
+  696,
+  622,
+  686,
+  401,
+  644,
+  124,
+  276,
+  707,
+  746,
+  136,
+  48,
+  275,
+  263,
+  285,
+  301,
+  59,
+  367,
+  802,
+  225,
+  719,
+  334,
+  91,
+  899,
+  836,
+  39,
+  801,
+  797,
+  52,
+  769,
+  941,
+  404,
+  667,
+  842,
+  726,
+  652,
+  538,
+  68,
+  780,
+  305,
+  694,
+  212,
+  208,
+  576,
+  35,
+  505,
+  26,
+  939,
+  402,
+  977,
+  342,
+  4,
+  436,
+  287,
+  861,
+  465,
+  898,
+  593,
+  691,
+  341,
+  595,
+  526,
+  722,
+  464,
+  273,
+  301,
+  51,
+  148,
+  888,
+  16,
+  548,
+  760,
+  252,
+  855,
+  690,
+  754,
+  886,
+  625,
+  404,
+  861,
+  546,
+  558,
+  201,
+  715,
+  800,
+  24,
+  464,
+  763,
+  181,
+  111,
+  42,
+  899,
+  398,
+  995,
+  166,
+  769,
+  737,
+  196,
+  1,
+  99,
+  136,
+  62,
+  335,
+  351,
+  346,
+  289,
+  899,
+  124,
+  607,
+  468,
+  686,
+  775,
+  991,
+  561,
+  335,
+  250,
+  880,
+  252,
+  56,
+  390,
+  363,
+  965,
+  233,
+  98,
+  954,
+  669,
+  596,
+  836,
+  912,
+  645,
+  516,
+  891,
+  340,
+  529,
+  722,
+  391,
+  580,
+  212,
+  501,
+  961,
+  154,
+  117,
+  877,
+  956,
+  245,
+  543,
+  749,
+  229,
+  959,
+  415,
+  3,
+  886,
+  430,
+  294,
+  501,
+  957,
+  218,
+  686,
+  825,
+  508,
+  746,
+  186,
+  624,
+  450,
+  123,
+  310,
+  161,
+  775,
+  581,
+  541,
+  630,
+  788,
+  652,
+  849,
+  101,
+  81,
+  872,
+  316,
+  621,
+  8,
+  17,
+  934,
+  555,
+  326,
+  252,
+  104,
+  720,
+  706,
+  130,
+  364,
+  56,
+  558,
+  83,
+  928,
+  538,
+  227,
+  366,
+  463,
+  527,
+  769,
+  19,
+  815,
+  801,
+  899,
+  72,
+  970,
+  25,
+  993,
+  340,
+  724,
+  765,
+  167,
+  347,
+  803,
+  148,
+  363,
+  967,
+  325,
+  927,
+  588,
+  791,
+  579,
+  647,
+  245,
+  767,
+  522,
+  989,
+  49,
+  619,
+  794,
+  385,
+  865,
+  665,
+  136,
+  426,
+  849,
+  354,
+  982,
+  870,
+  328,
+  181,
+  922,
+  304,
+  822,
+  665,
+  956,
+  324,
+  168,
+  412,
+  785,
+  919,
+  486,
+  340,
+  677,
+  751,
+  646,
+  857,
+  629,
+  108,
+  650,
+  366,
+  931,
+  195,
+  684,
+  498,
+  266,
+  669,
+  73,
+  103,
+  512,
+  456,
+  187,
+  190,
+  356,
+  146,
+  361,
+  597,
+  277,
+  261,
+  993,
+  479,
+  850,
+  883,
+  950,
+  622,
+  192,
+  351,
+  293,
+  375,
+  86,
+  141,
+  824,
+  714,
+  492,
+  48,
+  589,
+  564,
+  266,
+  359,
+  425,
+  75,
+  797,
+  538,
+  550,
+  885,
+  404,
+  863,
+  468,
+  301,
+  321,
+  475,
+  876,
+  916,
+  666,
+  927,
+  31,
+  256,
+  839,
+  177,
+  61,
+  875,
+  23,
+  348,
+  257,
+  939,
+  931,
+  533,
+  473,
+  865,
+  108,
+  130,
+  772,
+  296,
+  768,
+  721,
+  908,
+  108,
+  727,
+  659,
+  811,
+  821,
+  971,
+  652,
+  546,
+  727,
+  678,
+  767,
+  229,
+  606,
+  503,
+  298,
+  186,
+  539,
+  4,
+  203,
+  752,
+  630,
+  179,
+  182,
+  476,
+  366,
+  651,
+  924,
+  38,
+  925,
+  37,
+  177,
+  658,
+  489,
+  816,
+  322,
+  963,
+  928,
+  818,
+  169,
+  602,
+  403,
+  506,
+  127,
+  844,
+  749,
+  674,
+  845,
+  529,
+  865,
+  635,
+  791,
+  776,
+  334,
+  136,
+  342,
+  593,
+  512,
+  660,
+  640,
+  787,
+  139,
+  544,
+  181,
+  43,
+  46,
+  413,
+  337,
+  854,
+  986,
+  815,
+  121,
+  877,
+  294,
+  218,
+  4,
+  136,
+  225,
+  766,
+  992,
+  910,
+  530,
+  646,
+  213,
+  695,
+  271,
+  967,
+  986,
+  628,
+  777,
+  180,
+  866,
+  599,
+  664,
+  46,
+  994,
+  396,
+  56,
+  256,
+  739,
+  481,
+  608,
+  360,
+  134,
+  970,
+  282,
+  898,
+  417,
+  948,
+  956,
+  230,
+  884,
+  748,
+  74,
+  938,
+  224,
+  920,
+  974,
+  475,
+  405,
+  442,
+  630,
+  596,
+  118,
+  398,
+  439,
+  969,
+  188,
+  169,
+  251,
+  630,
+  835,
+  480,
+  557,
+  904,
+  461,
+  371,
+  885,
+  197,
+  305,
+  678,
+  12,
+  663,
+  960,
+  311,
+  877,
+  747,
+  20,
+  271,
+  622,
+  48,
+  621,
+  135,
+  59,
+  179,
+  377,
+  684,
+  861,
+  760,
+  38,
+  780,
+  91,
+  18,
+  23,
+  432,
+  37,
+  443,
+  450,
+  508,
+  193,
+  960,
+  986,
+  761,
+  605,
+  788,
+  86,
+  436,
+  23,
+  581,
+  605,
+  128,
+  84,
+  979,
+  732,
+  230,
+  787,
+  836,
+  261,
+  677,
+  117,
+  292,
+  477,
+  388,
+  20,
+  962,
+  707,
+  979,
+  933,
+  662,
+  112,
+  234,
+  771,
+  167,
+  31,
+  673,
+  42,
+  705,
+  675,
+  151,
+  452,
+  875,
+  655,
+  399,
+  59,
+  702,
+  502,
+  444,
+  892,
+  290,
+  856,
+  53,
+  260,
+  19,
+  221,
+  987,
+  330,
+  80,
+  665,
+  551,
+  377,
+  540,
+  188,
+  920,
+  680,
+  133,
+  77,
+  466,
+  439,
+  258,
+  570,
+  659,
+  56,
+  10,
+  615,
+  504,
+  336,
+  655,
+  720,
+  156,
+  289,
+  354,
+  637,
+  184,
+  853,
+  944,
+  177,
+  973,
+  177,
+  537,
+  934,
+  78,
+  267,
+  209,
+  898,
+  115,
+  986,
+  920,
+  926,
+  393,
+  217,
+  204,
+  312,
+  989,
+  655,
+  214,
+  47,
+  231,
+  278,
+  866,
+  734,
+  707,
+  605,
+  208,
+  232,
+  506,
+  116,
+  383,
+  662,
+  151,
+  92,
+  785,
+  431,
+  614,
+  585,
+  682,
+  781,
+  343,
+  590,
+  458,
+  232,
+  360,
+  187,
+  18,
+  769,
+  704,
+  620,
+  67,
+  109,
+  88,
+  353,
+  401,
+  228,
+  508,
+  406,
+  255,
+  989,
+  151,
+  702,
+  277,
+  376,
+  381,
+  409,
+  932,
+  31,
+  761,
+  783,
+  233,
+  154,
+  871,
+  55,
+  648,
+  5,
+  12,
+  465,
+  96,
+  904,
+  169,
+  325,
+  428,
+  572,
+  47,
+  78,
+  258,
+  525,
+  276,
+  502,
+  972,
+  488,
+  763,
+  798,
+  973,
+  186,
+  490,
+  362,
+  205,
+  154,
+  245,
+  784,
+  493,
+  76,
+  975,
+  459,
+  598,
+  227,
+  161,
+  752,
+  243,
+  858,
+  931,
+  996,
+  543,
+  488,
+  560,
+  240,
+  49,
+  318,
+  374,
+  914,
+  52,
+  693,
+  762,
+  329,
+  691,
+  193,
+  122,
+  925,
+  577,
+  748,
+  236,
+  8,
+  591,
+  640,
+  61,
+  77,
+  295,
+  117,
+  323,
+  732,
+  493,
+  811,
+  67,
+  694,
+  158,
+  589,
+  247,
+  115,
+  184,
+  682,
+  927,
+  918,
+  353,
+  217,
+  904,
+  834,
+  107,
+  728,
+  683,
+  908,
+  596,
+  721,
+  44,
+  412,
+  780,
+  882,
+  682,
+  497,
+  832,
+  559,
+  126,
+  303,
+  100,
+  214,
+  829,
+  344,
+  654,
+  679,
+  336,
+  148,
+  213,
+  982,
+  859,
+  558,
+  855,
+  999,
+  698,
+  38,
+  490,
+  340,
+  846,
+  852,
+  26,
+  942,
+  575,
+  383,
+  1,
+  198,
+  836,
+  570,
+  893,
+  950,
+  7,
+  527,
+  628,
+  753,
+  660,
+  180,
+  354,
+  819,
+  775,
+  271,
+  187,
+  374,
+  532,
+  374,
+  900
+};
+const int idx[10004] = {
+  13,
+  111,
+  124,
+  218,
+  316,
+  502,
+  34,
+  119,
+  167,
+  180,
+  186,
+  346,
+  511,
+  543,
+  755,
+  788,
+  833,
+  929,
+  46,
+  109,
+  154,
+  220,
+  248,
+  448,
+  509,
+  517,
+  530,
+  557,
+  639,
+  643,
+  720,
+  137,
+  189,
+  424,
+  480,
+  570,
+  642,
+  849,
+  896,
+  968,
+  117,
+  136,
+  208,
+  248,
+  347,
+  410,
+  433,
+  515,
+  747,
+  144,
+  148,
+  375,
+  405,
+  444,
+  532,
+  788,
+  808,
+  987,
+  110,
+  112,
+  403,
+  415,
+  596,
+  612,
+  669,
+  794,
+  851,
+  80,
+  285,
+  288,
+  433,
+  500,
+  628,
+  982,
+  999,
+  57,
+  237,
+  252,
+  304,
+  469,
+  600,
+  609,
+  621,
+  741,
+  798,
+  251,
+  322,
+  369,
+  374,
+  376,
+  507,
+  623,
+  666,
+  669,
+  677,
+  707,
+  823,
+  919,
+  63,
+  187,
+  266,
+  360,
+  396,
+  439,
+  459,
+  526,
+  623,
+  804,
+  857,
+  881,
+  948,
+  160,
+  165,
+  226,
+  446,
+  538,
+  585,
+  624,
+  866,
+  975,
+  979,
+  18,
+  54,
+  151,
+  180,
+  230,
+  298,
+  480,
+  678,
+  688,
+  696,
+  742,
+  757,
+  889,
+  979,
+  100,
+  245,
+  513,
+  925,
+  162,
+  413,
+  427,
+  588,
+  645,
+  807,
+  853,
+  194,
+  313,
+  339,
+  466,
+  539,
+  581,
+  732,
+  791,
+  832,
+  927,
+  954,
+  962,
+  966,
+  42,
+  45,
+  138,
+  141,
+  239,
+  338,
+  584,
+  696,
+  912,
+  929,
+  269,
+  352,
+  443,
+  463,
+  896,
+  962,
+  60,
+  92,
+  273,
+  568,
+  591,
+  851,
+  38,
+  77,
+  281,
+  362,
+  544,
+  614,
+  651,
+  836,
+  871,
+  873,
+  45,
+  61,
+  140,
+  153,
+  234,
+  439,
+  472,
+  509,
+  588,
+  675,
+  760,
+  777,
+  178,
+  198,
+  248,
+  517,
+  566,
+  679,
+  700,
+  289,
+  455,
+  602,
+  695,
+  711,
+  853,
+  923,
+  179,
+  199,
+  214,
+  280,
+  343,
+  405,
+  435,
+  504,
+  898,
+  910,
+  939,
+  130,
+  219,
+  296,
+  445,
+  508,
+  634,
+  763,
+  918,
+  922,
+  978,
+  87,
+  285,
+  614,
+  667,
+  679,
+  739,
+  834,
+  192,
+  347,
+  549,
+  557,
+  724,
+  764,
+  928,
+  929,
+  976,
+  17,
+  283,
+  413,
+  429,
+  612,
+  683,
+  707,
+  725,
+  743,
+  833,
+  856,
+  165,
+  267,
+  304,
+  361,
+  397,
+  410,
+  570,
+  683,
+  766,
+  788,
+  849,
+  882,
+  885,
+  30,
+  58,
+  221,
+  254,
+  453,
+  457,
+  470,
+  674,
+  687,
+  745,
+  809,
+  819,
+  55,
+  121,
+  231,
+  538,
+  604,
+  718,
+  768,
+  960,
+  71,
+  77,
+  104,
+  186,
+  205,
+  234,
+  456,
+  467,
+  579,
+  682,
+  733,
+  767,
+  947,
+  66,
+  86,
+  157,
+  290,
+  422,
+  441,
+  473,
+  560,
+  607,
+  640,
+  682,
+  888,
+  37,
+  296,
+  439,
+  629,
+  642,
+  733,
+  824,
+  917,
+  969,
+  4,
+  25,
+  580,
+  622,
+  636,
+  666,
+  672,
+  732,
+  802,
+  921,
+  943,
+  130,
+  194,
+  245,
+  273,
+  323,
+  344,
+  603,
+  740,
+  795,
+  974,
+  189,
+  422,
+  445,
+  446,
+  831,
+  905,
+  912,
+  36,
+  60,
+  218,
+  428,
+  455,
+  627,
+  743,
+  796,
+  801,
+  903,
+  136,
+  152,
+  166,
+  352,
+  364,
+  369,
+  382,
+  466,
+  521,
+  577,
+  665,
+  746,
+  910,
+  294,
+  345,
+  445,
+  645,
+  686,
+  718,
+  757,
+  762,
+  796,
+  817,
+  832,
+  836,
+  997,
+  127,
+  258,
+  259,
+  449,
+  541,
+  643,
+  665,
+  756,
+  817,
+  854,
+  870,
+  89,
+  134,
+  188,
+  362,
+  408,
+  531,
+  566,
+  816,
+  127,
+  170,
+  302,
+  336,
+  426,
+  434,
+  601,
+  708,
+  774,
+  780,
+  900,
+  935,
+  377,
+  469,
+  618,
+  650,
+  790,
+  809,
+  78,
+  253,
+  340,
+  382,
+  586,
+  673,
+  684,
+  282,
+  354,
+  363,
+  398,
+  636,
+  655,
+  729,
+  885,
+  911,
+  10,
+  175,
+  195,
+  229,
+  273,
+  339,
+  380,
+  531,
+  660,
+  681,
+  794,
+  800,
+  236,
+  416,
+  646,
+  679,
+  685,
+  885,
+  7,
+  116,
+  299,
+  481,
+  702,
+  747,
+  922,
+  64,
+  153,
+  374,
+  391,
+  532,
+  558,
+  602,
+  655,
+  662,
+  804,
+  847,
+  867,
+  998,
+  45,
+  66,
+  97,
+  106,
+  236,
+  240,
+  247,
+  453,
+  641,
+  646,
+  711,
+  712,
+  715,
+  855,
+  906,
+  923,
+  37,
+  65,
+  122,
+  331,
+  578,
+  589,
+  610,
+  139,
+  293,
+  354,
+  395,
+  430,
+  486,
+  589,
+  614,
+  661,
+  699,
+  846,
+  910,
+  18,
+  53,
+  78,
+  234,
+  296,
+  690,
+  828,
+  923,
+  87,
+  115,
+  156,
+  161,
+  173,
+  201,
+  400,
+  474,
+  501,
+  526,
+  782,
+  861,
+  63,
+  271,
+  427,
+  552,
+  590,
+  657,
+  920,
+  41,
+  194,
+  281,
+  571,
+  640,
+  681,
+  696,
+  301,
+  306,
+  514,
+  553,
+  560,
+  641,
+  683,
+  762,
+  812,
+  818,
+  876,
+  904,
+  932,
+  978,
+  38,
+  62,
+  98,
+  103,
+  370,
+  390,
+  531,
+  559,
+  693,
+  813,
+  924,
+  943,
+  955,
+  973,
+  13,
+  40,
+  62,
+  75,
+  396,
+  419,
+  615,
+  773,
+  968,
+  989,
+  150,
+  183,
+  241,
+  261,
+  407,
+  476,
+  492,
+  524,
+  541,
+  863,
+  994,
+  156,
+  195,
+  197,
+  278,
+  457,
+  467,
+  610,
+  621,
+  956,
+  49,
+  343,
+  454,
+  477,
+  572,
+  600,
+  700,
+  759,
+  804,
+  923,
+  92,
+  194,
+  455,
+  842,
+  968,
+  160,
+  211,
+  461,
+  463,
+  467,
+  622,
+  854,
+  972,
+  333,
+  469,
+  563,
+  571,
+  639,
+  838,
+  977,
+  18,
+  105,
+  133,
+  258,
+  572,
+  720,
+  804,
+  851,
+  930,
+  19,
+  139,
+  158,
+  301,
+  354,
+  407,
+  589,
+  726,
+  846,
+  904,
+  26,
+  54,
+  155,
+  212,
+  216,
+  418,
+  534,
+  647,
+  792,
+  862,
+  889,
+  101,
+  216,
+  228,
+  396,
+  470,
+  473,
+  592,
+  706,
+  799,
+  913,
+  922,
+  98,
+  324,
+  524,
+  672,
+  685,
+  856,
+  213,
+  224,
+  228,
+  300,
+  395,
+  604,
+  631,
+  651,
+  835,
+  944,
+  289,
+  574,
+  613,
+  657,
+  671,
+  748,
+  763,
+  768,
+  815,
+  843,
+  908,
+  74,
+  79,
+  203,
+  218,
+  245,
+  249,
+  390,
+  548,
+  616,
+  804,
+  986,
+  49,
+  196,
+  585,
+  591,
+  608,
+  728,
+  750,
+  810,
+  836,
+  920,
+  980,
+  38,
+  41,
+  93,
+  94,
+  320,
+  360,
+  502,
+  555,
+  729,
+  742,
+  814,
+  984,
+  89,
+  131,
+  499,
+  677,
+  825,
+  846,
+  919,
+  966,
+  17,
+  37,
+  121,
+  168,
+  560,
+  585,
+  691,
+  788,
+  892,
+  925,
+  951,
+  995,
+  13,
+  69,
+  124,
+  229,
+  308,
+  554,
+  643,
+  668,
+  717,
+  747,
+  813,
+  814,
+  864,
+  298,
+  327,
+  386,
+  425,
+  586,
+  600,
+  725,
+  730,
+  832,
+  12,
+  38,
+  94,
+  150,
+  175,
+  501,
+  538,
+  552,
+  571,
+  606,
+  624,
+  650,
+  686,
+  728,
+  157,
+  605,
+  630,
+  713,
+  784,
+  850,
+  954,
+  181,
+  234,
+  610,
+  612,
+  661,
+  663,
+  677,
+  688,
+  726,
+  809,
+  818,
+  67,
+  77,
+  164,
+  193,
+  214,
+  345,
+  352,
+  551,
+  696,
+  919,
+  994,
+  12,
+  311,
+  404,
+  454,
+  473,
+  521,
+  581,
+  651,
+  677,
+  717,
+  850,
+  873,
+  880,
+  892,
+  945,
+  54,
+  138,
+  210,
+  219,
+  248,
+  413,
+  480,
+  491,
+  639,
+  652,
+  773,
+  807,
+  824,
+  962,
+  79,
+  211,
+  499,
+  560,
+  561,
+  759,
+  774,
+  800,
+  865,
+  35,
+  146,
+  619,
+  746,
+  754,
+  81,
+  237,
+  258,
+  388,
+  477,
+  658,
+  704,
+  712,
+  781,
+  109,
+  720,
+  758,
+  98,
+  209,
+  252,
+  311,
+  410,
+  532,
+  611,
+  656,
+  722,
+  772,
+  822,
+  828,
+  912,
+  980,
+  95,
+  107,
+  167,
+  287,
+  289,
+  303,
+  441,
+  446,
+  580,
+  600,
+  630,
+  632,
+  658,
+  682,
+  847,
+  92,
+  137,
+  177,
+  238,
+  262,
+  324,
+  438,
+  479,
+  534,
+  539,
+  689,
+  846,
+  956,
+  962,
+  200,
+  496,
+  521,
+  656,
+  714,
+  785,
+  814,
+  857,
+  184,
+  204,
+  455,
+  702,
+  754,
+  803,
+  887,
+  928,
+  993,
+  42,
+  51,
+  189,
+  204,
+  358,
+  572,
+  601,
+  665,
+  867,
+  71,
+  108,
+  208,
+  243,
+  263,
+  314,
+  359,
+  418,
+  482,
+  556,
+  680,
+  945,
+  958,
+  964,
+  97,
+  200,
+  202,
+  223,
+  230,
+  428,
+  447,
+  537,
+  574,
+  635,
+  663,
+  728,
+  737,
+  858,
+  861,
+  930,
+  71,
+  84,
+  85,
+  196,
+  199,
+  242,
+  513,
+  761,
+  48,
+  98,
+  127,
+  194,
+  233,
+  283,
+  334,
+  420,
+  627,
+  632,
+  931,
+  34,
+  82,
+  176,
+  197,
+  217,
+  235,
+  237,
+  358,
+  462,
+  947,
+  10,
+  178,
+  265,
+  350,
+  396,
+  468,
+  539,
+  586,
+  612,
+  628,
+  644,
+  791,
+  40,
+  234,
+  292,
+  299,
+  375,
+  396,
+  410,
+  429,
+  728,
+  36,
+  360,
+  475,
+  562,
+  962,
+  5,
+  60,
+  169,
+  509,
+  558,
+  594,
+  613,
+  648,
+  654,
+  726,
+  769,
+  773,
+  777,
+  40,
+  49,
+  403,
+  446,
+  524,
+  548,
+  730,
+  774,
+  938,
+  978,
+  997,
+  221,
+  248,
+  407,
+  447,
+  585,
+  756,
+  824,
+  894,
+  972,
+  121,
+  189,
+  364,
+  537,
+  563,
+  179,
+  328,
+  344,
+  692,
+  711,
+  750,
+  760,
+  780,
+  810,
+  929,
+  942,
+  106,
+  336,
+  551,
+  616,
+  640,
+  654,
+  726,
+  890,
+  74,
+  200,
+  233,
+  254,
+  382,
+  396,
+  895,
+  971,
+  283,
+  614,
+  898,
+  87,
+  122,
+  172,
+  255,
+  324,
+  383,
+  498,
+  525,
+  699,
+  817,
+  825,
+  3,
+  41,
+  104,
+  280,
+  399,
+  617,
+  641,
+  769,
+  789,
+  817,
+  891,
+  937,
+  143,
+  175,
+  185,
+  217,
+  222,
+  362,
+  391,
+  465,
+  515,
+  544,
+  818,
+  868,
+  35,
+  44,
+  122,
+  235,
+  345,
+  415,
+  479,
+  569,
+  575,
+  740,
+  765,
+  867,
+  967,
+  78,
+  107,
+  265,
+  358,
+  524,
+  646,
+  716,
+  720,
+  840,
+  76,
+  77,
+  353,
+  406,
+  533,
+  648,
+  726,
+  733,
+  906,
+  979,
+  65,
+  133,
+  182,
+  187,
+  191,
+  424,
+  430,
+  520,
+  674,
+  776,
+  945,
+  975,
+  18,
+  242,
+  393,
+  458,
+  468,
+  530,
+  599,
+  717,
+  933,
+  278,
+  297,
+  465,
+  476,
+  579,
+  591,
+  633,
+  643,
+  937,
+  271,
+  481,
+  618,
+  890,
+  5,
+  126,
+  171,
+  192,
+  209,
+  259,
+  367,
+  840,
+  861,
+  6,
+  26,
+  47,
+  90,
+  225,
+  239,
+  385,
+  577,
+  782,
+  795,
+  797,
+  893,
+  76,
+  82,
+  309,
+  348,
+  450,
+  583,
+  677,
+  696,
+  752,
+  785,
+  800,
+  991,
+  2,
+  191,
+  211,
+  279,
+  280,
+  556,
+  591,
+  774,
+  785,
+  822,
+  913,
+  34,
+  117,
+  159,
+  204,
+  266,
+  418,
+  547,
+  565,
+  962,
+  992,
+  33,
+  72,
+  140,
+  141,
+  157,
+  254,
+  513,
+  558,
+  643,
+  695,
+  779,
+  791,
+  882,
+  978,
+  13,
+  53,
+  65,
+  479,
+  513,
+  674,
+  687,
+  711,
+  785,
+  811,
+  830,
+  4,
+  5,
+  9,
+  34,
+  77,
+  137,
+  265,
+  270,
+  542,
+  552,
+  622,
+  632,
+  634,
+  647,
+  783,
+  895,
+  951,
+  995,
+  89,
+  113,
+  174,
+  225,
+  231,
+  258,
+  294,
+  347,
+  383,
+  414,
+  444,
+  463,
+  467,
+  493,
+  535,
+  612,
+  688,
+  107,
+  111,
+  213,
+  238,
+  494,
+  555,
+  572,
+  676,
+  40,
+  50,
+  59,
+  119,
+  291,
+  365,
+  416,
+  565,
+  607,
+  613,
+  631,
+  902,
+  908,
+  998,
+  63,
+  495,
+  534,
+  581,
+  601,
+  694,
+  719,
+  731,
+  790,
+  969,
+  176,
+  262,
+  481,
+  545,
+  694,
+  737,
+  853,
+  202,
+  267,
+  269,
+  302,
+  466,
+  727,
+  786,
+  816,
+  858,
+  923,
+  14,
+  241,
+  387,
+  416,
+  468,
+  501,
+  513,
+  599,
+  48,
+  157,
+  318,
+  426,
+  589,
+  632,
+  871,
+  882,
+  87,
+  444,
+  486,
+  558,
+  618,
+  773,
+  794,
+  73,
+  116,
+  199,
+  229,
+  233,
+  255,
+  360,
+  400,
+  425,
+  468,
+  474,
+  540,
+  589,
+  786,
+  834,
+  868,
+  888,
+  85,
+  112,
+  162,
+  185,
+  316,
+  331,
+  346,
+  410,
+  611,
+  729,
+  798,
+  863,
+  234,
+  591,
+  637,
+  933,
+  8,
+  12,
+  32,
+  43,
+  101,
+  339,
+  436,
+  708,
+  88,
+  111,
+  115,
+  790,
+  841,
+  935,
+  976,
+  12,
+  175,
+  245,
+  447,
+  449,
+  548,
+  581,
+  652,
+  743,
+  763,
+  773,
+  776,
+  828,
+  951,
+  58,
+  62,
+  68,
+  277,
+  297,
+  401,
+  418,
+  460,
+  482,
+  561,
+  656,
+  734,
+  812,
+  818,
+  837,
+  861,
+  118,
+  192,
+  254,
+  267,
+  270,
+  276,
+  347,
+  463,
+  509,
+  514,
+  714,
+  717,
+  788,
+  905,
+  924,
+  100,
+  256,
+  334,
+  335,
+  465,
+  627,
+  803,
+  815,
+  884,
+  996,
+  15,
+  140,
+  172,
+  197,
+  227,
+  300,
+  310,
+  466,
+  530,
+  560,
+  567,
+  784,
+  860,
+  15,
+  108,
+  132,
+  188,
+  310,
+  621,
+  838,
+  839,
+  988,
+  8,
+  130,
+  289,
+  462,
+  472,
+  549,
+  557,
+  561,
+  643,
+  753,
+  755,
+  841,
+  955,
+  40,
+  325,
+  334,
+  371,
+  375,
+  417,
+  573,
+  872,
+  921,
+  989,
+  25,
+  94,
+  138,
+  217,
+  312,
+  370,
+  528,
+  585,
+  603,
+  630,
+  729,
+  803,
+  810,
+  73,
+  424,
+  570,
+  624,
+  630,
+  642,
+  671,
+  697,
+  873,
+  935,
+  987,
+  94,
+  174,
+  318,
+  415,
+  507,
+  516,
+  676,
+  779,
+  821,
+  941,
+  973,
+  73,
+  78,
+  97,
+  148,
+  237,
+  269,
+  293,
+  304,
+  483,
+  575,
+  591,
+  916,
+  64,
+  228,
+  238,
+  269,
+  287,
+  400,
+  633,
+  749,
+  114,
+  173,
+  311,
+  400,
+  454,
+  634,
+  644,
+  726,
+  731,
+  860,
+  921,
+  224,
+  262,
+  367,
+  401,
+  504,
+  589,
+  630,
+  727,
+  848,
+  161,
+  392,
+  401,
+  410,
+  530,
+  548,
+  787,
+  894,
+  989,
+  121,
+  372,
+  437,
+  676,
+  929,
+  976,
+  980,
+  111,
+  365,
+  706,
+  954,
+  82,
+  379,
+  563,
+  728,
+  949,
+  124,
+  227,
+  540,
+  671,
+  767,
+  861,
+  484,
+  678,
+  840,
+  864,
+  916,
+  304,
+  348,
+  502,
+  599,
+  617,
+  657,
+  82,
+  149,
+  163,
+  216,
+  229,
+  449,
+  612,
+  620,
+  636,
+  673,
+  679,
+  756,
+  802,
+  859,
+  953,
+  142,
+  176,
+  215,
+  273,
+  335,
+  415,
+  586,
+  658,
+  682,
+  764,
+  865,
+  896,
+  923,
+  76,
+  283,
+  284,
+  464,
+  481,
+  588,
+  625,
+  742,
+  790,
+  947,
+  119,
+  186,
+  309,
+  320,
+  404,
+  407,
+  440,
+  496,
+  692,
+  853,
+  884,
+  901,
+  980,
+  990,
+  345,
+  493,
+  503,
+  691,
+  738,
+  743,
+  890,
+  929,
+  993,
+  998,
+  45,
+  272,
+  313,
+  350,
+  384,
+  452,
+  499,
+  569,
+  248,
+  346,
+  515,
+  676,
+  751,
+  755,
+  775,
+  778,
+  17,
+  491,
+  522,
+  538,
+  622,
+  672,
+  919,
+  961,
+  54,
+  126,
+  207,
+  301,
+  375,
+  447,
+  500,
+  599,
+  651,
+  683,
+  890,
+  947,
+  93,
+  317,
+  482,
+  656,
+  774,
+  865,
+  904,
+  96,
+  224,
+  260,
+  313,
+  340,
+  372,
+  410,
+  437,
+  452,
+  511,
+  512,
+  718,
+  911,
+  77,
+  100,
+  176,
+  232,
+  418,
+  661,
+  689,
+  805,
+  956,
+  51,
+  262,
+  280,
+  352,
+  380,
+  413,
+  461,
+  538,
+  616,
+  769,
+  783,
+  821,
+  855,
+  946,
+  956,
+  73,
+  169,
+  238,
+  246,
+  319,
+  391,
+  392,
+  669,
+  769,
+  770,
+  786,
+  946,
+  415,
+  453,
+  590,
+  628,
+  630,
+  684,
+  852,
+  52,
+  258,
+  318,
+  322,
+  535,
+  545,
+  561,
+  610,
+  621,
+  662,
+  687,
+  839,
+  87,
+  98,
+  181,
+  269,
+  454,
+  666,
+  667,
+  684,
+  891,
+  142,
+  270,
+  300,
+  396,
+  398,
+  443,
+  652,
+  677,
+  821,
+  0,
+  77,
+  85,
+  163,
+  180,
+  281,
+  470,
+  491,
+  665,
+  694,
+  760,
+  899,
+  992,
+  32,
+  51,
+  73,
+  75,
+  157,
+  216,
+  224,
+  301,
+  376,
+  433,
+  536,
+  612,
+  703,
+  11,
+  228,
+  456,
+  471,
+  543,
+  627,
+  650,
+  873,
+  898,
+  144,
+  258,
+  597,
+  796,
+  36,
+  394,
+  486,
+  492,
+  497,
+  681,
+  710,
+  963,
+  522,
+  582,
+  709,
+  769,
+  775,
+  987,
+  80,
+  129,
+  156,
+  281,
+  339,
+  346,
+  402,
+  777,
+  789,
+  812,
+  822,
+  859,
+  108,
+  127,
+  207,
+  293,
+  337,
+  385,
+  415,
+  479,
+  509,
+  539,
+  746,
+  785,
+  929,
+  934,
+  943,
+  27,
+  52,
+  55,
+  67,
+  124,
+  298,
+  381,
+  625,
+  690,
+  741,
+  975,
+  26,
+  112,
+  127,
+  152,
+  225,
+  513,
+  534,
+  672,
+  734,
+  766,
+  968,
+  26,
+  87,
+  123,
+  198,
+  266,
+  279,
+  410,
+  445,
+  612,
+  791,
+  807,
+  946,
+  996,
+  287,
+  417,
+  458,
+  515,
+  562,
+  576,
+  725,
+  750,
+  779,
+  92,
+  136,
+  168,
+  174,
+  213,
+  300,
+  392,
+  541,
+  602,
+  618,
+  729,
+  761,
+  960,
+  2,
+  340,
+  378,
+  414,
+  441,
+  575,
+  632,
+  731,
+  791,
+  870,
+  875,
+  2,
+  176,
+  241,
+  307,
+  436,
+  707,
+  912,
+  929,
+  962,
+  232,
+  300,
+  389,
+  397,
+  400,
+  483,
+  547,
+  628,
+  766,
+  781,
+  783,
+  833,
+  981,
+  193,
+  200,
+  224,
+  681,
+  739,
+  750,
+  25,
+  404,
+  409,
+  420,
+  511,
+  621,
+  623,
+  857,
+  909,
+  144,
+  179,
+  221,
+  223,
+  400,
+  413,
+  483,
+  507,
+  516,
+  609,
+  806,
+  869,
+  995,
+  1,
+  194,
+  270,
+  433,
+  450,
+  549,
+  591,
+  794,
+  872,
+  106,
+  125,
+  136,
+  207,
+  239,
+  432,
+  529,
+  588,
+  634,
+  869,
+  936,
+  61,
+  70,
+  156,
+  171,
+  172,
+  272,
+  582,
+  594,
+  943,
+  310,
+  445,
+  589,
+  752,
+  769,
+  775,
+  778,
+  901,
+  76,
+  130,
+  151,
+  165,
+  236,
+  473,
+  503,
+  558,
+  794,
+  804,
+  945,
+  953,
+  971,
+  2,
+  4,
+  44,
+  150,
+  167,
+  190,
+  209,
+  658,
+  747,
+  934,
+  75,
+  156,
+  315,
+  528,
+  697,
+  760,
+  156,
+  165,
+  232,
+  644,
+  680,
+  686,
+  771,
+  846,
+  100,
+  197,
+  377,
+  497,
+  658,
+  674,
+  685,
+  716,
+  759,
+  890,
+  1,
+  18,
+  104,
+  318,
+  462,
+  643,
+  793,
+  930,
+  999,
+  104,
+  112,
+  141,
+  231,
+  255,
+  414,
+  419,
+  651,
+  754,
+  900,
+  914,
+  965,
+  969,
+  43,
+  275,
+  386,
+  410,
+  419,
+  480,
+  607,
+  649,
+  688,
+  763,
+  850,
+  149,
+  184,
+  326,
+  434,
+  485,
+  599,
+  618,
+  786,
+  915,
+  54,
+  113,
+  195,
+  358,
+  383,
+  489,
+  564,
+  788,
+  840,
+  887,
+  219,
+  232,
+  351,
+  373,
+  691,
+  777,
+  42,
+  58,
+  124,
+  272,
+  297,
+  571,
+  583,
+  590,
+  618,
+  734,
+  867,
+  60,
+  90,
+  174,
+  217,
+  339,
+  423,
+  531,
+  640,
+  707,
+  767,
+  798,
+  896,
+  981,
+  208,
+  304,
+  402,
+  657,
+  959,
+  197,
+  242,
+  348,
+  373,
+  409,
+  449,
+  489,
+  529,
+  545,
+  577,
+  812,
+  844,
+  853,
+  956,
+  114,
+  128,
+  137,
+  254,
+  386,
+  401,
+  424,
+  425,
+  470,
+  509,
+  735,
+  835,
+  872,
+  899,
+  29,
+  49,
+  189,
+  201,
+  495,
+  517,
+  598,
+  669,
+  712,
+  734,
+  794,
+  903,
+  32,
+  34,
+  191,
+  411,
+  499,
+  542,
+  581,
+  593,
+  748,
+  823,
+  878,
+  99,
+  169,
+  439,
+  522,
+  729,
+  879,
+  31,
+  97,
+  195,
+  273,
+  314,
+  496,
+  498,
+  863,
+  55,
+  75,
+  100,
+  153,
+  198,
+  404,
+  459,
+  664,
+  800,
+  877,
+  919,
+  999,
+  97,
+  252,
+  330,
+  477,
+  572,
+  663,
+  687,
+  707,
+  726,
+  778,
+  822,
+  905,
+  909,
+  62,
+  285,
+  353,
+  384,
+  564,
+  578,
+  626,
+  669,
+  34,
+  82,
+  303,
+  585,
+  614,
+  682,
+  816,
+  896,
+  917,
+  971,
+  198,
+  200,
+  255,
+  508,
+  524,
+  640,
+  789,
+  840,
+  855,
+  125,
+  177,
+  277,
+  332,
+  491,
+  513,
+  514,
+  526,
+  619,
+  626,
+  651,
+  730,
+  735,
+  795,
+  999,
+  91,
+  141,
+  279,
+  457,
+  617,
+  717,
+  24,
+  26,
+  255,
+  270,
+  314,
+  333,
+  425,
+  493,
+  518,
+  626,
+  900,
+  943,
+  161,
+  381,
+  386,
+  412,
+  688,
+  795,
+  970,
+  999,
+  51,
+  77,
+  123,
+  193,
+  225,
+  227,
+  340,
+  757,
+  826,
+  901,
+  927,
+  938,
+  972,
+  180,
+  304,
+  358,
+  508,
+  531,
+  997,
+  46,
+  99,
+  182,
+  354,
+  653,
+  661,
+  749,
+  765,
+  766,
+  911,
+  50,
+  320,
+  365,
+  604,
+  720,
+  812,
+  60,
+  91,
+  196,
+  249,
+  492,
+  525,
+  671,
+  681,
+  724,
+  801,
+  813,
+  936,
+  34,
+  221,
+  318,
+  353,
+  490,
+  557,
+  584,
+  640,
+  801,
+  152,
+  253,
+  264,
+  314,
+  567,
+  587,
+  888,
+  898,
+  238,
+  263,
+  269,
+  386,
+  446,
+  578,
+  613,
+  632,
+  853,
+  893,
+  193,
+  311,
+  391,
+  604,
+  638,
+  780,
+  786,
+  890,
+  909,
+  931,
+  25,
+  152,
+  201,
+  221,
+  222,
+  345,
+  358,
+  442,
+  578,
+  622,
+  640,
+  711,
+  748,
+  979,
+  474,
+  479,
+  541,
+  963,
+  193,
+  202,
+  264,
+  365,
+  512,
+  648,
+  992,
+  60,
+  135,
+  327,
+  330,
+  355,
+  400,
+  434,
+  556,
+  561,
+  691,
+  760,
+  810,
+  848,
+  3,
+  25,
+  372,
+  421,
+  555,
+  618,
+  678,
+  723,
+  790,
+  850,
+  876,
+  947,
+  47,
+  179,
+  253,
+  284,
+  588,
+  608,
+  615,
+  688,
+  732,
+  746,
+  753,
+  923,
+  997,
+  70,
+  197,
+  212,
+  281,
+  360,
+  588,
+  897,
+  994,
+  140,
+  146,
+  209,
+  212,
+  321,
+  427,
+  581,
+  736,
+  744,
+  755,
+  848,
+  913,
+  15,
+  183,
+  733,
+  792,
+  804,
+  848,
+  854,
+  6,
+  13,
+  42,
+  187,
+  211,
+  465,
+  567,
+  741,
+  755,
+  858,
+  955,
+  36,
+  56,
+  131,
+  213,
+  352,
+  377,
+  393,
+  405,
+  520,
+  543,
+  729,
+  826,
+  865,
+  42,
+  66,
+  80,
+  116,
+  322,
+  463,
+  768,
+  866,
+  981,
+  105,
+  252,
+  513,
+  613,
+  652,
+  788,
+  199,
+  245,
+  609,
+  673,
+  703,
+  770,
+  863,
+  868,
+  34,
+  432,
+  522,
+  571,
+  641,
+  649,
+  804,
+  842,
+  934,
+  24,
+  25,
+  88,
+  322,
+  369,
+  423,
+  598,
+  632,
+  675,
+  711,
+  969,
+  161,
+  274,
+  320,
+  377,
+  434,
+  705,
+  749,
+  753,
+  850,
+  881,
+  134,
+  158,
+  235,
+  245,
+  346,
+  383,
+  422,
+  425,
+  594,
+  598,
+  735,
+  750,
+  876,
+  988,
+  144,
+  183,
+  191,
+  344,
+  460,
+  522,
+  527,
+  529,
+  537,
+  619,
+  711,
+  812,
+  852,
+  901,
+  979,
+  100,
+  143,
+  653,
+  755,
+  759,
+  816,
+  23,
+  161,
+  188,
+  223,
+  266,
+  326,
+  726,
+  750,
+  802,
+  898,
+  998,
+  27,
+  178,
+  242,
+  269,
+  604,
+  870,
+  990,
+  137,
+  350,
+  424,
+  447,
+  553,
+  559,
+  580,
+  624,
+  677,
+  690,
+  751,
+  894,
+  922,
+  995,
+  41,
+  147,
+  178,
+  272,
+  357,
+  361,
+  415,
+  782,
+  891,
+  124,
+  149,
+  194,
+  473,
+  542,
+  687,
+  758,
+  776,
+  852,
+  935,
+  33,
+  63,
+  420,
+  25,
+  54,
+  134,
+  169,
+  216,
+  217,
+  315,
+  367,
+  378,
+  452,
+  535,
+  549,
+  598,
+  624,
+  683,
+  731,
+  882,
+  893,
+  203,
+  277,
+  470,
+  676,
+  686,
+  688,
+  711,
+  805,
+  880,
+  943,
+  74,
+  139,
+  158,
+  190,
+  216,
+  295,
+  380,
+  431,
+  436,
+  445,
+  514,
+  683,
+  713,
+  807,
+  809,
+  820,
+  845,
+  897,
+  991,
+  46,
+  227,
+  290,
+  462,
+  672,
+  901,
+  10,
+  76,
+  108,
+  110,
+  111,
+  160,
+  168,
+  257,
+  453,
+  533,
+  739,
+  746,
+  764,
+  846,
+  946,
+  999,
+  36,
+  136,
+  311,
+  392,
+  724,
+  908,
+  30,
+  450,
+  495,
+  648,
+  672,
+  726,
+  878,
+  881,
+  984,
+  80,
+  208,
+  329,
+  502,
+  511,
+  515,
+  553,
+  560,
+  694,
+  824,
+  938,
+  70,
+  110,
+  144,
+  183,
+  309,
+  332,
+  337,
+  342,
+  398,
+  591,
+  635,
+  811,
+  842,
+  192,
+  339,
+  449,
+  504,
+  570,
+  594,
+  644,
+  666,
+  692,
+  779,
+  847,
+  32,
+  138,
+  155,
+  279,
+  296,
+  409,
+  427,
+  524,
+  605,
+  837,
+  919,
+  993,
+  38,
+  72,
+  139,
+  173,
+  279,
+  281,
+  285,
+  306,
+  375,
+  390,
+  426,
+  734,
+  909,
+  958,
+  17,
+  61,
+  451,
+  523,
+  573,
+  622,
+  935,
+  16,
+  74,
+  97,
+  139,
+  149,
+  193,
+  268,
+  353,
+  433,
+  475,
+  481,
+  508,
+  752,
+  881,
+  919,
+  9,
+  93,
+  292,
+  406,
+  543,
+  573,
+  610,
+  612,
+  642,
+  855,
+  326,
+  327,
+  428,
+  430,
+  677,
+  781,
+  796,
+  906,
+  918,
+  93,
+  191,
+  206,
+  467,
+  654,
+  704,
+  707,
+  709,
+  813,
+  908,
+  87,
+  212,
+  252,
+  315,
+  586,
+  755,
+  777,
+  801,
+  809,
+  838,
+  982,
+  479,
+  491,
+  499,
+  681,
+  887,
+  996,
+  37,
+  378,
+  408,
+  456,
+  460,
+  493,
+  568,
+  601,
+  616,
+  684,
+  820,
+  866,
+  915,
+  153,
+  186,
+  593,
+  781,
+  878,
+  48,
+  262,
+  320,
+  361,
+  599,
+  696,
+  698,
+  871,
+  17,
+  104,
+  128,
+  142,
+  216,
+  347,
+  468,
+  583,
+  656,
+  737,
+  752,
+  759,
+  767,
+  848,
+  860,
+  885,
+  105,
+  151,
+  173,
+  198,
+  412,
+  467,
+  701,
+  709,
+  967,
+  65,
+  165,
+  315,
+  431,
+  523,
+  562,
+  633,
+  694,
+  780,
+  782,
+  795,
+  943,
+  991,
+  28,
+  125,
+  223,
+  283,
+  384,
+  460,
+  586,
+  589,
+  600,
+  743,
+  754,
+  846,
+  907,
+  983,
+  12,
+  26,
+  94,
+  190,
+  256,
+  282,
+  380,
+  385,
+  450,
+  570,
+  582,
+  669,
+  672,
+  751,
+  804,
+  892,
+  26,
+  167,
+  259,
+  337,
+  409,
+  425,
+  121,
+  133,
+  305,
+  332,
+  408,
+  432,
+  531,
+  582,
+  598,
+  680,
+  716,
+  778,
+  790,
+  907,
+  942,
+  224,
+  240,
+  394,
+  449,
+  489,
+  503,
+  575,
+  594,
+  618,
+  653,
+  711,
+  736,
+  744,
+  821,
+  961,
+  536,
+  603,
+  781,
+  866,
+  901,
+  911,
+  916,
+  970,
+  42,
+  110,
+  186,
+  276,
+  396,
+  565,
+  573,
+  677,
+  738,
+  918,
+  956,
+  965,
+  978,
+  160,
+  191,
+  338,
+  502,
+  572,
+  721,
+  731,
+  45,
+  209,
+  224,
+  226,
+  623,
+  718,
+  721,
+  725,
+  840,
+  953,
+  977,
+  24,
+  77,
+  117,
+  290,
+  941,
+  945,
+  84,
+  200,
+  254,
+  374,
+  591,
+  635,
+  652,
+  765,
+  826,
+  949,
+  104,
+  257,
+  715,
+  162,
+  456,
+  479,
+  892,
+  34,
+  110,
+  142,
+  645,
+  664,
+  840,
+  950,
+  139,
+  313,
+  453,
+  615,
+  792,
+  798,
+  47,
+  133,
+  170,
+  350,
+  605,
+  757,
+  922,
+  940,
+  45,
+  204,
+  274,
+  369,
+  411,
+  809,
+  888,
+  903,
+  969,
+  151,
+  318,
+  354,
+  375,
+  629,
+  758,
+  881,
+  917,
+  972,
+  185,
+  238,
+  397,
+  405,
+  422,
+  450,
+  500,
+  532,
+  625,
+  677,
+  708,
+  755,
+  780,
+  824,
+  845,
+  931,
+  963,
+  975,
+  18,
+  245,
+  447,
+  519,
+  700,
+  21,
+  49,
+  130,
+  133,
+  185,
+  191,
+  388,
+  654,
+  760,
+  812,
+  817,
+  858,
+  906,
+  982,
+  997,
+  209,
+  508,
+  611,
+  691,
+  725,
+  79,
+  232,
+  320,
+  367,
+  481,
+  559,
+  649,
+  656,
+  830,
+  960,
+  40,
+  288,
+  542,
+  644,
+  646,
+  749,
+  827,
+  894,
+  929,
+  956,
+  73,
+  87,
+  215,
+  261,
+  377,
+  517,
+  822,
+  906,
+  997,
+  56,
+  267,
+  276,
+  375,
+  415,
+  528,
+  660,
+  670,
+  892,
+  959,
+  998,
+  999,
+  146,
+  329,
+  331,
+  332,
+  400,
+  510,
+  623,
+  653,
+  822,
+  18,
+  375,
+  394,
+  477,
+  482,
+  596,
+  665,
+  724,
+  847,
+  872,
+  935,
+  40,
+  136,
+  320,
+  332,
+  408,
+  767,
+  975,
+  24,
+  49,
+  156,
+  246,
+  378,
+  578,
+  627,
+  916,
+  965,
+  998,
+  123,
+  285,
+  305,
+  438,
+  476,
+  538,
+  554,
+  773,
+  804,
+  968,
+  4,
+  181,
+  240,
+  411,
+  715,
+  797,
+  802,
+  896,
+  904,
+  985,
+  68,
+  118,
+  185,
+  326,
+  645,
+  690,
+  736,
+  744,
+  961,
+  3,
+  404,
+  437,
+  572,
+  812,
+  902,
+  917,
+  921,
+  180,
+  291,
+  327,
+  328,
+  389,
+  407,
+  408,
+  530,
+  650,
+  727,
+  996,
+  230,
+  313,
+  506,
+  579,
+  593,
+  610,
+  814,
+  832,
+  840,
+  876,
+  951,
+  251,
+  327,
+  353,
+  581,
+  588,
+  711,
+  837,
+  2,
+  60,
+  165,
+  275,
+  291,
+  320,
+  735,
+  796,
+  63,
+  78,
+  165,
+  318,
+  433,
+  439,
+  456,
+  466,
+  529,
+  765,
+  144,
+  221,
+  259,
+  686,
+  793,
+  7,
+  242,
+  265,
+  433,
+  474,
+  664,
+  840,
+  954,
+  95,
+  161,
+  165,
+  209,
+  396,
+  820,
+  947,
+  36,
+  198,
+  262,
+  342,
+  449,
+  482,
+  621,
+  742,
+  756,
+  822,
+  972,
+  145,
+  339,
+  342,
+  479,
+  523,
+  811,
+  916,
+  199,
+  318,
+  323,
+  363,
+  491,
+  496,
+  562,
+  570,
+  612,
+  719,
+  739,
+  836,
+  168,
+  216,
+  252,
+  319,
+  760,
+  841,
+  845,
+  955,
+  144,
+  354,
+  442,
+  443,
+  662,
+  752,
+  936,
+  77,
+  185,
+  315,
+  473,
+  512,
+  596,
+  612,
+  634,
+  900,
+  936,
+  974,
+  166,
+  189,
+  428,
+  498,
+  755,
+  922,
+  23,
+  100,
+  204,
+  534,
+  719,
+  738,
+  854,
+  44,
+  120,
+  273,
+  407,
+  988,
+  50,
+  386,
+  460,
+  472,
+  513,
+  552,
+  811,
+  912,
+  981,
+  995,
+  24,
+  113,
+  129,
+  302,
+  442,
+  512,
+  685,
+  726,
+  966,
+  161,
+  413,
+  491,
+  498,
+  499,
+  543,
+  688,
+  690,
+  809,
+  843,
+  888,
+  564,
+  624,
+  756,
+  815,
+  832,
+  866,
+  932,
+  1,
+  13,
+  26,
+  39,
+  87,
+  176,
+  279,
+  284,
+  317,
+  344,
+  397,
+  442,
+  507,
+  591,
+  663,
+  691,
+  800,
+  803,
+  865,
+  925,
+  987,
+  995,
+  996,
+  315,
+  541,
+  557,
+  664,
+  679,
+  754,
+  808,
+  851,
+  918,
+  0,
+  117,
+  131,
+  262,
+  442,
+  627,
+  702,
+  799,
+  945,
+  281,
+  313,
+  314,
+  384,
+  427,
+  558,
+  669,
+  706,
+  720,
+  721,
+  766,
+  786,
+  840,
+  842,
+  923,
+  58,
+  119,
+  317,
+  411,
+  415,
+  416,
+  680,
+  997,
+  84,
+  442,
+  487,
+  689,
+  811,
+  833,
+  940,
+  22,
+  431,
+  515,
+  598,
+  605,
+  738,
+  876,
+  919,
+  960,
+  980,
+  3,
+  38,
+  130,
+  716,
+  854,
+  885,
+  51,
+  93,
+  141,
+  153,
+  195,
+  258,
+  329,
+  390,
+  497,
+  508,
+  680,
+  863,
+  169,
+  211,
+  335,
+  423,
+  442,
+  479,
+  864,
+  169,
+  239,
+  534,
+  605,
+  708,
+  743,
+  772,
+  814,
+  832,
+  54,
+  110,
+  167,
+  171,
+  290,
+  370,
+  433,
+  652,
+  661,
+  677,
+  710,
+  726,
+  829,
+  902,
+  915,
+  44,
+  88,
+  104,
+  214,
+  313,
+  346,
+  487,
+  555,
+  582,
+  660,
+  674,
+  713,
+  721,
+  762,
+  785,
+  797,
+  986,
+  998,
+  50,
+  143,
+  158,
+  281,
+  488,
+  566,
+  579,
+  584,
+  596,
+  846,
+  876,
+  42,
+  64,
+  71,
+  73,
+  105,
+  170,
+  171,
+  210,
+  276,
+  531,
+  577,
+  699,
+  879,
+  889,
+  925,
+  932,
+  442,
+  447,
+  462,
+  504,
+  530,
+  687,
+  714,
+  838,
+  120,
+  171,
+  280,
+  358,
+  644,
+  735,
+  765,
+  964,
+  988,
+  993,
+  80,
+  352,
+  740,
+  813,
+  999,
+  133,
+  155,
+  192,
+  196,
+  442,
+  456,
+  504,
+  519,
+  530,
+  606,
+  777,
+  916,
+  985,
+  24,
+  42,
+  351,
+  407,
+  504,
+  516,
+  682,
+  879,
+  67,
+  69,
+  145,
+  152,
+  492,
+  515,
+  562,
+  575,
+  658,
+  668,
+  700,
+  722,
+  811,
+  956,
+  18,
+  126,
+  283,
+  289,
+  297,
+  307,
+  337,
+  368,
+  519,
+  615,
+  789,
+  838,
+  876,
+  970,
+  38,
+  137,
+  307,
+  378,
+  436,
+  437,
+  453,
+  520,
+  793,
+  844,
+  893,
+  168,
+  179,
+  230,
+  327,
+  487,
+  662,
+  727,
+  126,
+  320,
+  584,
+  707,
+  864,
+  895,
+  295,
+  309,
+  781,
+  823,
+  988,
+  18,
+  42,
+  151,
+  163,
+  259,
+  324,
+  349,
+  416,
+  521,
+  659,
+  689,
+  912,
+  24,
+  87,
+  201,
+  319,
+  406,
+  434,
+  488,
+  554,
+  576,
+  624,
+  714,
+  851,
+  995,
+  49,
+  142,
+  236,
+  300,
+  416,
+  497,
+  586,
+  708,
+  777,
+  962,
+  969,
+  217,
+  235,
+  279,
+  316,
+  430,
+  491,
+  630,
+  842,
+  907,
+  124,
+  143,
+  180,
+  455,
+  672,
+  695,
+  891,
+  971,
+  90,
+  173,
+  363,
+  410,
+  446,
+  480,
+  528,
+  631,
+  690,
+  777,
+  792,
+  143,
+  187,
+  261,
+  268,
+  292,
+  410,
+  524,
+  557,
+  618,
+  643,
+  656,
+  680,
+  807,
+  812,
+  824,
+  900,
+  2,
+  5,
+  117,
+  216,
+  329,
+  355,
+  400,
+  493,
+  606,
+  631,
+  850,
+  875,
+  947,
+  93,
+  134,
+  172,
+  427,
+  477,
+  508,
+  540,
+  585,
+  878,
+  123,
+  302,
+  594,
+  678,
+  697,
+  747,
+  824,
+  868,
+  965,
+  14,
+  21,
+  178,
+  180,
+  227,
+  281,
+  379,
+  412,
+  417,
+  450,
+  456,
+  465,
+  589,
+  596,
+  736,
+  760,
+  844,
+  13,
+  81,
+  177,
+  276,
+  327,
+  359,
+  623,
+  674,
+  676,
+  3,
+  6,
+  34,
+  144,
+  150,
+  202,
+  219,
+  376,
+  429,
+  539,
+  648,
+  663,
+  885,
+  944,
+  997,
+  31,
+  259,
+  263,
+  291,
+  646,
+  783,
+  820,
+  836,
+  903,
+  929,
+  83,
+  145,
+  193,
+  372,
+  392,
+  422,
+  564,
+  734,
+  740,
+  846,
+  868,
+  945,
+  185,
+  277,
+  325,
+  394,
+  499,
+  649,
+  656,
+  748,
+  841,
+  922,
+  958,
+  19,
+  43,
+  51,
+  96,
+  291,
+  397,
+  680,
+  729,
+  913,
+  943,
+  978,
+  151,
+  179,
+  234,
+  248,
+  358,
+  692,
+  704,
+  778,
+  809,
+  847,
+  850,
+  873,
+  969,
+  242,
+  327,
+  340,
+  552,
+  736,
+  742,
+  837,
+  959,
+  179,
+  216,
+  355,
+  356,
+  443,
+  447,
+  512,
+  515,
+  529,
+  634,
+  786,
+  47,
+  142,
+  203,
+  223,
+  606,
+  623,
+  815,
+  24,
+  37,
+  67,
+  199,
+  272,
+  349,
+  380,
+  512,
+  574,
+  586,
+  743,
+  847,
+  890,
+  897,
+  25,
+  107,
+  347,
+  474,
+  476,
+  621,
+  642,
+  734,
+  755,
+  142,
+  211,
+  273,
+  526,
+  528,
+  602,
+  632,
+  761,
+  765,
+  776,
+  847,
+  112,
+  118,
+  140,
+  153,
+  229,
+  313,
+  448,
+  469,
+  619,
+  627,
+  637,
+  672,
+  751,
+  900,
+  906,
+  297,
+  411,
+  464,
+  497,
+  691,
+  740,
+  886,
+  14,
+  109,
+  125,
+  187,
+  194,
+  241,
+  263,
+  379,
+  552,
+  615,
+  657,
+  670,
+  750,
+  47,
+  133,
+  386,
+  482,
+  517,
+  641,
+  696,
+  734,
+  951,
+  1,
+  101,
+  103,
+  134,
+  205,
+  526,
+  533,
+  538,
+  559,
+  594,
+  680,
+  835,
+  4,
+  224,
+  526,
+  600,
+  769,
+  885,
+  991,
+  2,
+  292,
+  326,
+  380,
+  393,
+  539,
+  798,
+  907,
+  465,
+  641,
+  727,
+  763,
+  794,
+  854,
+  44,
+  92,
+  235,
+  381,
+  420,
+  430,
+  461,
+  538,
+  555,
+  725,
+  756,
+  849,
+  177,
+  180,
+  337,
+  353,
+  540,
+  571,
+  588,
+  706,
+  734,
+  753,
+  776,
+  786,
+  982,
+  999,
+  10,
+  159,
+  258,
+  428,
+  449,
+  505,
+  588,
+  888,
+  998,
+  55,
+  79,
+  95,
+  211,
+  226,
+  432,
+  435,
+  560,
+  563,
+  613,
+  694,
+  806,
+  968,
+  90,
+  165,
+  207,
+  422,
+  439,
+  489,
+  674,
+  693,
+  985,
+  8,
+  111,
+  336,
+  474,
+  489,
+  554,
+  715,
+  742,
+  772,
+  889,
+  906,
+  918,
+  102,
+  197,
+  236,
+  294,
+  345,
+  562,
+  568,
+  697,
+  850,
+  950,
+  113,
+  151,
+  204,
+  226,
+  235,
+  267,
+  302,
+  380,
+  407,
+  499,
+  813,
+  916,
+  956,
+  200,
+  275,
+  403,
+  546,
+  607,
+  697,
+  734,
+  187,
+  211,
+  255,
+  329,
+  359,
+  421,
+  495,
+  555,
+  581,
+  696,
+  961,
+  973,
+  231,
+  318,
+  359,
+  388,
+  422,
+  643,
+  707,
+  932,
+  940,
+  949,
+  3,
+  65,
+  128,
+  134,
+  172,
+  231,
+  349,
+  728,
+  749,
+  757,
+  772,
+  891,
+  150,
+  185,
+  551,
+  599,
+  617,
+  709,
+  816,
+  170,
+  339,
+  406,
+  487,
+  800,
+  887,
+  71,
+  196,
+  209,
+  449,
+  497,
+  517,
+  518,
+  529,
+  629,
+  661,
+  715,
+  869,
+  20,
+  37,
+  96,
+  99,
+  214,
+  273,
+  400,
+  555,
+  917,
+  31,
+  227,
+  228,
+  246,
+  353,
+  379,
+  507,
+  534,
+  590,
+  620,
+  680,
+  734,
+  830,
+  876,
+  955,
+  996,
+  5,
+  361,
+  364,
+  559,
+  699,
+  882,
+  920,
+  11,
+  114,
+  119,
+  154,
+  161,
+  319,
+  467,
+  533,
+  570,
+  787,
+  827,
+  995,
+  23,
+  171,
+  240,
+  254,
+  268,
+  287,
+  455,
+  580,
+  672,
+  726,
+  977,
+  982,
+  203,
+  239,
+  298,
+  407,
+  579,
+  594,
+  610,
+  624,
+  672,
+  756,
+  161,
+  228,
+  437,
+  465,
+  552,
+  861,
+  879,
+  968,
+  987,
+  989,
+  59,
+  79,
+  143,
+  149,
+  166,
+  271,
+  300,
+  411,
+  641,
+  677,
+  757,
+  868,
+  918,
+  994,
+  0,
+  321,
+  340,
+  346,
+  548,
+  788,
+  821,
+  953,
+  59,
+  120,
+  230,
+  344,
+  726,
+  823,
+  850,
+  83,
+  121,
+  201,
+  345,
+  355,
+  369,
+  398,
+  422,
+  507,
+  527,
+  554,
+  599,
+  712,
+  735,
+  874,
+  900,
+  28,
+  40,
+  149,
+  243,
+  344,
+  494,
+  759,
+  902,
+  979,
+  9,
+  168,
+  493,
+  610,
+  655,
+  747,
+  806,
+  975,
+  8,
+  29,
+  56,
+  150,
+  177,
+  207,
+  268,
+  364,
+  368,
+  458,
+  473,
+  719,
+  796,
+  862,
+  865,
+  45,
+  52,
+  115,
+  198,
+  285,
+  377,
+  396,
+  548,
+  682,
+  705,
+  807,
+  833,
+  957,
+  36,
+  149,
+  150,
+  278,
+  440,
+  451,
+  558,
+  575,
+  625,
+  630,
+  689,
+  932,
+  953,
+  985,
+  16,
+  106,
+  338,
+  342,
+  667,
+  675,
+  723,
+  745,
+  973,
+  86,
+  175,
+  207,
+  262,
+  385,
+  496,
+  774,
+  33,
+  222,
+  265,
+  295,
+  297,
+  410,
+  412,
+  500,
+  526,
+  595,
+  813,
+  899,
+  87,
+  155,
+  168,
+  505,
+  612,
+  650,
+  753,
+  819,
+  830,
+  103,
+  147,
+  237,
+  278,
+  438,
+  480,
+  490,
+  648,
+  671,
+  748,
+  822,
+  183,
+  246,
+  400,
+  541,
+  582,
+  614,
+  622,
+  745,
+  807,
+  80,
+  137,
+  430,
+  461,
+  541,
+  724,
+  6,
+  142,
+  168,
+  183,
+  196,
+  313,
+  484,
+  594,
+  635,
+  716,
+  803,
+  825,
+  861,
+  972,
+  981,
+  83,
+  164,
+  202,
+  232,
+  270,
+  311,
+  404,
+  431,
+  688,
+  729,
+  867,
+  903,
+  925,
+  69,
+  283,
+  295,
+  363,
+  410,
+  434,
+  457,
+  481,
+  574,
+  578,
+  587,
+  600,
+  664,
+  803,
+  858,
+  76,
+  205,
+  334,
+  441,
+  553,
+  590,
+  944,
+  69,
+  272,
+  486,
+  513,
+  604,
+  749,
+  842,
+  852,
+  954,
+  17,
+  86,
+  115,
+  203,
+  343,
+  355,
+  467,
+  478,
+  629,
+  646,
+  748,
+  811,
+  900,
+  13,
+  25,
+  120,
+  353,
+  608,
+  612,
+  747,
+  766,
+  856,
+  109,
+  234,
+  265,
+  279,
+  325,
+  379,
+  418,
+  464,
+  550,
+  552,
+  571,
+  344,
+  448,
+  517,
+  682,
+  895,
+  173,
+  242,
+  281,
+  314,
+  350,
+  502,
+  518,
+  552,
+  745,
+  19,
+  70,
+  75,
+  80,
+  695,
+  697,
+  793,
+  877,
+  85,
+  189,
+  248,
+  300,
+  417,
+  433,
+  507,
+  936,
+  947,
+  8,
+  351,
+  368,
+  400,
+  450,
+  470,
+  474,
+  501,
+  518,
+  524,
+  558,
+  616,
+  666,
+  712,
+  953,
+  172,
+  398,
+  644,
+  680,
+  785,
+  71,
+  116,
+  288,
+  314,
+  327,
+  488,
+  724,
+  770,
+  858,
+  934,
+  958,
+  67,
+  115,
+  279,
+  654,
+  689,
+  707,
+  752,
+  888,
+  966,
+  208,
+  544,
+  679,
+  719,
+  789,
+  831,
+  49,
+  263,
+  420,
+  433,
+  502,
+  602,
+  651,
+  678,
+  730,
+  756,
+  762,
+  900,
+  100,
+  113,
+  177,
+  198,
+  509,
+  516,
+  596,
+  645,
+  783,
+  939,
+  987,
+  335,
+  429,
+  437,
+  543,
+  566,
+  695,
+  707,
+  747,
+  868,
+  921,
+  0,
+  84,
+  203,
+  215,
+  477,
+  523,
+  526,
+  612,
+  627,
+  766,
+  778,
+  809,
+  126,
+  203,
+  373,
+  590,
+  640,
+  863,
+  871,
+  937,
+  201,
+  221,
+  729,
+  746,
+  772,
+  924,
+  937,
+  964,
+  78,
+  339,
+  406,
+  424,
+  475,
+  679,
+  869,
+  938,
+  64,
+  147,
+  163,
+  171,
+  293,
+  381,
+  390,
+  511,
+  989,
+  63,
+  85,
+  208,
+  335,
+  441,
+  510,
+  566,
+  586,
+  909,
+  935,
+  970,
+  50,
+  100,
+  351,
+  354,
+  397,
+  442,
+  448,
+  580,
+  657,
+  789,
+  836,
+  293,
+  311,
+  456,
+  795,
+  796,
+  799,
+  909,
+  972,
+  984,
+  28,
+  132,
+  226,
+  361,
+  473,
+  493,
+  586,
+  611,
+  676,
+  693,
+  939,
+  948,
+  150,
+  185,
+  269,
+  362,
+  648,
+  650,
+  870,
+  307,
+  330,
+  438,
+  756,
+  852,
+  99,
+  223,
+  285,
+  371,
+  767,
+  912,
+  966,
+  1,
+  3,
+  111,
+  583,
+  733,
+  841,
+  959,
+  977,
+  115,
+  263,
+  283,
+  498,
+  517,
+  534,
+  604,
+  656,
+  661,
+  769,
+  876,
+  974,
+  59,
+  123,
+  291,
+  343,
+  473,
+  565,
+  634,
+  834,
+  898,
+  923,
+  962,
+  75,
+  85,
+  92,
+  125,
+  305,
+  827,
+  836,
+  901,
+  936,
+  28,
+  124,
+  316,
+  541,
+  636,
+  694,
+  929,
+  960,
+  37,
+  69,
+  169,
+  442,
+  491,
+  588,
+  619,
+  643,
+  740,
+  794,
+  939,
+  941,
+  10,
+  43,
+  248,
+  450,
+  812,
+  907,
+  984,
+  271,
+  307,
+  316,
+  533,
+  702,
+  733,
+  752,
+  850,
+  892,
+  919,
+  971,
+  97,
+  132,
+  154,
+  461,
+  633,
+  741,
+  905,
+  940,
+  74,
+  115,
+  118,
+  251,
+  297,
+  344,
+  405,
+  623,
+  655,
+  658,
+  775,
+  801,
+  903,
+  965,
+  53,
+  309,
+  392,
+  643,
+  696,
+  752,
+  764,
+  867,
+  981,
+  64,
+  228,
+  236,
+  301,
+  498,
+  512,
+  536,
+  568,
+  685,
+  865,
+  925,
+  29,
+  371,
+  372,
+  626,
+  760,
+  765,
+  773,
+  813,
+  980,
+  109,
+  177,
+  211,
+  322,
+  370,
+  415,
+  425,
+  514,
+  647,
+  672,
+  767,
+  945,
+  613,
+  720,
+  863,
+  870,
+  886,
+  924,
+  144,
+  233,
+  483,
+  504,
+  811,
+  872,
+  908,
+  921,
+  61,
+  160,
+  350,
+  376,
+  424,
+  602,
+  632,
+  675,
+  682,
+  861,
+  959,
+  380,
+  389,
+  848,
+  7,
+  13,
+  458,
+  629,
+  103,
+  193,
+  231,
+  533,
+  590,
+  598,
+  661,
+  741,
+  880,
+  243,
+  400,
+  505,
+  601,
+  689,
+  965,
+  15,
+  136,
+  200,
+  230,
+  322,
+  419,
+  792,
+  890,
+  3,
+  71,
+  174,
+  189,
+  336,
+  363,
+  371,
+  403,
+  534,
+  743,
+  792,
+  799,
+  867,
+  909,
+  951,
+  57,
+  198,
+  202,
+  334,
+  471,
+  542,
+  709,
+  19,
+  104,
+  156,
+  246,
+  421,
+  450,
+  593,
+  721,
+  866,
+  972,
+  43,
+  185,
+  199,
+  243,
+  255,
+  293,
+  343,
+  395,
+  413,
+  608,
+  749,
+  759,
+  819,
+  160,
+  261,
+  357,
+  728,
+  734,
+  788,
+  849,
+  859,
+  884,
+  915,
+  129,
+  394,
+  592,
+  803,
+  974,
+  57,
+  79,
+  246,
+  528,
+  698,
+  740,
+  909,
+  968,
+  90,
+  204,
+  337,
+  699,
+  926,
+  125,
+  181,
+  251,
+  333,
+  335,
+  439,
+  737,
+  778,
+  905,
+  922,
+  1,
+  22,
+  64,
+  80,
+  304,
+  45,
+  63,
+  99,
+  144,
+  222,
+  274,
+  384,
+  406,
+  447,
+  643,
+  774,
+  784,
+  918,
+  58,
+  110,
+  156,
+  294,
+  436,
+  531,
+  654,
+  742,
+  769,
+  948,
+  153,
+  171,
+  177,
+  389,
+  647,
+  722,
+  781,
+  825,
+  829,
+  854,
+  33,
+  150,
+  194,
+  237,
+  313,
+  314,
+  386,
+  502,
+  645,
+  705,
+  791,
+  833,
+  845,
+  882,
+  916,
+  136,
+  222,
+  275,
+  381,
+  471,
+  859,
+  901,
+  902,
+  917,
+  992,
+  118,
+  319,
+  494,
+  512,
+  812,
+  897,
+  960,
+  35,
+  252,
+  489,
+  565,
+  573,
+  605,
+  684,
+  847,
+  22,
+  396,
+  541,
+  560,
+  589,
+  618,
+  685,
+  771,
+  793,
+  968,
+  53,
+  102,
+  130,
+  434,
+  506,
+  738,
+  759,
+  867,
+  884,
+  886,
+  894,
+  956,
+  95,
+  100,
+  117,
+  215,
+  360,
+  399,
+  416,
+  421,
+  612,
+  692,
+  697,
+  707,
+  815,
+  852,
+  875,
+  892,
+  936,
+  346,
+  380,
+  563,
+  691,
+  718,
+  115,
+  192,
+  309,
+  603,
+  881,
+  888,
+  927,
+  983,
+  182,
+  206,
+  222,
+  295,
+  355,
+  446,
+  672,
+  710,
+  751,
+  85,
+  127,
+  144,
+  267,
+  306,
+  339,
+  372,
+  393,
+  688,
+  739,
+  821,
+  886,
+  894,
+  915,
+  952,
+  169,
+  179,
+  233,
+  316,
+  654,
+  864,
+  988,
+  98,
+  102,
+  153,
+  188,
+  205,
+  245,
+  290,
+  333,
+  901,
+  922,
+  986,
+  988,
+  996,
+  93,
+  390,
+  438,
+  445,
+  539,
+  614,
+  713,
+  800,
+  856,
+  962,
+  101,
+  145,
+  245,
+  546,
+  560,
+  581,
+  598,
+  937,
+  54,
+  148,
+  181,
+  302,
+  592,
+  670,
+  761,
+  287,
+  324,
+  365,
+  464,
+  471,
+  473,
+  487,
+  598,
+  667,
+  741,
+  0,
+  95,
+  183,
+  420,
+  469,
+  648,
+  686,
+  890,
+  902,
+  20,
+  207,
+  397,
+  410,
+  481,
+  545,
+  579,
+  635,
+  689,
+  755,
+  791,
+  850,
+  856,
+  857,
+  998,
+  15,
+  332,
+  481,
+  577,
+  603,
+  635,
+  948,
+  58,
+  135,
+  208,
+  370,
+  469,
+  848,
+  942,
+  946,
+  31,
+  149,
+  153,
+  164,
+  174,
+  329,
+  444,
+  534,
+  548,
+  615,
+  110,
+  137,
+  177,
+  287,
+  699,
+  705,
+  848,
+  197,
+  204,
+  236,
+  382,
+  543,
+  874,
+  984,
+  49,
+  78,
+  163,
+  185,
+  316,
+  355,
+  365,
+  577,
+  667,
+  673,
+  720,
+  722,
+  785,
+  942,
+  10,
+  117,
+  182,
+  218,
+  305,
+  398,
+  471,
+  676,
+  807,
+  839,
+  944,
+  173,
+  182,
+  184,
+  302,
+  340,
+  426,
+  609,
+  693,
+  735,
+  762,
+  873,
+  947,
+  24,
+  85,
+  290,
+  299,
+  499,
+  551,
+  609,
+  648,
+  660,
+  685,
+  11,
+  62,
+  109,
+  185,
+  345,
+  797,
+  843,
+  264,
+  776,
+  824,
+  845,
+  958,
+  49,
+  58,
+  170,
+  367,
+  451,
+  469,
+  654,
+  794,
+  842,
+  877,
+  897,
+  950,
+  4,
+  57,
+  58,
+  61,
+  260,
+  334,
+  494,
+  540,
+  561,
+  636,
+  659,
+  950,
+  68,
+  96,
+  146,
+  167,
+  270,
+  293,
+  401,
+  623,
+  625,
+  668,
+  690,
+  934,
+  946,
+  218,
+  280,
+  309,
+  389,
+  447,
+  492,
+  641,
+  730,
+  786,
+  843,
+  871,
+  970,
+  973,
+  14,
+  93,
+  284,
+  404,
+  666,
+  713,
+  835,
+  183,
+  214,
+  292,
+  563,
+  739,
+  823,
+  876,
+  6,
+  84,
+  543,
+  556,
+  579,
+  855,
+  35,
+  227,
+  327,
+  380,
+  439,
+  712,
+  769,
+  776,
+  46,
+  176,
+  178,
+  192,
+  239,
+  555,
+  703,
+  744,
+  751,
+  813,
+  939,
+  30,
+  89,
+  141,
+  260,
+  268,
+  348,
+  367,
+  374,
+  730,
+  742,
+  766,
+  769,
+  832,
+  99,
+  150,
+  199,
+  229,
+  286,
+  292,
+  344,
+  464,
+  524,
+  558,
+  565,
+  629,
+  716,
+  766,
+  818,
+  867,
+  876,
+  877,
+  881,
+  131,
+  208,
+  312,
+  472,
+  524,
+  565,
+  638,
+  645,
+  655,
+  663,
+  665,
+  713,
+  752,
+  877,
+  958,
+  963,
+  985,
+  993,
+  23,
+  160,
+  240,
+  594,
+  602,
+  663,
+  876,
+  945,
+  961,
+  53,
+  82,
+  159,
+  217,
+  219,
+  270,
+  549,
+  598,
+  742,
+  846,
+  885,
+  628,
+  878,
+  121,
+  210,
+  273,
+  554,
+  555,
+  759,
+  911,
+  913,
+  28,
+  233,
+  269,
+  347,
+  489,
+  592,
+  859,
+  934,
+  952,
+  6,
+  60,
+  79,
+  123,
+  256,
+  279,
+  455,
+  557,
+  727,
+  123,
+  750,
+  906,
+  971,
+  7,
+  26,
+  96,
+  209,
+  464,
+  477,
+  662,
+  693,
+  963,
+  201,
+  427,
+  474,
+  663,
+  728,
+  917,
+  81,
+  102,
+  488,
+  644,
+  802,
+  834,
+  929,
+  987,
+  273,
+  283,
+  459,
+  531,
+  736,
+  918,
+  960,
+  112,
+  182,
+  187,
+  193,
+  311,
+  360,
+  400,
+  517,
+  668,
+  885,
+  888,
+  70,
+  89,
+  130,
+  190,
+  248,
+  262,
+  334,
+  447,
+  451,
+  493,
+  513,
+  531,
+  548,
+  721,
+  891,
+  918,
+  925,
+  968,
+  102,
+  249,
+  396,
+  397,
+  405,
+  473,
+  532,
+  761,
+  869,
+  127,
+  211,
+  234,
+  375,
+  377,
+  513,
+  517,
+  523,
+  526,
+  712,
+  772,
+  848,
+  890,
+  172,
+  264,
+  385,
+  445,
+  461,
+  474,
+  485,
+  537,
+  608,
+  687,
+  735,
+  11,
+  220,
+  328,
+  381,
+  488,
+  690,
+  790,
+  910,
+  969,
+  994,
+  191,
+  284,
+  472,
+  565,
+  584,
+  660,
+  706,
+  715,
+  739,
+  75,
+  78,
+  81,
+  260,
+  372,
+  741,
+  898,
+  910,
+  967,
+  972,
+  108,
+  410,
+  463,
+  923,
+  936,
+  947,
+  961,
+  110,
+  111,
+  160,
+  191,
+  239,
+  735,
+  963,
+  77,
+  267,
+  275,
+  330,
+  357,
+  620,
+  664,
+  699,
+  837,
+  842,
+  42,
+  45,
+  375,
+  384,
+  468,
+  516,
+  521,
+  552,
+  564,
+  700,
+  943,
+  981,
+  36,
+  272,
+  288,
+  442,
+  506,
+  507,
+  533,
+  708,
+  748,
+  834,
+  950,
+  261,
+  275,
+  24,
+  97,
+  124,
+  311,
+  398,
+  504,
+  558,
+  581,
+  653,
+  799,
+  930,
+  988,
+  63,
+  164,
+  260,
+  305,
+  348,
+  372,
+  456,
+  468,
+  667,
+  794,
+  934,
+  956,
+  210,
+  478,
+  533,
+  927,
+  14,
+  89,
+  163,
+  207,
+  356,
+  626,
+  628,
+  658,
+  696,
+  725,
+  731,
+  764,
+  43,
+  58,
+  449,
+  639,
+  894,
+  138,
+  163,
+  290,
+  344,
+  345,
+  386,
+  432,
+  466,
+  614,
+  767,
+  800,
+  831,
+  7,
+  292,
+  314,
+  322,
+  327,
+  518,
+  549,
+  760,
+  981,
+  122,
+  246,
+  297,
+  461,
+  489,
+  502,
+  581,
+  630,
+  746,
+  769,
+  904,
+  0,
+  27,
+  157,
+  259,
+  337,
+  434,
+  504,
+  541,
+  573,
+  781,
+  794,
+  842,
+  928,
+  986,
+  184,
+  244,
+  372,
+  423,
+  482,
+  503,
+  626,
+  644,
+  785,
+  890,
+  47,
+  242,
+  509,
+  671,
+  675,
+  765,
+  884,
+  982,
+  81,
+  84,
+  147,
+  314,
+  456,
+  483,
+  603,
+  670,
+  691,
+  896,
+  928,
+  18,
+  21,
+  75,
+  114,
+  284,
+  513,
+  574,
+  621,
+  630,
+  753,
+  765,
+  896,
+  331,
+  344,
+  358,
+  409,
+  499,
+  678,
+  679,
+  953,
+  90,
+  123,
+  139,
+  150,
+  161,
+  228,
+  296,
+  534,
+  658,
+  707,
+  715,
+  743,
+  757,
+  945,
+  962,
+  993,
+  92,
+  133,
+  147,
+  201,
+  297,
+  363,
+  517,
+  7,
+  80,
+  147,
+  183,
+  328,
+  348,
+  351,
+  594,
+  691,
+  723,
+  735,
+  18,
+  145,
+  216,
+  231,
+  305,
+  364,
+  380,
+  447,
+  589,
+  629,
+  648,
+  727,
+  729,
+  109,
+  132,
+  161,
+  195,
+  408,
+  443,
+  527,
+  748,
+  770,
+  821,
+  928,
+  962,
+  119,
+  298,
+  395,
+  556,
+  728,
+  898,
+  945,
+  10,
+  129,
+  451,
+  490,
+  606,
+  620,
+  662,
+  698,
+  782,
+  813,
+  816,
+  952,
+  69,
+  175,
+  203,
+  306,
+  399,
+  405,
+  707,
+  710,
+  12,
+  107,
+  284,
+  285,
+  448,
+  584,
+  689,
+  818,
+  990,
+  11,
+  105,
+  114,
+  271,
+  305,
+  561,
+  572,
+  626,
+  669,
+  710,
+  72,
+  224,
+  233,
+  276,
+  445,
+  476,
+  613,
+  615,
+  879,
+  244,
+  268,
+  502,
+  512,
+  520,
+  600,
+  671,
+  694,
+  887,
+  987,
+  81,
+  87,
+  378,
+  384,
+  397,
+  423,
+  427,
+  626,
+  630,
+  693,
+  699,
+  726,
+  887,
+  929,
+  967,
+  31,
+  71,
+  326,
+  345,
+  350,
+  422,
+  515,
+  531,
+  630,
+  761,
+  26,
+  33,
+  461,
+  601,
+  627,
+  716,
+  743,
+  975,
+  81,
+  399,
+  489,
+  609,
+  733,
+  741,
+  787,
+  806,
+  874,
+  903,
+  932,
+  988,
+  81,
+  367,
+  406,
+  492,
+  550,
+  561,
+  599,
+  635,
+  756,
+  838,
+  944,
+  958,
+  39,
+  75,
+  102,
+  259,
+  345,
+  376,
+  499,
+  519,
+  548,
+  763,
+  788,
+  857,
+  899,
+  947,
+  948,
+  970,
+  975,
+  26,
+  244,
+  367,
+  408,
+  410,
+  415,
+  669,
+  849,
+  904,
+  912,
+  913,
+  932,
+  84,
+  89,
+  233,
+  297,
+  433,
+  599,
+  818,
+  869,
+  957,
+  194,
+  373,
+  632,
+  651,
+  718,
+  728,
+  827,
+  997,
+  15,
+  45,
+  173,
+  175,
+  229,
+  339,
+  690,
+  714,
+  758,
+  764,
+  824,
+  837,
+  961,
+  211,
+  223,
+  606,
+  623,
+  648,
+  674,
+  684,
+  819,
+  919,
+  207,
+  258,
+  277,
+  280,
+  285,
+  424,
+  429,
+  670,
+  855,
+  867,
+  872,
+  966,
+  0,
+  21,
+  346,
+  560,
+  652,
+  791,
+  911,
+  327,
+  376,
+  387,
+  460,
+  491,
+  496,
+  662,
+  667,
+  745,
+  754,
+  767,
+  974,
+  2,
+  209,
+  210,
+  598,
+  883,
+  930,
+  952,
+  7,
+  90,
+  267,
+  342,
+  368,
+  486,
+  628,
+  698,
+  915,
+  935,
+  2,
+  12,
+  86,
+  209,
+  243,
+  383,
+  449,
+  604,
+  841,
+  967,
+  976,
+  27,
+  31,
+  47,
+  117,
+  424,
+  536,
+  714,
+  745,
+  891,
+  899,
+  950,
+  85,
+  152,
+  210,
+  270,
+  389,
+  551,
+  86,
+  140,
+  202,
+  432,
+  625,
+  885,
+  908,
+  928,
+  43,
+  81,
+  110,
+  227,
+  278,
+  589,
+  613,
+  729,
+  732,
+  743,
+  747,
+  762,
+  784,
+  864,
+  980,
+  57,
+  132,
+  309,
+  313,
+  349,
+  366,
+  494,
+  563,
+  564,
+  604,
+  640,
+  800,
+  935,
+  6,
+  77,
+  201,
+  726,
+  745,
+  772,
+  833,
+  990,
+  33,
+  45,
+  178,
+  335,
+  393,
+  410,
+  498,
+  534,
+  603,
+  626,
+  672,
+  685,
+  740,
+  930,
+  995,
+  118,
+  142,
+  306,
+  373,
+  446,
+  480,
+  802,
+  930,
+  998,
+  184,
+  273,
+  401,
+  444,
+  483,
+  484,
+  526,
+  611,
+  641,
+  666,
+  681,
+  786,
+  899,
+  919,
+  942,
+  31,
+  50,
+  66,
+  68,
+  86,
+  140,
+  229,
+  349,
+  445,
+  588,
+  665,
+  682,
+  686,
+  783,
+  798,
+  900,
+  926,
+  976,
+  261,
+  727,
+  811,
+  125,
+  144,
+  256,
+  377,
+  644,
+  660,
+  752,
+  843,
+  981,
+  982,
+  997,
+  998,
+  296,
+  382,
+  477,
+  479,
+  548,
+  583,
+  676,
+  767,
+  791,
+  25,
+  446,
+  546,
+  585,
+  654,
+  727,
+  804,
+  969,
+  7,
+  53,
+  203,
+  220,
+  247,
+  450,
+  487,
+  503,
+  578,
+  638,
+  657,
+  730,
+  753,
+  792,
+  998,
+  4,
+  87,
+  316,
+  379,
+  840,
+  891,
+  896,
+  902,
+  906,
+  150,
+  361,
+  490,
+  517,
+  533,
+  693,
+  696,
+  791,
+  805,
+  868,
+  944,
+  962,
+  128,
+  154,
+  165,
+  374,
+  573,
+  636,
+  796,
+  44,
+  78,
+  249,
+  341,
+  392,
+  538,
+  569,
+  746,
+  752,
+  858,
+  59,
+  106,
+  357,
+  471,
+  570,
+  680,
+  850,
+  968,
+  984,
+  166,
+  184,
+  216,
+  263,
+  306,
+  660,
+  745,
+  807,
+  207,
+  236,
+  295,
+  302,
+  444,
+  536,
+  603,
+  618,
+  632,
+  938,
+  198,
+  212,
+  293,
+  357,
+  381,
+  384,
+  406,
+  564,
+  763,
+  813,
+  908,
+  922,
+  936,
+  958,
+  54,
+  119,
+  458,
+  459,
+  586,
+  764,
+  810,
+  869,
+  897,
+  168,
+  200,
+  232,
+  274,
+  312,
+  423,
+  434,
+  497,
+  549,
+  618,
+  628,
+  829,
+  842,
+  896,
+  961,
+  105,
+  226,
+  276,
+  292,
+  592,
+  727,
+  818,
+  106,
+  426,
+  459,
+  529,
+  543,
+  544,
+  569,
+  572,
+  600,
+  601,
+  629,
+  641,
+  700,
+  766,
+  793,
+  24,
+  87,
+  89,
+  173,
+  312,
+  617,
+  680,
+  921,
+  960,
+  991,
+  234,
+  289,
+  308,
+  321,
+  364,
+  865,
+  14,
+  76,
+  98,
+  425,
+  656,
+  965,
+  289,
+  435,
+  497,
+  630,
+  695,
+  907,
+  977,
+  41,
+  95,
+  276,
+  584,
+  700,
+  822,
+  829,
+  29,
+  129,
+  183,
+  244,
+  247,
+  258,
+  276,
+  303,
+  337,
+  374,
+  413,
+  424,
+  431,
+  434,
+  507,
+  675,
+  713,
+  827,
+  855,
+  49,
+  81,
+  99,
+  133,
+  163,
+  213,
+  219,
+  425,
+  747,
+  810,
+  997,
+  95,
+  271,
+  454,
+  553,
+  775,
+  796,
+  974,
+  984,
+  439,
+  468,
+  662,
+  799,
+  897,
+  907,
+  936,
+  92,
+  101,
+  119,
+  146,
+  780,
+  915,
+  65,
+  292,
+  373,
+  408,
+  465,
+  564,
+  752,
+  756,
+  818,
+  863,
+  960,
+  124,
+  128,
+  414,
+  811,
+  843,
+  890,
+  134,
+  211,
+  218,
+  271,
+  288,
+  353,
+  612,
+  765,
+  772,
+  825,
+  853,
+  859,
+  910,
+  60,
+  68,
+  327,
+  452,
+  638,
+  642,
+  675,
+  682,
+  692,
+  710,
+  722,
+  732,
+  807,
+  42,
+  93,
+  220,
+  272,
+  284,
+  306,
+  472,
+  635,
+  714,
+  718,
+  61,
+  67,
+  110,
+  362,
+  397,
+  471,
+  667,
+  965,
+  98,
+  180,
+  259,
+  387,
+  400,
+  433,
+  592,
+  725,
+  811,
+  884,
+  975,
+  181,
+  383,
+  497,
+  584,
+  595,
+  634,
+  883,
+  957,
+  386,
+  387,
+  419,
+  538,
+  604,
+  681,
+  780,
+  834,
+  981,
+  113,
+  146,
+  166,
+  224,
+  228,
+  237,
+  249,
+  341,
+  516,
+  569,
+  593,
+  744,
+  819,
+  891,
+  984,
+  23,
+  74,
+  323,
+  540,
+  592,
+  681,
+  733,
+  739,
+  853,
+  19,
+  176,
+  191,
+  580,
+  581,
+  823,
+  930,
+  8,
+  35,
+  97,
+  238,
+  240,
+  264,
+  575,
+  620,
+  649,
+  668,
+  686,
+  713,
+  775,
+  784,
+  900,
+  992,
+  185,
+  448,
+  498,
+  697,
+  709,
+  783,
+  278,
+  279,
+  325,
+  554,
+  667,
+  672,
+  894,
+  925,
+  43,
+  89,
+  172,
+  524,
+  526,
+  735,
+  748,
+  772,
+  778,
+  268,
+  435,
+  528,
+  561,
+  604,
+  708,
+  79,
+  334,
+  401,
+  650,
+  838,
+  841,
+  898,
+  82,
+  112,
+  196,
+  217,
+  229,
+  441,
+  644,
+  101,
+  116,
+  139,
+  398,
+  399,
+  424,
+  493,
+  600,
+  644,
+  659,
+  785,
+  966,
+  983,
+  5,
+  284,
+  315,
+  495,
+  563,
+  566,
+  624,
+  802,
+  986,
+  129,
+  169,
+  325,
+  440,
+  448,
+  706,
+  752,
+  845,
+  863,
+  114,
+  153,
+  277,
+  287,
+  535,
+  588,
+  602,
+  609,
+  736,
+  769,
+  185,
+  272,
+  304,
+  332,
+  569,
+  743,
+  811,
+  54,
+  72,
+  218,
+  292,
+  379,
+  556,
+  638,
+  825,
+  8,
+  60,
+  87,
+  391,
+  421,
+  568,
+  602,
+  644,
+  667,
+  764,
+  797,
+  809,
+  872,
+  900,
+  950,
+  952,
+  178,
+  247,
+  251,
+  412,
+  811,
+  823,
+  897,
+  929,
+  115,
+  129,
+  212,
+  341,
+  352,
+  578,
+  754,
+  920,
+  925,
+  160,
+  429,
+  511,
+  522,
+  709,
+  838,
+  942,
+  12,
+  123,
+  206,
+  214,
+  253,
+  255,
+  264,
+  458,
+  641,
+  679,
+  848,
+  238,
+  309,
+  380,
+  491,
+  565,
+  619,
+  697,
+  750,
+  835,
+  936,
+  957,
+  962,
+  345,
+  380,
+  463,
+  486,
+  547,
+  653,
+  763,
+  787,
+  859,
+  861,
+  940,
+  950,
+  984,
+  164,
+  281,
+  297,
+  344,
+  510,
+  570,
+  580,
+  657,
+  936,
+  984,
+  66,
+  210,
+  590,
+  877,
+  72,
+  85,
+  106,
+  143,
+  148,
+  385,
+  557,
+  627,
+  631,
+  653,
+  724,
+  742,
+  745,
+  800,
+  829,
+  58,
+  179,
+  352,
+  528,
+  658,
+  696,
+  761,
+  763,
+  864,
+  28,
+  34,
+  164,
+  235,
+  712,
+  742,
+  802,
+  919,
+  943,
+  962,
+  64,
+  143,
+  312,
+  336,
+  338,
+  371,
+  381,
+  519,
+  690,
+  811,
+  868,
+  65,
+  374,
+  403,
+  440,
+  508,
+  525,
+  884,
+  26,
+  112,
+  144,
+  218,
+  228,
+  234,
+  254,
+  281,
+  315,
+  455,
+  493,
+  505,
+  598,
+  677,
+  707,
+  948,
+  20,
+  160,
+  165,
+  186,
+  290,
+  353,
+  787,
+  806,
+  904,
+  917,
+  10,
+  67,
+  246,
+  290,
+  560,
+  620,
+  711,
+  724,
+  8,
+  375,
+  410,
+  481,
+  515,
+  663,
+  743,
+  747,
+  967,
+  179,
+  252,
+  256,
+  324,
+  877,
+  885,
+  971,
+  90,
+  306,
+  330,
+  445,
+  728,
+  806,
+  888,
+  287,
+  348,
+  412,
+  500,
+  631,
+  687,
+  726,
+  728,
+  85,
+  238,
+  273,
+  403,
+  532,
+  654,
+  879,
+  23,
+  102,
+  434,
+  437,
+  849,
+  856,
+  17,
+  265,
+  383,
+  547,
+  599,
+  858,
+  995,
+  285,
+  320,
+  553,
+  737,
+  787,
+  894,
+  5,
+  17,
+  89,
+  190,
+  327,
+  418,
+  525,
+  543,
+  587,
+  678,
+  730,
+  835,
+  928,
+  947,
+  13,
+  74,
+  134,
+  303,
+  421,
+  436,
+  475,
+  701,
+  929,
+  156,
+  347,
+  498,
+  698,
+  870,
+  909,
+  4,
+  15,
+  45,
+  73,
+  229,
+  268,
+  345,
+  357,
+  459,
+  500,
+  513,
+  544,
+  620,
+  624,
+  702,
+  959,
+  29,
+  71,
+  163,
+  196,
+  197,
+  416,
+  756,
+  851,
+  890,
+  921,
+  926,
+  65,
+  443,
+  507,
+  514,
+  531,
+  581,
+  649,
+  674,
+  855,
+  861,
+  865,
+  957,
+  35,
+  94,
+  113,
+  505,
+  660,
+  821,
+  208,
+  229,
+  246,
+  324,
+  327,
+  446,
+  470,
+  494,
+  518,
+  526,
+  600,
+  659,
+  886,
+  897,
+  103,
+  402,
+  403,
+  460,
+  541,
+  709,
+  815,
+  816,
+  973,
+  128,
+  236,
+  378,
+  398,
+  561,
+  602,
+  609,
+  659,
+  677,
+  688,
+  741,
+  815,
+  59,
+  82,
+  122,
+  162,
+  233,
+  265,
+  335,
+  407,
+  452,
+  489,
+  495,
+  542,
+  642,
+  696,
+  825,
+  902,
+  262,
+  524,
+  738,
+  166,
+  389,
+  408,
+  564,
+  603,
+  639,
+  942,
+  16,
+  51,
+  87,
+  211,
+  336,
+  371,
+  404,
+  449,
+  538,
+  560,
+  594,
+  612,
+  849,
+  953,
+  23,
+  64,
+  432,
+  559,
+  802,
+  813,
+  874,
+  919,
+  89,
+  341,
+  355,
+  383,
+  509,
+  650,
+  778,
+  972,
+  998,
+  13,
+  208,
+  407,
+  419,
+  465,
+  582,
+  595,
+  825,
+  909,
+  83,
+  110,
+  184,
+  240,
+  362,
+  559,
+  684,
+  815,
+  840,
+  881,
+  269,
+  670,
+  675,
+  680,
+  793,
+  794,
+  804,
+  805,
+  807,
+  830,
+  2,
+  20,
+  491,
+  581,
+  676,
+  9,
+  231,
+  243,
+  294,
+  464,
+  513,
+  544,
+  703,
+  763,
+  813,
+  862,
+  880,
+  943,
+  114,
+  115,
+  131,
+  145,
+  191,
+  357,
+  380,
+  391,
+  394,
+  399,
+  548,
+  651,
+  654,
+  805,
+  82,
+  152,
+  163,
+  241,
+  250,
+  331,
+  430,
+  467,
+  474,
+  536,
+  598,
+  634,
+  722,
+  778,
+  857,
+  951,
+  954,
+  104,
+  131,
+  190,
+  354,
+  475,
+  511,
+  574,
+  656,
+  778,
+  801,
+  902,
+  100,
+  296,
+  462,
+  928,
+  9,
+  231,
+  239,
+  263,
+  311,
+  485,
+  614,
+  713,
+  139,
+  238,
+  307,
+  343,
+  349,
+  395,
+  499,
+  678,
+  821,
+  912,
+  166,
+  181,
+  312,
+  491,
+  520,
+  710,
+  752,
+  871,
+  108,
+  306,
+  511,
+  652,
+  679,
+  777,
+  799,
+  19,
+  23,
+  80,
+  92,
+  261,
+  466,
+  558,
+  606,
+  781,
+  844,
+  941,
+  11,
+  89,
+  94,
+  178,
+  257,
+  381,
+  398,
+  586,
+  610,
+  646,
+  817,
+  903,
+  952,
+  988,
+  107,
+  176,
+  296,
+  332,
+  430,
+  434,
+  531,
+  669,
+  807,
+  888,
+  997,
+  124,
+  246,
+  537,
+  650,
+  786,
+  979,
+  194,
+  535,
+  548,
+  560,
+  566,
+  711,
+  760,
+  930,
+  947,
+  143,
+  151,
+  395,
+  872,
+  981,
+  95,
+  107,
+  380,
+  475,
+  552,
+  597,
+  757,
+  804,
+  810,
+  914,
+  96,
+  210,
+  329,
+  445,
+  516,
+  575,
+  609,
+  690,
+  860,
+  913,
+  963,
+  134,
+  197,
+  307,
+  313,
+  414,
+  465,
+  560,
+  639,
+  780,
+  854,
+  946,
+  103,
+  353,
+  413,
+  532,
+  657,
+  689,
+  904,
+  958,
+  990,
+  43,
+  131,
+  142,
+  217,
+  236,
+  406,
+  597,
+  859,
+  61,
+  153,
+  437,
+  468,
+  586,
+  635,
+  670,
+  701,
+  117,
+  138,
+  237,
+  305,
+  358,
+  528,
+  605,
+  613,
+  628,
+  759,
+  771,
+  836,
+  896,
+  968,
+  988,
+  34,
+  82,
+  347,
+  448,
+  461,
+  575,
+  761,
+  910,
+  977,
+  50,
+  103,
+  173,
+  185,
+  287,
+  308,
+  406,
+  462,
+  671,
+  767,
+  789,
+  890,
+  905,
+  548,
+  562,
+  606,
+  653,
+  692,
+  846,
+  114,
+  170,
+  477,
+  549,
+  607,
+  696,
+  945,
+  130,
+  172,
+  175,
+  319,
+  443,
+  480,
+  869,
+  44,
+  65,
+  111,
+  324,
+  413,
+  474,
+  610,
+  627,
+  642,
+  685,
+  807,
+  824,
+  265,
+  465,
+  558,
+  564,
+  614,
+  628,
+  833,
+  916,
+  942,
+  26,
+  70,
+  136,
+  208,
+  492,
+  641,
+  803,
+  912,
+  914,
+  74,
+  168,
+  198,
+  368,
+  376,
+  558,
+  737,
+  783,
+  816,
+  845,
+  959,
+  126,
+  246,
+  406,
+  444,
+  449,
+  517,
+  579,
+  665,
+  772,
+  789,
+  906,
+  988,
+  189,
+  235,
+  374,
+  387,
+  446,
+  456,
+  554,
+  643,
+  685,
+  826,
+  848,
+  893,
+  944,
+  972,
+  21,
+  134,
+  141,
+  304,
+  360,
+  385,
+  409,
+  498,
+  523,
+  659,
+  8,
+  111,
+  156,
+  256,
+  276,
+  342,
+  449,
+  480,
+  543,
+  686,
+  691,
+  863,
+  205,
+  281,
+  302,
+  375,
+  439,
+  492,
+  605,
+  675,
+  707,
+  741,
+  933,
+  966,
+  971,
+  42,
+  381,
+  569,
+  899,
+  902,
+  980,
+  217,
+  321,
+  374,
+  416,
+  482,
+  560,
+  563,
+  626,
+  677,
+  690,
+  780,
+  788,
+  963,
+  57,
+  58,
+  61,
+  77,
+  110,
+  255,
+  326,
+  389,
+  466,
+  476,
+  557,
+  744,
+  791,
+  846,
+  861,
+  967,
+  980,
+  31,
+  99,
+  213,
+  234,
+  282,
+  362,
+  396,
+  702,
+  861,
+  51,
+  102,
+  209,
+  308,
+  335,
+  408,
+  418,
+  511,
+  567,
+  726,
+  758,
+  899,
+  927,
+  940,
+  992,
+  69,
+  132,
+  185,
+  261,
+  358,
+  396,
+  684,
+  872,
+  986,
+  116,
+  149,
+  204,
+  691,
+  814,
+  892,
+  895,
+  914,
+  916,
+  154,
+  224,
+  243,
+  253,
+  282,
+  368,
+  579,
+  654,
+  661,
+  703,
+  735,
+  868,
+  930,
+  29,
+  164,
+  253,
+  277,
+  290,
+  340,
+  626,
+  765,
+  852,
+  173,
+  203,
+  225,
+  282,
+  415,
+  587,
+  595,
+  643,
+  858,
+  874,
+  83,
+  238,
+  314,
+  462,
+  803,
+  822,
+  960,
+  83,
+  362,
+  467,
+  497,
+  666,
+  748,
+  814,
+  76,
+  210,
+  256,
+  374,
+  538,
+  759,
+  833,
+  881,
+  8,
+  57,
+  74,
+  92,
+  117,
+  142,
+  383,
+  649,
+  738,
+  815,
+  821,
+  836,
+  919,
+  13,
+  18,
+  218,
+  342,
+  474,
+  664,
+  723,
+  827,
+  866,
+  147,
+  153,
+  240,
+  404,
+  557,
+  567,
+  591,
+  656,
+  721,
+  757,
+  822,
+  12,
+  98,
+  205,
+  241,
+  376,
+  394,
+  487,
+  494,
+  823,
+  919,
+  74,
+  272,
+  285,
+  362,
+  575,
+  598,
+  873,
+  880,
+  894,
+  119,
+  221,
+  227,
+  291,
+  338,
+  447,
+  507,
+  541,
+  559,
+  620,
+  721,
+  752,
+  802,
+  819,
+  835,
+  843,
+  849,
+  90,
+  130,
+  258,
+  417,
+  481,
+  576,
+  611,
+  826,
+  859,
+  893,
+  950,
+  321,
+  476,
+  528,
+  664,
+  679,
+  752,
+  789,
+  940,
+  951,
+  51,
+  97,
+  144,
+  274,
+  341,
+  384,
+  466,
+  627,
+  642,
+  682,
+  753,
+  766,
+  140,
+  301,
+  310,
+  340,
+  480,
+  669,
+  793,
+  885,
+  887,
+  917,
+  83,
+  115,
+  188,
+  269,
+  272,
+  418,
+  534,
+  546,
+  746,
+  810,
+  869,
+  109,
+  126,
+  185,
+  245,
+  345,
+  750,
+  759,
+  815,
+  854,
+  492,
+  514,
+  609,
+  647,
+  706,
+  726,
+  760,
+  106,
+  176,
+  289,
+  544,
+  753,
+  861,
+  901,
+  47,
+  145,
+  234,
+  253,
+  308,
+  466,
+  467,
+  826,
+  38,
+  89,
+  147,
+  210,
+  254,
+  270,
+  283,
+  453,
+  607,
+  727,
+  828,
+  874,
+  912,
+  915,
+  921,
+  17,
+  201,
+  303,
+  338,
+  815,
+  880,
+  984,
+  100,
+  296,
+  475,
+  490,
+  567,
+  963,
+  979,
+  72,
+  110,
+  120,
+  308,
+  451,
+  622,
+  670,
+  695,
+  696,
+  720,
+  912,
+  981,
+  23,
+  239,
+  255,
+  344,
+  397,
+  847,
+  950,
+  45,
+  141,
+  311,
+  607,
+  626,
+  877,
+  58,
+  87,
+  106,
+  132,
+  210,
+  232,
+  265,
+  373,
+  447,
+  476,
+  621,
+  887,
+  959,
+  134,
+  135,
+  187,
+  189,
+  345,
+  346,
+  411,
+  603,
+  626,
+  901,
+  21,
+  158,
+  177,
+  263,
+  344,
+  408,
+  458,
+  851,
+  855,
+  856,
+  942,
+  971,
+  978,
+  6,
+  23,
+  129,
+  235,
+  368,
+  400,
+  617,
+  962,
+  311,
+  445,
+  457,
+  530,
+  540,
+  650,
+  722,
+  18,
+  118,
+  176,
+  177,
+  337,
+  350,
+  510,
+  771,
+  787,
+  804,
+  839,
+  193,
+  229,
+  261,
+  434,
+  523,
+  528,
+  553,
+  559,
+  660,
+  673,
+  197,
+  400,
+  436,
+  481,
+  556,
+  566,
+  569,
+  627,
+  642,
+  662,
+  866,
+  101,
+  247,
+  354,
+  423,
+  611,
+  669,
+  714,
+  923,
+  323,
+  447,
+  531,
+  561,
+  668,
+  674,
+  700,
+  816,
+  921,
+  27,
+  243,
+  270,
+  324,
+  341,
+  380,
+  546,
+  594,
+  730,
+  877,
+  889,
+  367,
+  683,
+  847,
+  889,
+  897,
+  166,
+  535,
+  574,
+  680,
+  819,
+  949,
+  185,
+  261,
+  266,
+  637,
+  639,
+  669,
+  836,
+  963,
+  990,
+  72,
+  233,
+  450,
+  675,
+  815,
+  826,
+  996,
+  93,
+  129,
+  278,
+  355,
+  405,
+  422,
+  430,
+  550,
+  585,
+  727,
+  783,
+  795,
+  882,
+  51,
+  79,
+  303,
+  308,
+  311,
+  354,
+  449,
+  469,
+  530,
+  553,
+  572,
+  731,
+  757,
+  900,
+  933,
+  255,
+  359,
+  382,
+  405,
+  426,
+  453,
+  680,
+  727,
+  757,
+  195,
+  287,
+  342,
+  445,
+  687,
+  693,
+  824,
+  875,
+  955,
+  986,
+  29,
+  61,
+  154,
+  200,
+  236,
+  287,
+  359,
+  497,
+  568,
+  761,
+  843,
+  965,
+  140,
+  217,
+  301,
+  459,
+  518,
+  647,
+  698,
+  870,
+  880,
+  24,
+  60,
+  158,
+  202,
+  223,
+  333,
+  477,
+  746,
+  749,
+  826,
+  930,
+  265,
+  431,
+  539,
+  588,
+  610,
+  620,
+  900,
+  901,
+  929,
+  13,
+  117,
+  140,
+  170,
+  287,
+  390,
+  438,
+  580,
+  611,
+  659,
+  806,
+  916,
+  930,
+  940,
+  159,
+  296,
+  467,
+  534,
+  639,
+  679,
+  706,
+  878,
+  989,
+  147,
+  533,
+  545,
+  685,
+  741,
+  846,
+  2,
+  34,
+  251,
+  331,
+  424,
+  440,
+  647,
+  694,
+  733,
+  808,
+  866,
+  929,
+  423,
+  571,
+  667,
+  692,
+  996,
+  74,
+  347,
+  424,
+  565,
+  581,
+  618,
+  638,
+  658,
+  681,
+  833,
+  919,
+  936,
+  965,
+  128,
+  307,
+  357,
+  367,
+  412,
+  468,
+  523,
+  571,
+  616,
+  667,
+  683,
+  57,
+  137,
+  197,
+  337,
+  398,
+  606,
+  781,
+  840,
+  850,
+  864,
+  880,
+  948,
+  115,
+  177,
+  229,
+  265,
+  293,
+  303,
+  479,
+  659,
+  667,
+  813,
+  844,
+  953,
+  22,
+  95,
+  274,
+  308,
+  423,
+  485,
+  608,
+  632,
+  688,
+  820,
+  875,
+  945,
+  952,
+  71,
+  234,
+  248,
+  250,
+  497,
+  951,
+  141,
+  170,
+  236,
+  265,
+  394,
+  471,
+  567,
+  703,
+  854,
+  896,
+  897,
+  37,
+  164,
+  271,
+  395,
+  524,
+  793,
+  943,
+  5,
+  109,
+  156,
+  183,
+  293,
+  349,
+  383,
+  533,
+  679,
+  743,
+  114,
+  138,
+  236,
+  316,
+  334,
+  352,
+  489,
+  569,
+  699,
+  755,
+  904,
+  993,
+  314,
+  489,
+  568,
+  658,
+  736,
+  748,
+  848,
+  156,
+  160,
+  252,
+  472,
+  531,
+  613,
+  687,
+  701,
+  740,
+  767,
+  780,
+  841,
+  882,
+  975,
+  990,
+  47,
+  195,
+  363,
+  506,
+  654,
+  767,
+  792,
+  802,
+  150,
+  204,
+  319,
+  379,
+  455,
+  574,
+  843,
+  869,
+  84,
+  116,
+  190,
+  191,
+  193,
+  268,
+  366,
+  409,
+  579,
+  628,
+  767,
+  794,
+  801,
+  823,
+  887,
+  107,
+  176,
+  361,
+  465,
+  467,
+  647,
+  666,
+  700,
+  708,
+  720,
+  754,
+  784,
+  932,
+  959,
+  66,
+  167,
+  196,
+  213,
+  261,
+  319,
+  330,
+  398,
+  416,
+  534,
+  598,
+  677,
+  787,
+  800,
+  910,
+  961,
+  999,
+  404,
+  411,
+  452,
+  536,
+  786,
+  886,
+  940,
+  84,
+  116,
+  236,
+  334,
+  374,
+  433,
+  701,
+  870,
+  73,
+  184,
+  341,
+  367,
+  412,
+  423,
+  673,
+  678,
+  981,
+  258,
+  269,
+  313,
+  360,
+  423,
+  561,
+  602,
+  854,
+  985,
+  112,
+  227,
+  253,
+  256,
+  326,
+  327,
+  517,
+  624,
+  736,
+  891,
+  38,
+  79,
+  361,
+  369,
+  581,
+  583,
+  700,
+  43,
+  100,
+  329,
+  391,
+  722,
+  926,
+  967,
+  972,
+  82,
+  224,
+  254,
+  366,
+  389,
+  755,
+  756,
+  820,
+  942,
+  54,
+  393,
+  405,
+  464,
+  596,
+  663,
+  864,
+  966,
+  108,
+  297,
+  305,
+  368,
+  832,
+  878,
+  903,
+  918,
+  995,
+  324,
+  797,
+  823,
+  871,
+  298,
+  535,
+  642,
+  720,
+  803,
+  910,
+  961,
+  33,
+  319,
+  442,
+  492,
+  568,
+  803,
+  8,
+  84,
+  197,
+  359,
+  435,
+  791,
+  922,
+  949,
+  969,
+  984,
+  210,
+  220,
+  380,
+  904,
+  949,
+  977,
+  984,
+  22,
+  68,
+  83,
+  190,
+  333,
+  468,
+  648,
+  683,
+  783,
+  807,
+  856,
+  959,
+  54,
+  95,
+  180,
+  213,
+  353,
+  417,
+  721,
+  744,
+  888,
+  331,
+  388,
+  441,
+  951,
+  5,
+  86,
+  132,
+  167,
+  224,
+  366,
+  553,
+  655,
+  812,
+  815,
+  989,
+  33,
+  34,
+  183,
+  239,
+  270,
+  529,
+  811,
+  105,
+  117,
+  126,
+  220,
+  280,
+  315,
+  353,
+  201,
+  294,
+  364,
+  511,
+  521,
+  532,
+  557,
+  744,
+  756,
+  846,
+  173,
+  199,
+  436,
+  511,
+  712,
+  725,
+  27,
+  244,
+  262,
+  274,
+  347,
+  404,
+  486,
+  623,
+  857,
+  858,
+  34,
+  126,
+  217,
+  618,
+  674,
+  813,
+  818,
+  830,
+  876,
+  885,
+  63,
+  134,
+  200,
+  269,
+  427,
+  448,
+  486,
+  646,
+  774,
+  778,
+  928,
+  162,
+  229,
+  251,
+  273,
+  277,
+  281,
+  372,
+  448,
+  563,
+  606,
+  641,
+  845,
+  997,
+  81,
+  93,
+  153,
+  516,
+  592,
+  603,
+  641,
+  706,
+  929,
+  945,
+  17,
+  25,
+  109,
+  140,
+  440,
+  524,
+  803,
+  309,
+  494,
+  513,
+  542,
+  778,
+  809,
+  93,
+  161,
+  360,
+  405,
+  507,
+  556,
+  559,
+  734,
+  881,
+  986,
+  53,
+  238,
+  271,
+  320,
+  367,
+  600,
+  768,
+  940,
+  315,
+  351,
+  521,
+  530,
+  548,
+  549,
+  628,
+  881,
+  909,
+  917,
+  246,
+  296,
+  318,
+  324,
+  339,
+  359,
+  393,
+  511,
+  557,
+  690,
+  696,
+  764,
+  777,
+  810,
+  954,
+  73,
+  337,
+  473,
+  526,
+  601,
+  620,
+  668,
+  689,
+  698,
+  768,
+  782,
+  859,
+  930,
+  937,
+  942,
+  954,
+  162,
+  279,
+  410,
+  454,
+  958,
+  29,
+  36,
+  77,
+  109,
+  139,
+  185,
+  224,
+  270,
+  512,
+  601,
+  657,
+  664,
+  669,
+  683,
+  695,
+  734,
+  947,
+  146,
+  193,
+  464,
+  491,
+  767,
+  771,
+  818,
+  911,
+  947,
+  981,
+  56,
+  102,
+  291,
+  434,
+  527,
+  601,
+  613,
+  646,
+  731,
+  777,
+  3,
+  90,
+  179,
+  196,
+  270,
+  380,
+  458,
+  638,
+  680,
+  854,
+  883,
+  956,
+  72,
+  104,
+  272,
+  518,
+  755,
+  33,
+  387,
+  450,
+  519,
+  528,
+  576,
+  607,
+  637,
+  786,
+  228,
+  298,
+  355,
+  377,
+  414,
+  560,
+  847,
+  853,
+  927,
+  47,
+  191,
+  304,
+  328,
+  371,
+  424,
+  441,
+  555,
+  658,
+  837,
+  902,
+  132,
+  215,
+  252,
+  278,
+  293,
+  339,
+  390,
+  729,
+  754,
+  855,
+  896,
+  11,
+  115,
+  159,
+  173,
+  351,
+  407,
+  412,
+  438,
+  996,
+  87,
+  104,
+  164,
+  212,
+  213,
+  329,
+  419,
+  668,
+  683,
+  847,
+  940,
+  134,
+  245,
+  296,
+  306,
+  346,
+  369,
+  382,
+  417,
+  495,
+  555,
+  578,
+  662,
+  712,
+  844,
+  850,
+  885,
+  988,
+  58,
+  212,
+  347,
+  886,
+  925,
+  60,
+  132,
+  301,
+  377,
+  933,
+  26,
+  38,
+  49,
+  94,
+  176,
+  206,
+  344,
+  416,
+  686,
+  719,
+  734,
+  837,
+  32,
+  160,
+  194,
+  481,
+  567,
+  653,
+  711,
+  813,
+  871,
+  946,
+  980,
+  48,
+  53,
+  124,
+  170,
+  281,
+  370,
+  414,
+  501,
+  938,
+  943,
+  951,
+  115,
+  386,
+  540,
+  583,
+  678,
+  729,
+  901,
+  28,
+  105,
+  153,
+  177,
+  178,
+  443,
+  494,
+  496,
+  591,
+  609,
+  628,
+  683,
+  22,
+  144,
+  185,
+  234,
+  306,
+  323,
+  704,
+  830,
+  838,
+  923,
+  940,
+  29,
+  75,
+  140,
+  393,
+  625,
+  760,
+  916,
+  919,
+  15,
+  109,
+  266,
+  846,
+  107,
+  129,
+  278,
+  279,
+  323,
+  438,
+  461,
+  543,
+  567,
+  648,
+  713,
+  866,
+  908,
+  277,
+  320,
+  390,
+  421,
+  549,
+  564,
+  620,
+  885,
+  935,
+  58,
+  322,
+  330,
+  432,
+  435,
+  517,
+  578,
+  704,
+  941,
+  952,
+  89,
+  172,
+  420,
+  511,
+  542,
+  607,
+  654,
+  921,
+  103,
+  240,
+  287,
+  289,
+  302,
+  324,
+  399,
+  415,
+  657,
+  680,
+  764,
+  781,
+  799,
+  824,
+  835,
+  911,
+  36,
+  148,
+  156,
+  170,
+  241,
+  478,
+  600,
+  672,
+  685,
+  764,
+  936,
+  979,
+  106,
+  285,
+  492,
+  493,
+  834,
+  839,
+  873,
+  948,
+  956,
+  35,
+  50,
+  122,
+  176,
+  261,
+  597,
+  621,
+  628,
+  654,
+  935,
+  190,
+  244,
+  301,
+  337,
+  473,
+  646,
+  886,
+  76,
+  193,
+  213,
+  313,
+  331,
+  356,
+  408,
+  449,
+  511,
+  848,
+  853,
+  876,
+  19,
+  109,
+  168,
+  262,
+  269,
+  320,
+  467,
+  642,
+  650,
+  687,
+  703,
+  921,
+  936,
+  973,
+  43,
+  68,
+  305,
+  395,
+  433,
+  534,
+  746,
+  812,
+  815,
+  986,
+  998,
+  165,
+  240,
+  323,
+  346,
+  459,
+  468,
+  474,
+  650,
+  834,
+  919,
+  991,
+  993,
+  36,
+  40,
+  46,
+  195,
+  331,
+  346,
+  844,
+  852,
+  7,
+  216,
+  248,
+  548,
+  637,
+  733,
+  788,
+  810,
+  909,
+  151,
+  205,
+  248,
+  297,
+  381,
+  501,
+  589,
+  601,
+  610,
+  693,
+  851,
+  211,
+  379,
+  508,
+  770,
+  955,
+  17,
+  216,
+  372,
+  471,
+  804,
+  838,
+  934,
+  977,
+  16,
+  119,
+  332,
+  338,
+  478,
+  628,
+  803,
+  911,
+  8,
+  132,
+  144,
+  169,
+  192,
+  713,
+  748,
+  808,
+  824,
+  13,
+  19,
+  31,
+  78,
+  94,
+  513,
+  561,
+  587,
+  825,
+  953,
+  248,
+  254,
+  470,
+  520,
+  594,
+  634,
+  636,
+  647,
+  830,
+  862,
+  869,
+  17,
+  37,
+  62,
+  138,
+  270,
+  337,
+  449,
+  474,
+  540,
+  566,
+  583,
+  721,
+  929,
+  935,
+  954,
+  221,
+  273,
+  315,
+  397,
+  447,
+  641,
+  725,
+  830,
+  885,
+  928,
+  7,
+  175,
+  188,
+  464,
+  482,
+  493,
+  519,
+  612,
+  615,
+  666,
+  758,
+  807,
+  915,
+  70,
+  133,
+  350,
+  438,
+  479,
+  522,
+  564,
+  893,
+  120,
+  273,
+  384,
+  424,
+  446,
+  447,
+  467,
+  585,
+  633,
+  792,
+  948,
+  997,
+  7,
+  51,
+  151,
+  197,
+  232,
+  348,
+  581,
+  596,
+  628,
+  833,
+  890,
+  32,
+  96,
+  265,
+  272,
+  387,
+  691,
+  694,
+  17,
+  322,
+  369,
+  457,
+  499,
+  611,
+  735,
+  813,
+  885,
+  72,
+  84,
+  130,
+  210,
+  228,
+  334,
+  349,
+  396,
+  443,
+  483,
+  498,
+  508,
+  509,
+  762,
+  105,
+  127,
+  157,
+  198,
+  206,
+  286,
+  298,
+  371,
+  380,
+  516,
+  698,
+  738,
+  837,
+  840,
+  946,
+  982,
+  359,
+  436,
+  687,
+  802,
+  805,
+  950,
+  112,
+  113,
+  141,
+  282,
+  290,
+  524,
+  527,
+  624,
+  642,
+  762,
+  840,
+  858,
+  997,
+  30,
+  257,
+  465,
+  573,
+  605,
+  661,
+  752,
+  783,
+  795,
+  880,
+  907,
+  8,
+  101,
+  145,
+  253,
+  375,
+  459,
+  556,
+  559,
+  584,
+  748,
+  999,
+  50,
+  180,
+  388,
+  638,
+  902,
+  122,
+  192,
+  405,
+  468,
+  486,
+  562,
+  604,
+  841,
+  844,
+  134,
+  197,
+  381,
+  382,
+  414,
+  430,
+  431,
+  655,
+  666,
+  807,
+  958,
+  81,
+  210,
+  496,
+  538,
+  724,
+  903,
+  947,
+  51,
+  118,
+  243,
+  326,
+  537,
+  597,
+  836,
+  966,
+  11,
+  139,
+  147,
+  204,
+  214,
+  269,
+  288,
+  290,
+  304,
+  307,
+  334,
+  451,
+  575,
+  600,
+  661,
+  775,
+  800,
+  969,
+  986,
+  64,
+  206,
+  269,
+  403,
+  461,
+  508,
+  548,
+  581,
+  596,
+  692,
+  777,
+  124,
+  232,
+  312,
+  322,
+  447,
+  498,
+  526,
+  543,
+  656,
+  670,
+  712,
+  751,
+  907,
+  923,
+  71,
+  94,
+  114,
+  148,
+  201,
+  249,
+  293,
+  296,
+  331,
+  336,
+  505,
+  607,
+  768,
+  933,
+  217,
+  260,
+  296,
+  302,
+  311,
+  581,
+  625,
+  655,
+  781,
+  892,
+  926,
+  23,
+  43,
+  100,
+  156,
+  273,
+  337,
+  572,
+  673,
+  741,
+  980,
+  52,
+  156,
+  164,
+  336,
+  373,
+  400,
+  470,
+  951,
+  20,
+  30,
+  73,
+  179,
+  351,
+  566,
+  636,
+  872,
+  883,
+  944,
+  11,
+  62,
+  460,
+  482,
+  486,
+  495,
+  512,
+  651,
+  868,
+  917,
+  997,
+  16,
+  74,
+  417,
+  496,
+  590,
+  639,
+  692,
+  778,
+  781,
+  855,
+  928,
+  930,
+  259,
+  275,
+  477,
+  637,
+  748,
+  807,
+  957,
+  999,
+  38,
+  184,
+  260,
+  266,
+  268,
+  323,
+  391,
+  598,
+  628,
+  881,
+  947,
+  54,
+  62,
+  219,
+  270,
+  471,
+  473,
+  491,
+  673,
+  859,
+  892,
+  947,
+  72,
+  218,
+  309,
+  331,
+  372,
+  573,
+  741,
+  822,
+  825,
+  966,
+  48,
+  200,
+  205,
+  237,
+  261,
+  265,
+  338,
+  353,
+  666,
+  928,
+  967,
+  53,
+  74,
+  259,
+  284,
+  507,
+  615,
+  886,
+  905,
+  955,
+  10,
+  21,
+  44,
+  406,
+  460,
+  684,
+  782,
+  816,
+  826,
+  907,
+  34,
+  189,
+  260,
+  332,
+  356,
+  444,
+  460,
+  758,
+  781,
+  838,
+  842,
+  905,
+  967,
+  6,
+  7,
+  169,
+  220,
+  295,
+  384,
+  399,
+  442,
+  739,
+  922,
+  969,
+  286,
+  300,
+  401,
+  460,
+  503,
+  659,
+  686,
+  727,
+  749,
+  785,
+  974,
+  993,
+  998,
+  183,
+  210,
+  328,
+  450,
+  453,
+  480,
+  496,
+  517,
+  525,
+  549,
+  635,
+  716,
+  732,
+  748,
+  749,
+  832,
+  959,
+  95,
+  107,
+  121,
+  258,
+  326,
+  416,
+  588,
+  654,
+  753,
+  831,
+  34,
+  83,
+  101,
+  181,
+  224,
+  552,
+  623,
+  671,
+  866,
+  983,
+  997,
+  104,
+  129,
+  143,
+  198,
+  213,
+  420,
+  438,
+  612,
+  674,
+  910,
+  943,
+  210,
+  212,
+  218,
+  321,
+  330,
+  455,
+  692,
+  794,
+  839,
+  960,
+  965,
+  17,
+  101,
+  124,
+  395,
+  476,
+  513,
+  514,
+  566,
+  692,
+  846,
+  856,
+  859,
+  862,
+  908,
+  920,
+  947,
+  958,
+  8,
+  200,
+  373,
+  462,
+  556,
+  739,
+  796,
+  932,
+  951,
+  958,
+  44,
+  56,
+  186,
+  262,
+  310,
+  355,
+  380,
+  470,
+  593,
+  714,
+  906,
+  964,
+  989,
+  65,
+  114,
+  195,
+  306,
+  307,
+  355,
+  403,
+  469,
+  513,
+  654,
+  685,
+  800,
+  812,
+  816,
+  825,
+  843,
+  925,
+  3,
+  328,
+  425,
+  486,
+  730,
+  773,
+  789,
+  824,
+  943,
+  966,
+  967,
+  981,
+  984,
+  83,
+  156,
+  311,
+  439,
+  545,
+  565,
+  650,
+  682,
+  769,
+  299,
+  341,
+  409,
+  782,
+  943,
+  5,
+  52,
+  57,
+  123,
+  146,
+  175,
+  409,
+  443,
+  532,
+  989,
+  120,
+  158,
+  430,
+  436,
+  449,
+  640,
+  659,
+  734,
+  749,
+  834,
+  882,
+  911,
+  952,
+  22,
+  226,
+  442,
+  591,
+  879,
+  51,
+  69,
+  86,
+  97,
+  178,
+  263,
+  316,
+  425,
+  534,
+  554,
+  565,
+  888,
+  988,
+  991,
+  24,
+  352,
+  511,
+  522,
+  555,
+  570,
+  603,
+  696,
+  887,
+  960,
+  39,
+  133,
+  260,
+  401,
+  465,
+  526,
+  609,
+  732,
+  131,
+  206,
+  305,
+  669,
+  809,
+  877,
+  986,
+  439,
+  520,
+  567,
+  588,
+  617,
+  712,
+  891,
+  998,
+  274,
+  358,
+  425,
+  495,
+  715,
+  872,
+  918,
+  923,
+  951,
+  980,
+  983,
+  119,
+  123,
+  316,
+  324,
+  349,
+  644,
+  705,
+  718,
+  769,
+  781,
+  795,
+  884,
+  110,
+  133,
+  140,
+  152,
+  157,
+  495,
+  569,
+  608,
+  629,
+  803,
+  827,
+  909,
+  942,
+  9,
+  230,
+  268,
+  423,
+  626,
+  707,
+  724,
+  748,
+  828,
+  996,
+  274,
+  308,
+  436,
+  722,
+  879,
+  213,
+  259,
+  324,
+  329,
+  377,
+  534,
+  588,
+  827,
+  896,
+  149,
+  261,
+  591,
+  597,
+  785,
+  813,
+  883,
+  920,
+  996,
+  10,
+  64,
+  237,
+  417,
+  535,
+  686,
+  709,
+  717,
+  744,
+  41,
+  67,
+  260,
+  370,
+  405,
+  407,
+  520,
+  632,
+  893,
+  955,
+  127,
+  250,
+  336,
+  354,
+  388,
+  474,
+  591,
+  703,
+  805,
+  811,
+  833,
+  871,
+  881,
+  991,
+  994,
+  17,
+  91,
+  113,
+  122,
+  300,
+  301,
+  463,
+  716,
+  741,
+  776,
+  784,
+  906,
+  994,
+  33,
+  57,
+  206,
+  448,
+  520,
+  612,
+  769,
+  834,
+  282,
+  393,
+  441,
+  461,
+  503,
+  796,
+  72,
+  206,
+  304,
+  381,
+  565,
+  723,
+  114,
+  121,
+  130,
+  259,
+  346,
+  386,
+  432,
+  538,
+  575,
+  595,
+  855,
+  945
+};
+const double x[1000] = {
+  602,
+  730,
+  528,
+  886,
+  890,
+  755,
+  124,
+  435,
+  24,
+  245,
+  112,
+  144,
+  171,
+  746,
+  547,
+  172,
+  905,
+  97,
+  70,
+  133,
+  117,
+  951,
+  783,
+  271,
+  174,
+  263,
+  769,
+  889,
+  920,
+  698,
+  644,
+  138,
+  34,
+  866,
+  831,
+  249,
+  611,
+  672,
+  502,
+  450,
+  225,
+  557,
+  793,
+  244,
+  336,
+  942,
+  604,
+  135,
+  507,
+  328,
+  36,
+  299,
+  769,
+  323,
+  957,
+  171,
+  455,
+  627,
+  701,
+  624,
+  383,
+  354,
+  675,
+  971,
+  562,
+  945,
+  354,
+  90,
+  495,
+  269,
+  684,
+  468,
+  832,
+  38,
+  189,
+  103,
+  509,
+  754,
+  85,
+  70,
+  727,
+  897,
+  441,
+  745,
+  443,
+  561,
+  23,
+  796,
+  104,
+  178,
+  388,
+  178,
+  663,
+  652,
+  533,
+  738,
+  423,
+  500,
+  390,
+  567,
+  834,
+  806,
+  97,
+  517,
+  352,
+  636,
+  158,
+  839,
+  822,
+  68,
+  707,
+  838,
+  778,
+  15,
+  201,
+  364,
+  397,
+  166,
+  372,
+  39,
+  525,
+  360,
+  596,
+  664,
+  606,
+  182,
+  684,
+  147,
+  941,
+  695,
+  815,
+  721,
+  377,
+  215,
+  386,
+  265,
+  598,
+  890,
+  241,
+  302,
+  423,
+  623,
+  610,
+  26,
+  311,
+  887,
+  496,
+  968,
+  549,
+  581,
+  421,
+  638,
+  154,
+  471,
+  768,
+  953,
+  7,
+  906,
+  894,
+  155,
+  687,
+  813,
+  376,
+  463,
+  815,
+  436,
+  817,
+  5,
+  366,
+  412,
+  435,
+  825,
+  437,
+  614,
+  437,
+  14,
+  492,
+  117,
+  610,
+  0,
+  837,
+  665,
+  464,
+  847,
+  513,
+  606,
+  532,
+  503,
+  566,
+  270,
+  559,
+  509,
+  634,
+  339,
+  535,
+  708,
+  663,
+  1,
+  837,
+  508,
+  499,
+  216,
+  758,
+  36,
+  242,
+  351,
+  432,
+  439,
+  562,
+  307,
+  643,
+  498,
+  659,
+  16,
+  265,
+  653,
+  105,
+  527,
+  595,
+  448,
+  832,
+  381,
+  714,
+  533,
+  178,
+  644,
+  455,
+  667,
+  7,
+  378,
+  639,
+  19,
+  50,
+  415,
+  591,
+  827,
+  956,
+  69,
+  712,
+  767,
+  368,
+  552,
+  230,
+  288,
+  146,
+  676,
+  651,
+  333,
+  284,
+  782,
+  283,
+  774,
+  791,
+  451,
+  795,
+  991,
+  618,
+  620,
+  547,
+  769,
+  226,
+  563,
+  117,
+  524,
+  287,
+  615,
+  322,
+  41,
+  582,
+  156,
+  664,
+  261,
+  368,
+  702,
+  25,
+  439,
+  382,
+  123,
+  682,
+  970,
+  511,
+  928,
+  870,
+  453,
+  865,
+  724,
+  255,
+  504,
+  567,
+  105,
+  465,
+  146,
+  349,
+  616,
+  419,
+  389,
+  629,
+  964,
+  482,
+  483,
+  252,
+  183,
+  300,
+  578,
+  255,
+  825,
+  702,
+  650,
+  468,
+  808,
+  939,
+  360,
+  830,
+  281,
+  969,
+  139,
+  488,
+  603,
+  449,
+  731,
+  941,
+  172,
+  643,
+  569,
+  90,
+  966,
+  468,
+  818,
+  249,
+  649,
+  661,
+  661,
+  955,
+  52,
+  17,
+  364,
+  472,
+  854,
+  154,
+  543,
+  110,
+  327,
+  905,
+  715,
+  940,
+  612,
+  248,
+  634,
+  690,
+  326,
+  622,
+  52,
+  935,
+  244,
+  406,
+  604,
+  351,
+  303,
+  268,
+  717,
+  247,
+  475,
+  718,
+  835,
+  885,
+  534,
+  842,
+  942,
+  929,
+  713,
+  786,
+  72,
+  122,
+  443,
+  64,
+  512,
+  38,
+  189,
+  552,
+  935,
+  778,
+  832,
+  569,
+  144,
+  810,
+  634,
+  399,
+  261,
+  918,
+  728,
+  648,
+  340,
+  730,
+  358,
+  496,
+  928,
+  344,
+  929,
+  572,
+  876,
+  667,
+  933,
+  584,
+  122,
+  739,
+  978,
+  37,
+  250,
+  192,
+  113,
+  763,
+  214,
+  852,
+  365,
+  638,
+  570,
+  82,
+  861,
+  448,
+  649,
+  813,
+  950,
+  843,
+  154,
+  527,
+  12,
+  953,
+  153,
+  311,
+  177,
+  490,
+  754,
+  973,
+  511,
+  777,
+  649,
+  605,
+  311,
+  539,
+  133,
+  245,
+  940,
+  717,
+  851,
+  189,
+  905,
+  410,
+  214,
+  170,
+  983,
+  998,
+  404,
+  599,
+  843,
+  41,
+  955,
+  505,
+  916,
+  947,
+  851,
+  397,
+  194,
+  288,
+  781,
+  897,
+  546,
+  305,
+  113,
+  356,
+  454,
+  679,
+  774,
+  314,
+  897,
+  452,
+  169,
+  391,
+  344,
+  880,
+  840,
+  327,
+  404,
+  29,
+  353,
+  688,
+  196,
+  135,
+  860,
+  878,
+  288,
+  523,
+  335,
+  1,
+  680,
+  923,
+  480,
+  108,
+  10,
+  188,
+  165,
+  500,
+  331,
+  668,
+  279,
+  939,
+  797,
+  203,
+  925,
+  768,
+  310,
+  453,
+  213,
+  909,
+  769,
+  136,
+  93,
+  501,
+  926,
+  249,
+  888,
+  591,
+  628,
+  317,
+  668,
+  364,
+  375,
+  951,
+  432,
+  217,
+  765,
+  469,
+  458,
+  25,
+  330,
+  279,
+  734,
+  995,
+  187,
+  150,
+  739,
+  179,
+  551,
+  844,
+  920,
+  871,
+  906,
+  397,
+  540,
+  376,
+  123,
+  233,
+  19,
+  227,
+  109,
+  158,
+  20,
+  11,
+  899,
+  462,
+  655,
+  837,
+  756,
+  930,
+  580,
+  304,
+  655,
+  419,
+  695,
+  319,
+  496,
+  856,
+  575,
+  700,
+  223,
+  793,
+  462,
+  666,
+  274,
+  967,
+  650,
+  287,
+  521,
+  69,
+  898,
+  684,
+  759,
+  31,
+  373,
+  515,
+  56,
+  966,
+  971,
+  836,
+  950,
+  94,
+  647,
+  948,
+  766,
+  988,
+  556,
+  458,
+  415,
+  46,
+  741,
+  519,
+  186,
+  393,
+  409,
+  658,
+  349,
+  833,
+  339,
+  61,
+  250,
+  49,
+  63,
+  503,
+  21,
+  951,
+  809,
+  391,
+  242,
+  739,
+  823,
+  9,
+  548,
+  876,
+  431,
+  920,
+  451,
+  967,
+  291,
+  529,
+  37,
+  133,
+  656,
+  240,
+  981,
+  223,
+  167,
+  458,
+  624,
+  473,
+  570,
+  942,
+  260,
+  808,
+  16,
+  792,
+  699,
+  537,
+  84,
+  906,
+  429,
+  728,
+  320,
+  785,
+  301,
+  9,
+  679,
+  882,
+  98,
+  431,
+  223,
+  920,
+  173,
+  895,
+  605,
+  68,
+  698,
+  696,
+  987,
+  855,
+  191,
+  657,
+  533,
+  478,
+  321,
+  846,
+  921,
+  490,
+  278,
+  145,
+  500,
+  274,
+  974,
+  505,
+  33,
+  936,
+  691,
+  922,
+  140,
+  846,
+  951,
+  745,
+  893,
+  803,
+  316,
+  689,
+  960,
+  509,
+  518,
+  911,
+  121,
+  12,
+  477,
+  702,
+  94,
+  521,
+  751,
+  840,
+  492,
+  666,
+  922,
+  714,
+  43,
+  683,
+  871,
+  531,
+  774,
+  137,
+  914,
+  745,
+  722,
+  78,
+  398,
+  384,
+  536,
+  365,
+  245,
+  807,
+  925,
+  201,
+  917,
+  368,
+  214,
+  246,
+  143,
+  388,
+  937,
+  483,
+  480,
+  793,
+  415,
+  835,
+  554,
+  514,
+  838,
+  655,
+  837,
+  481,
+  483,
+  777,
+  447,
+  963,
+  596,
+  248,
+  819,
+  696,
+  540,
+  163,
+  333,
+  589,
+  863,
+  603,
+  835,
+  952,
+  253,
+  329,
+  552,
+  207,
+  684,
+  593,
+  618,
+  742,
+  53,
+  90,
+  27,
+  955,
+  217,
+  955,
+  20,
+  520,
+  221,
+  316,
+  45,
+  948,
+  552,
+  110,
+  594,
+  774,
+  517,
+  880,
+  32,
+  575,
+  852,
+  463,
+  685,
+  10,
+  58,
+  945,
+  572,
+  875,
+  633,
+  942,
+  880,
+  426,
+  283,
+  491,
+  848,
+  491,
+  280,
+  412,
+  1,
+  819,
+  199,
+  190,
+  577,
+  488,
+  936,
+  678,
+  79,
+  317,
+  408,
+  689,
+  353,
+  889,
+  294,
+  561,
+  501,
+  411,
+  554,
+  321,
+  193,
+  748,
+  309,
+  110,
+  454,
+  33,
+  28,
+  193,
+  166,
+  804,
+  710,
+  581,
+  70,
+  726,
+  805,
+  673,
+  751,
+  147,
+  793,
+  395,
+  151,
+  129,
+  143,
+  610,
+  700,
+  590,
+  577,
+  814,
+  104,
+  990,
+  56,
+  254,
+  816,
+  278,
+  108,
+  765,
+  31,
+  208,
+  804,
+  730,
+  960,
+  323,
+  152,
+  202,
+  449,
+  238,
+  907,
+  532,
+  618,
+  377,
+  295,
+  625,
+  252,
+  383,
+  345,
+  46,
+  934,
+  908,
+  851,
+  304,
+  235,
+  623,
+  808,
+  363,
+  80,
+  373,
+  858,
+  839,
+  385,
+  426,
+  727,
+  615,
+  675,
+  860,
+  602,
+  623,
+  780,
+  246,
+  22,
+  681,
+  623,
+  293,
+  421,
+  908,
+  419,
+  811,
+  631,
+  155,
+  139,
+  861,
+  262,
+  789,
+  344,
+  507,
+  14,
+  445,
+  995,
+  316,
+  74,
+  32,
+  239,
+  932,
+  586,
+  167,
+  578,
+  555,
+  8,
+  720,
+  804,
+  18,
+  185,
+  637,
+  185,
+  21,
+  121,
+  993,
+  457,
+  0,
+  911,
+  330,
+  214,
+  343,
+  600,
+  720,
+  645,
+  542,
+  991,
+  704,
+  261,
+  481,
+  242,
+  949,
+  909,
+  745,
+  799,
+  644,
+  858,
+  132,
+  886,
+  194,
+  886,
+  695,
+  912,
+  980,
+  956,
+  51,
+  885,
+  410,
+  88,
+  578,
+  636,
+  698,
+  636,
+  532,
+  579,
+  389,
+  124,
+  386,
+  54,
+  616,
+  203,
+  838,
+  732,
+  152,
+  775,
+  749,
+  373
+};
+const int ptr[1001] = {
+  0,
+  6,
+  18,
+  31,
+  40,
+  49,
+  58,
+  67,
+  75,
+  85,
+  98,
+  111,
+  121,
+  135,
+  139,
+  146,
+  159,
+  169,
+  175,
+  181,
+  191,
+  203,
+  210,
+  217,
+  228,
+  238,
+  245,
+  254,
+  265,
+  278,
+  290,
+  298,
+  311,
+  323,
+  332,
+  343,
+  353,
+  360,
+  370,
+  383,
+  396,
+  407,
+  415,
+  427,
+  433,
+  440,
+  449,
+  461,
+  467,
+  474,
+  487,
+  503,
+  510,
+  522,
+  530,
+  542,
+  549,
+  556,
+  570,
+  584,
+  594,
+  605,
+  614,
+  624,
+  629,
+  637,
+  644,
+  653,
+  663,
+  674,
+  685,
+  691,
+  701,
+  712,
+  723,
+  734,
+  746,
+  754,
+  766,
+  779,
+  788,
+  802,
+  809,
+  820,
+  831,
+  846,
+  860,
+  869,
+  874,
+  883,
+  886,
+  900,
+  915,
+  929,
+  937,
+  946,
+  955,
+  969,
+  985,
+  993,
+  1004,
+  1014,
+  1026,
+  1035,
+  1040,
+  1053,
+  1064,
+  1073,
+  1078,
+  1089,
+  1097,
+  1105,
+  1108,
+  1119,
+  1131,
+  1143,
+  1156,
+  1165,
+  1175,
+  1187,
+  1196,
+  1205,
+  1209,
+  1218,
+  1230,
+  1242,
+  1253,
+  1263,
+  1277,
+  1288,
+  1306,
+  1323,
+  1331,
+  1345,
+  1355,
+  1362,
+  1372,
+  1380,
+  1388,
+  1395,
+  1412,
+  1424,
+  1428,
+  1436,
+  1443,
+  1457,
+  1473,
+  1488,
+  1498,
+  1511,
+  1520,
+  1533,
+  1543,
+  1556,
+  1567,
+  1578,
+  1590,
+  1598,
+  1609,
+  1618,
+  1627,
+  1634,
+  1638,
+  1643,
+  1649,
+  1654,
+  1660,
+  1675,
+  1688,
+  1698,
+  1712,
+  1722,
+  1730,
+  1738,
+  1746,
+  1758,
+  1765,
+  1778,
+  1787,
+  1802,
+  1814,
+  1821,
+  1833,
+  1842,
+  1851,
+  1864,
+  1877,
+  1886,
+  1890,
+  1898,
+  1904,
+  1916,
+  1931,
+  1942,
+  1953,
+  1966,
+  1975,
+  1988,
+  1999,
+  2008,
+  2021,
+  2027,
+  2036,
+  2049,
+  2058,
+  2069,
+  2078,
+  2086,
+  2099,
+  2109,
+  2115,
+  2123,
+  2133,
+  2142,
+  2155,
+  2166,
+  2175,
+  2185,
+  2191,
+  2202,
+  2215,
+  2220,
+  2234,
+  2248,
+  2260,
+  2271,
+  2277,
+  2285,
+  2297,
+  2310,
+  2318,
+  2328,
+  2337,
+  2352,
+  2358,
+  2370,
+  2378,
+  2391,
+  2397,
+  2407,
+  2413,
+  2425,
+  2434,
+  2442,
+  2452,
+  2462,
+  2476,
+  2480,
+  2487,
+  2500,
+  2512,
+  2525,
+  2533,
+  2545,
+  2552,
+  2563,
+  2576,
+  2585,
+  2591,
+  2599,
+  2608,
+  2619,
+  2629,
+  2643,
+  2658,
+  2664,
+  2675,
+  2682,
+  2696,
+  2705,
+  2715,
+  2718,
+  2736,
+  2746,
+  2765,
+  2771,
+  2787,
+  2793,
+  2802,
+  2813,
+  2826,
+  2837,
+  2849,
+  2863,
+  2870,
+  2885,
+  2895,
+  2904,
+  2914,
+  2925,
+  2931,
+  2944,
+  2949,
+  2957,
+  2973,
+  2982,
+  2995,
+  3009,
+  3025,
+  3031,
+  3046,
+  3061,
+  3069,
+  3082,
+  3089,
+  3100,
+  3106,
+  3116,
+  3119,
+  3123,
+  3130,
+  3136,
+  3144,
+  3153,
+  3162,
+  3180,
+  3185,
+  3200,
+  3205,
+  3215,
+  3225,
+  3234,
+  3246,
+  3255,
+  3266,
+  3273,
+  3283,
+  3293,
+  3303,
+  3312,
+  3320,
+  3331,
+  3342,
+  3349,
+  3357,
+  3367,
+  3372,
+  3380,
+  3387,
+  3398,
+  3405,
+  3417,
+  3425,
+  3432,
+  3443,
+  3449,
+  3456,
+  3461,
+  3471,
+  3480,
+  3491,
+  3498,
+  3521,
+  3530,
+  3539,
+  3554,
+  3562,
+  3569,
+  3579,
+  3585,
+  3597,
+  3604,
+  3613,
+  3628,
+  3646,
+  3657,
+  3673,
+  3681,
+  3691,
+  3696,
+  3709,
+  3717,
+  3731,
+  3745,
+  3756,
+  3763,
+  3769,
+  3774,
+  3786,
+  3799,
+  3810,
+  3819,
+  3827,
+  3838,
+  3854,
+  3867,
+  3876,
+  3885,
+  3902,
+  3911,
+  3926,
+  3936,
+  3948,
+  3959,
+  3970,
+  3983,
+  3991,
+  4002,
+  4009,
+  4023,
+  4032,
+  4043,
+  4058,
+  4065,
+  4078,
+  4087,
+  4099,
+  4106,
+  4114,
+  4120,
+  4132,
+  4146,
+  4155,
+  4168,
+  4177,
+  4189,
+  4199,
+  4212,
+  4219,
+  4231,
+  4241,
+  4253,
+  4260,
+  4266,
+  4278,
+  4287,
+  4303,
+  4310,
+  4322,
+  4334,
+  4344,
+  4354,
+  4368,
+  4376,
+  4383,
+  4399,
+  4408,
+  4416,
+  4431,
+  4444,
+  4458,
+  4467,
+  4474,
+  4486,
+  4495,
+  4506,
+  4515,
+  4521,
+  4536,
+  4549,
+  4564,
+  4571,
+  4580,
+  4593,
+  4602,
+  4613,
+  4618,
+  4627,
+  4635,
+  4644,
+  4659,
+  4664,
+  4675,
+  4684,
+  4690,
+  4702,
+  4713,
+  4723,
+  4735,
+  4743,
+  4751,
+  4759,
+  4768,
+  4779,
+  4790,
+  4799,
+  4811,
+  4818,
+  4823,
+  4830,
+  4838,
+  4850,
+  4861,
+  4870,
+  4878,
+  4890,
+  4897,
+  4908,
+  4916,
+  4930,
+  4939,
+  4950,
+  4959,
+  4971,
+  4977,
+  4985,
+  4996,
+  4999,
+  5003,
+  5012,
+  5018,
+  5026,
+  5041,
+  5048,
+  5058,
+  5071,
+  5081,
+  5086,
+  5094,
+  5099,
+  5109,
+  5114,
+  5127,
+  5137,
+  5147,
+  5162,
+  5172,
+  5179,
+  5187,
+  5197,
+  5209,
+  5226,
+  5231,
+  5239,
+  5248,
+  5263,
+  5270,
+  5283,
+  5293,
+  5301,
+  5308,
+  5318,
+  5327,
+  5342,
+  5349,
+  5357,
+  5367,
+  5374,
+  5381,
+  5395,
+  5406,
+  5418,
+  5428,
+  5435,
+  5440,
+  5452,
+  5464,
+  5477,
+  5490,
+  5497,
+  5504,
+  5510,
+  5518,
+  5529,
+  5542,
+  5561,
+  5579,
+  5588,
+  5599,
+  5601,
+  5609,
+  5618,
+  5627,
+  5631,
+  5640,
+  5646,
+  5654,
+  5661,
+  5672,
+  5690,
+  5699,
+  5712,
+  5723,
+  5733,
+  5742,
+  5752,
+  5759,
+  5766,
+  5776,
+  5788,
+  5799,
+  5801,
+  5813,
+  5825,
+  5829,
+  5841,
+  5846,
+  5858,
+  5867,
+  5878,
+  5892,
+  5902,
+  5910,
+  5921,
+  5933,
+  5941,
+  5957,
+  5964,
+  5975,
+  5988,
+  6000,
+  6007,
+  6019,
+  6027,
+  6036,
+  6046,
+  6055,
+  6065,
+  6080,
+  6090,
+  6098,
+  6110,
+  6122,
+  6139,
+  6151,
+  6160,
+  6168,
+  6181,
+  6190,
+  6202,
+  6209,
+  6221,
+  6228,
+  6238,
+  6249,
+  6260,
+  6266,
+  6274,
+  6289,
+  6302,
+  6310,
+  6325,
+  6334,
+  6349,
+  6367,
+  6370,
+  6382,
+  6391,
+  6399,
+  6414,
+  6423,
+  6435,
+  6442,
+  6452,
+  6461,
+  6469,
+  6479,
+  6493,
+  6502,
+  6517,
+  6524,
+  6539,
+  6549,
+  6555,
+  6561,
+  6568,
+  6575,
+  6594,
+  6605,
+  6613,
+  6620,
+  6626,
+  6637,
+  6643,
+  6656,
+  6669,
+  6679,
+  6687,
+  6698,
+  6706,
+  6715,
+  6730,
+  6739,
+  6746,
+  6762,
+  6768,
+  6776,
+  6785,
+  6791,
+  6798,
+  6805,
+  6818,
+  6827,
+  6836,
+  6846,
+  6853,
+  6861,
+  6877,
+  6885,
+  6894,
+  6901,
+  6912,
+  6924,
+  6937,
+  6947,
+  6951,
+  6966,
+  6975,
+  6985,
+  6996,
+  7003,
+  7019,
+  7029,
+  7037,
+  7046,
+  7053,
+  7060,
+  7068,
+  7075,
+  7081,
+  7088,
+  7094,
+  7108,
+  7117,
+  7123,
+  7139,
+  7150,
+  7162,
+  7168,
+  7182,
+  7191,
+  7203,
+  7219,
+  7222,
+  7229,
+  7243,
+  7251,
+  7260,
+  7269,
+  7279,
+  7289,
+  7294,
+  7307,
+  7321,
+  7338,
+  7349,
+  7353,
+  7361,
+  7371,
+  7379,
+  7386,
+  7397,
+  7411,
+  7422,
+  7428,
+  7437,
+  7442,
+  7452,
+  7463,
+  7474,
+  7483,
+  7491,
+  7499,
+  7514,
+  7523,
+  7536,
+  7542,
+  7549,
+  7556,
+  7568,
+  7577,
+  7586,
+  7597,
+  7609,
+  7623,
+  7633,
+  7645,
+  7658,
+  7664,
+  7677,
+  7694,
+  7703,
+  7718,
+  7727,
+  7736,
+  7749,
+  7758,
+  7768,
+  7775,
+  7782,
+  7790,
+  7803,
+  7812,
+  7823,
+  7833,
+  7842,
+  7859,
+  7870,
+  7879,
+  7891,
+  7901,
+  7912,
+  7921,
+  7928,
+  7935,
+  7943,
+  7958,
+  7965,
+  7972,
+  7984,
+  7991,
+  7997,
+  8010,
+  8020,
+  8033,
+  8041,
+  8048,
+  8059,
+  8069,
+  8080,
+  8088,
+  8097,
+  8108,
+  8113,
+  8119,
+  8128,
+  8135,
+  8148,
+  8163,
+  8172,
+  8182,
+  8194,
+  8203,
+  8214,
+  8223,
+  8237,
+  8246,
+  8252,
+  8264,
+  8269,
+  8282,
+  8293,
+  8305,
+  8317,
+  8330,
+  8336,
+  8347,
+  8354,
+  8364,
+  8376,
+  8383,
+  8398,
+  8406,
+  8414,
+  8429,
+  8443,
+  8460,
+  8467,
+  8475,
+  8484,
+  8493,
+  8503,
+  8510,
+  8518,
+  8527,
+  8535,
+  8544,
+  8548,
+  8555,
+  8561,
+  8571,
+  8578,
+  8590,
+  8599,
+  8603,
+  8614,
+  8621,
+  8628,
+  8638,
+  8644,
+  8654,
+  8664,
+  8675,
+  8688,
+  8698,
+  8705,
+  8711,
+  8721,
+  8729,
+  8739,
+  8754,
+  8770,
+  8775,
+  8792,
+  8802,
+  8812,
+  8824,
+  8829,
+  8838,
+  8847,
+  8858,
+  8869,
+  8878,
+  8889,
+  8906,
+  8911,
+  8916,
+  8928,
+  8939,
+  8950,
+  8957,
+  8969,
+  8980,
+  8988,
+  8992,
+  9005,
+  9014,
+  9024,
+  9032,
+  9048,
+  9060,
+  9069,
+  9079,
+  9086,
+  9098,
+  9112,
+  9123,
+  9135,
+  9143,
+  9152,
+  9163,
+  9168,
+  9176,
+  9184,
+  9193,
+  9203,
+  9214,
+  9229,
+  9239,
+  9252,
+  9260,
+  9272,
+  9283,
+  9290,
+  9299,
+  9313,
+  9329,
+  9335,
+  9348,
+  9359,
+  9370,
+  9375,
+  9384,
+  9395,
+  9402,
+  9410,
+  9429,
+  9440,
+  9454,
+  9468,
+  9479,
+  9489,
+  9497,
+  9507,
+  9518,
+  9530,
+  9538,
+  9549,
+  9560,
+  9570,
+  9581,
+  9590,
+  9600,
+  9613,
+  9624,
+  9637,
+  9654,
+  9664,
+  9675,
+  9686,
+  9697,
+  9714,
+  9724,
+  9737,
+  9754,
+  9767,
+  9776,
+  9781,
+  9791,
+  9804,
+  9809,
+  9823,
+  9833,
+  9841,
+  9848,
+  9856,
+  9867,
+  9879,
+  9892,
+  9902,
+  9907,
+  9916,
+  9925,
+  9934,
+  9944,
+  9959,
+  9972,
+  9980,
+  9986,
+  9992,
+  10004
+};
+const double verify_data[1000] = {
+  1971101,
+  3601995,
+  3608374,
+  3068439,
+  2756891,
+  1644445,
+  2326970,
+  3571797,
+  2167311,
+  3272467,
+  5257490,
+  2287052,
+  5507394,
+  1707471,
+  1181529,
+  2596954,
+  2999820,
+  1456597,
+  1755714,
+  2783599,
+  2224880,
+  953747,
+  1863442,
+  2375479,
+  3838149,
+  1472958,
+  2613759,
+  1412651,
+  2454897,
+  4139599,
+  1540527,
+  2373885,
+  2371153,
+  2496043,
+  2946006,
+  3041837,
+  2102841,
+  3413598,
+  3937131,
+  3428786,
+  2323528,
+  1657458,
+  3358521,
+  1821261,
+  937257,
+  2638848,
+  3351703,
+  2436591,
+  1387045,
+  3372777,
+  4422352,
+  2696491,
+  2775768,
+  1711500,
+  2463910,
+  1906176,
+  2655972,
+  2176802,
+  4025605,
+  1836921,
+  2902963,
+  1950818,
+  2553243,
+  2012524,
+  2449182,
+  1632320,
+  2628093,
+  1093587,
+  3089207,
+  3020390,
+  1485696,
+  1932818,
+  3334949,
+  1610563,
+  2076427,
+  3114683,
+  1548840,
+  3339439,
+  3335032,
+  1366398,
+  1685659,
+  1668385,
+  2510712,
+  2871270,
+  3270369,
+  4311377,
+  1982006,
+  1326681,
+  1381634,
+  398901,
+  3333661,
+  3352243,
+  2878790,
+  1577319,
+  2415255,
+  1191188,
+  3219765,
+  3467850,
+  1940862,
+  2056258,
+  1786527,
+  2278347,
+  2077897,
+  1457888,
+  3707208,
+  1405999,
+  952210,
+  1600564,
+  2343319,
+  1781556,
+  2474389,
+  522450,
+  3674982,
+  3619187,
+  3211390,
+  3586103,
+  1475431,
+  3546147,
+  3698208,
+  2049193,
+  1979189,
+  1111515,
+  2790498,
+  3439083,
+  4279066,
+  2774436,
+  2077245,
+  4390617,
+  3149593,
+  5326535,
+  3848199,
+  2772446,
+  2682304,
+  2277814,
+  1222790,
+  2067874,
+  1982666,
+  2371257,
+  1270393,
+  3228410,
+  2598823,
+  2428645,
+  904561,
+  2100006,
+  2337148,
+  3164102,
+  3908197,
+  1529402,
+  3084375,
+  1927419,
+  3196639,
+  2303890,
+  4265937,
+  2061281,
+  2212135,
+  2407656,
+  1723976,
+  2903704,
+  3276733,
+  1491735,
+  1684162,
+  1307018,
+  1201185,
+  636997,
+  1186016,
+  1774809,
+  2607471,
+  2619840,
+  3493545,
+  3226129,
+  1737347,
+  2380184,
+  1201957,
+  983240,
+  2529069,
+  2689857,
+  3022018,
+  2223714,
+  3625235,
+  3008732,
+  2417998,
+  4428750,
+  2270952,
+  2186948,
+  4812008,
+  2233927,
+  3334976,
+  1264519,
+  1626345,
+  1123879,
+  3098605,
+  4036407,
+  3104973,
+  2897790,
+  3788865,
+  2422217,
+  3611590,
+  1749696,
+  2447434,
+  2977777,
+  1573650,
+  2620107,
+  2319242,
+  2902283,
+  1882200,
+  1787017,
+  2436605,
+  3467551,
+  2413830,
+  187567,
+  2242075,
+  1754385,
+  1836061,
+  4245412,
+  3751015,
+  2715151,
+  1557751,
+  421948,
+  2963355,
+  2050843,
+  1758567,
+  2680768,
+  4076059,
+  4484640,
+  3293151,
+  1433126,
+  1649435,
+  4409656,
+  2223098,
+  2455979,
+  1874200,
+  2098066,
+  4020158,
+  1312572,
+  2801068,
+  3341899,
+  3785087,
+  1569098,
+  2778159,
+  1992179,
+  2669866,
+  1914494,
+  1619868,
+  2274333,
+  1857912,
+  3099797,
+  809499,
+  1679713,
+  3531350,
+  2599926,
+  1970143,
+  2920228,
+  2883295,
+  1394658,
+  3554897,
+  3534392,
+  1625041,
+  1492274,
+  1451033,
+  2248274,
+  2910569,
+  2341827,
+  2768016,
+  3567361,
+  781606,
+  2434644,
+  1782504,
+  4124675,
+  3646132,
+  2864945,
+  512560,
+  3618571,
+  2223074,
+  4315721,
+  1195043,
+  4737421,
+  1748427,
+  3474050,
+  1798506,
+  4916152,
+  2411793,
+  3382242,
+  5132409,
+  810557,
+  4870878,
+  1368859,
+  2955757,
+  1940419,
+  3146202,
+  880792,
+  3448573,
+  1017493,
+  2481321,
+  3652309,
+  3475252,
+  2845994,
+  3182841,
+  5898263,
+  1771223,
+  3346757,
+  2512678,
+  1778448,
+  3432671,
+  2814247,
+  3403195,
+  812303,
+  2104162,
+  85040,
+  989115,
+  1897384,
+  1248980,
+  2002961,
+  1371732,
+  2373820,
+  5178478,
+  1511192,
+  5127654,
+  1468260,
+  2185303,
+  2436412,
+  2978141,
+  2230665,
+  1707852,
+  2529167,
+  1152196,
+  3239187,
+  2498749,
+  2707774,
+  1502699,
+  1633289,
+  2782744,
+  4089832,
+  1548833,
+  1704769,
+  2712629,
+  992084,
+  1369606,
+  2480517,
+  2846051,
+  3100172,
+  2371224,
+  1173652,
+  1837754,
+  3822172,
+  1417367,
+  1538908,
+  1146694,
+  2528965,
+  2800885,
+  3461160,
+  786155,
+  6573509,
+  3071638,
+  1511640,
+  3652853,
+  1475533,
+  1525596,
+  2695806,
+  1277883,
+  3278333,
+  2226936,
+  2030339,
+  3914645,
+  4318373,
+  2059669,
+  3961569,
+  1772074,
+  3135802,
+  1261862,
+  4771438,
+  1587528,
+  2435428,
+  2869031,
+  2629400,
+  1533986,
+  1866116,
+  1203541,
+  2007311,
+  4295134,
+  3082652,
+  2127515,
+  3110833,
+  2895900,
+  4701588,
+  2727753,
+  2324739,
+  2142817,
+  4359375,
+  2762710,
+  2675084,
+  2776056,
+  2906201,
+  2859945,
+  1471060,
+  3224362,
+  2455374,
+  2030195,
+  909337,
+  2716237,
+  2230075,
+  3070171,
+  4476596,
+  2646370,
+  3421732,
+  2163616,
+  4043766,
+  2111374,
+  2016619,
+  1318843,
+  3586217,
+  3000490,
+  2914687,
+  2728187,
+  3496083,
+  3137438,
+  1555757,
+  2975780,
+  864871,
+  3568793,
+  3273559,
+  4362169,
+  1225951,
+  1858409,
+  1867854,
+  2081582,
+  4028493,
+  1772236,
+  2634979,
+  3563733,
+  1734270,
+  2430471,
+  3597625,
+  1010411,
+  1086456,
+  3717761,
+  3038402,
+  1630224,
+  4565438,
+  3347069,
+  2543316,
+  3034145,
+  1190307,
+  3710367,
+  2894919,
+  4122408,
+  1917891,
+  1308296,
+  1847812,
+  2799933,
+  5544619,
+  990734,
+  2302389,
+  2828494,
+  2767749,
+  2734181,
+  1584801,
+  2096227,
+  2132396,
+  1605917,
+  3953389,
+  489065,
+  3370917,
+  1246610,
+  1859633,
+  3905768,
+  2375583,
+  2352791,
+  3066605,
+  3023804,
+  1714567,
+  1630198,
+  3244096,
+  3311209,
+  2837076,
+  1806523,
+  3111912,
+  924345,
+  891749,
+  1710635,
+  2779972,
+  2288984,
+  2104226,
+  2726511,
+  2994247,
+  4159385,
+  927922,
+  3372483,
+  2093351,
+  3228595,
+  1549615,
+  3203118,
+  1566786,
+  2046013,
+  1122663,
+  902592,
+  2101848,
+  633763,
+  1382735,
+  2235887,
+  1595380,
+  1684910,
+  4534882,
+  1927642,
+  3881319,
+  4091228,
+  3489550,
+  1186206,
+  1089968,
+  1673520,
+  2908231,
+  1060251,
+  4422500,
+  2814892,
+  2014163,
+  3954105,
+  2685902,
+  1427353,
+  1040905,
+  2481509,
+  2984177,
+  5050926,
+  1266027,
+  2158372,
+  2317752,
+  4020554,
+  1226253,
+  3034218,
+  3335936,
+  3282626,
+  1782262,
+  3007006,
+  2399815,
+  4116453,
+  1101525,
+  2175742,
+  1919181,
+  1935647,
+  3021439,
+  2975812,
+  1409385,
+  3435714,
+  2843659,
+  2535310,
+  973352,
+  4051148,
+  3198667,
+  3025227,
+  3821291,
+  2634495,
+  1066026,
+  1015860,
+  2374721,
+  1893315,
+  2896157,
+  5768610,
+  4638503,
+  1096525,
+  2521763,
+  201516,
+  1885950,
+  2456554,
+  2395576,
+  1805310,
+  3539192,
+  706652,
+  3652867,
+  1803915,
+  2740108,
+  4902727,
+  2480670,
+  4763486,
+  2831231,
+  2804267,
+  2958655,
+  1180330,
+  1377988,
+  1967048,
+  3251495,
+  3641699,
+  2327118,
+  518996,
+  3627226,
+  4512513,
+  821503,
+  4513458,
+  1746977,
+  3396668,
+  2072470,
+  3064446,
+  4435618,
+  2734309,
+  2193304,
+  4275484,
+  3468741,
+  2498396,
+  3068739,
+  1699359,
+  2816909,
+  2705770,
+  2392503,
+  1288021,
+  2667346,
+  1722567,
+  2924017,
+  3160472,
+  1098169,
+  3756129,
+  5913618,
+  3768712,
+  2089078,
+  2340072,
+  2483109,
+  4368798,
+  2778403,
+  1706517,
+  2503001,
+  2633764,
+  2488649,
+  3759253,
+  1596753,
+  1671868,
+  1377167,
+  2721074,
+  2026518,
+  3148597,
+  1753515,
+  2407030,
+  3191030,
+  3974792,
+  1798541,
+  4805468,
+  2569249,
+  4324091,
+  3385093,
+  745588,
+  2231981,
+  2000465,
+  2339460,
+  3327609,
+  3719613,
+  4276833,
+  1018769,
+  2495582,
+  2942706,
+  2035953,
+  2227503,
+  3631249,
+  2988856,
+  2784977,
+  1822310,
+  4621193,
+  2352625,
+  1249877,
+  1540945,
+  1241921,
+  1994350,
+  5628798,
+  1620488,
+  1897543,
+  952310,
+  1052254,
+  3358187,
+  2994928,
+  2959189,
+  2720309,
+  2875425,
+  2144130,
+  4548462,
+  2048162,
+  1339841,
+  4090958,
+  1862715,
+  1268274,
+  4042390,
+  1581631,
+  2874452,
+  1735445,
+  1588799,
+  1331885,
+  2179684,
+  5179645,
+  1959366,
+  2027198,
+  2755029,
+  2265692,
+  2335785,
+  4348426,
+  1879924,
+  2696539,
+  1106357,
+  2932568,
+  2492358,
+  3120132,
+  3691105,
+  1442767,
+  4534420,
+  2112951,
+  2625910,
+  3375099,
+  1555111,
+  4988419,
+  1174798,
+  1332818,
+  1869705,
+  1696774,
+  1175511,
+  1819161,
+  1548388,
+  1420761,
+  1580164,
+  943541,
+  4405558,
+  2240390,
+  1501984,
+  4062955,
+  3082580,
+  2967491,
+  1152855,
+  3788527,
+  2868984,
+  4078134,
+  3701904,
+  752170,
+  1758523,
+  3256074,
+  2335111,
+  2496969,
+  2165110,
+  2589055,
+  1648006,
+  966763,
+  3719559,
+  4883836,
+  2489406,
+  2900336,
+  1003207,
+  914713,
+  2687415,
+  2957174,
+  991602,
+  3005713,
+  3016805,
+  3646583,
+  2002778,
+  2188117,
+  996416,
+  3940661,
+  3749144,
+  1702093,
+  1779575,
+  2135189,
+  1198463,
+  1665170,
+  1230802,
+  3071243,
+  1250575,
+  1159769,
+  2008716,
+  2577482,
+  1680782,
+  2755046,
+  2798673,
+  2779172,
+  4719731,
+  2451896,
+  2268516,
+  3364116,
+  2139930,
+  4014502,
+  5474835,
+  2379560,
+  3272928,
+  2133308,
+  2638465,
+  3610736,
+  2437161,
+  2469816,
+  1951246,
+  1998282,
+  2022421,
+  2093450,
+  2415039,
+  4011191,
+  2829334,
+  2863331,
+  4093600,
+  2661113,
+  2923200,
+  2198013,
+  2162835,
+  2958211,
+  1829311,
+  750764,
+  1125263,
+  1293794,
+  4883789,
+  1165273,
+  1322292,
+  2045605,
+  1796576,
+  1587215,
+  3595048,
+  2442957,
+  3675117,
+  2022610,
+  2207877,
+  3164247,
+  2539827,
+  2289433,
+  2050621,
+  2033111,
+  2996013,
+  643859,
+  1353849,
+  2284477,
+  1687120,
+  2374034,
+  3975861,
+  3174103,
+  3090405,
+  3004853,
+  1655110,
+  2881453,
+  3229992,
+  3406893,
+  1953384,
+  2162162,
+  3005248,
+  1806960,
+  2262637,
+  2658934,
+  3172203,
+  2346601,
+  2083857,
+  1905139,
+  2243485,
+  1779413,
+  2958736,
+  2324181,
+  1167937,
+  2487352,
+  2195558,
+  2511598,
+  3374057,
+  3239559,
+  3989322,
+  2007874,
+  1142953,
+  1917363,
+  1413284,
+  2254989,
+  2519517,
+  2612721,
+  1979898,
+  1472130,
+  4246577,
+  678823,
+  1032892,
+  1956684,
+  2963972,
+  2501714,
+  3206467,
+  3867577,
+  1866296,
+  1852756,
+  2674353,
+  2068891,
+  2485623,
+  1691978,
+  3224678,
+  2235530,
+  2642436,
+  3528805,
+  3154289,
+  763332,
+  2188687,
+  2175236,
+  3423181,
+  2228774,
+  4926897,
+  4720293,
+  1365097,
+  4384144,
+  1933318,
+  1538742,
+  3060760,
+  891455,
+  2247727,
+  1481978,
+  2009726,
+  3389542,
+  737932,
+  4035426,
+  4661761,
+  1332633,
+  913928,
+  2479290,
+  1992229,
+  2961682,
+  1641167,
+  3217414,
+  3225260,
+  2595246,
+  591918,
+  5566353,
+  2528672,
+  2502651,
+  1241588,
+  2590376,
+  3876970,
+  1793155,
+  1501528,
+  1838442,
+  2522918,
+  2422260,
+  3056321,
+  2273838,
+  2071241,
+  1658722,
+  2562266,
+  1338349,
+  1376886,
+  2223907,
+  1921712,
+  2211260,
+  1602704,
+  5260200,
+  2189077,
+  3019251,
+  2106858,
+  3976347,
+  2463524,
+  1576729,
+  491605,
+  3168168,
+  4672180,
+  1922298,
+  2396219,
+  2857066,
+  3012596,
+  874988,
+  2600192,
+  2197450,
+  1567978,
+  1636166,
+  4334187,
+  2964752,
+  4434709,
+  2753079,
+  2384760,
+  1534463,
+  2112708,
+  2065799,
+  1431116,
+  3960134,
+  2861238,
+  2406750,
+  2744852,
+  2940188,
+  3343790,
+  2451949,
+  2431427,
+  2343771,
+  4247520,
+  2386347,
+  5806313,
+  2995484,
+  3520605,
+  1723394,
+  2278390,
+  4240678,
+  1794433,
+  3515379,
+  4577968,
+  2412014,
+  1533701,
+  733354,
+  2879952,
+  4102595,
+  1847856,
+  1920316,
+  2281251,
+  1136467,
+  2032967,
+  2387741,
+  2059754,
+  3098458,
+  2813846,
+  2264943,
+  1328950,
+  1544527,
+  1143015,
+  2417418,
+  2816076,
+  4485204,
+  2576250,
+  2144794,
+  1827914,
+  1906691,
+  2348923
+};
diff --git a/benchmarks/spmv/spmv_gendata.scala b/benchmarks/spmv/spmv_gendata.scala
new file mode 100644 (file)
index 0000000..f777445
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/env scala
+!#
+
+val m = args(0).toInt
+val n = args(1).toInt
+val approx_nnz = args(2).toInt
+
+val pnnz = approx_nnz.toDouble/(m*n)
+val idx = collection.mutable.ArrayBuffer[Int]()
+val p = collection.mutable.ArrayBuffer(0)
+
+for (i <- 0 until m) {
+  for (j <- 0 until n) {
+    if (util.Random.nextDouble < pnnz)
+      idx += j
+  }
+  p += idx.length
+}
+
+val nnz = idx.length
+val v = Array.tabulate(n)(i => util.Random.nextInt(1000))
+val d = Array.tabulate(nnz)(i => util.Random.nextInt(1000))
+
+def printVec(t: String, name: String, data: Seq[Int]) = {
+  println("const " + t + " " + name + "[" + data.length + "] = {")
+  println("  "+data.map(_.toString).reduceLeft(_+",\n  "+_))
+  println("};")
+}
+
+def spmv(p: Seq[Int], d: Seq[Int], idx: Seq[Int], v: Seq[Int]) = {
+  val y = collection.mutable.ArrayBuffer[Int]()
+  for (i <- 0 until p.length-1) {
+    var yi = 0
+    for (k <- p(i) until p(i+1))
+      yi = yi + d(k)*v(idx(k))
+    y += yi
+  }
+  y
+}
+
+println("#define R " + m)
+println("#define C " + n)
+println("#define NNZ " + nnz)
+printVec("double", "val", d)
+printVec("int", "idx", idx)
+printVec("double", "x", v)
+printVec("int", "ptr", p)
+printVec("double", "verify_data", spmv(p, d, idx, v))
diff --git a/benchmarks/spmv/spmv_main.c b/benchmarks/spmv/spmv_main.c
new file mode 100644 (file)
index 0000000..11d9540
--- /dev/null
@@ -0,0 +1,123 @@
+//**************************************************************************
+// Double-precision general matrix multiplication benchmark
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( long n, const double test[], const double correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+#include <stdio.h>
+#include <stdlib.h>
+void printArray( char name[], long n, const double arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %8.1f ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+void spmv(int r, const double* val, const int* idx, const double* x,
+          const int* ptr, double* y)
+{
+  for (int i = 0; i < r; i++)
+  {
+    int k;
+    double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
+    for (k = ptr[i]; k < ptr[i+1]-3; k+=4)
+    {
+      yi0 += val[k+0]*x[idx[k+0]];
+      yi1 += val[k+1]*x[idx[k+1]];
+      yi2 += val[k+2]*x[idx[k+2]];
+      yi3 += val[k+3]*x[idx[k+3]];
+    }
+    for ( ; k < ptr[i+1]; k++)
+    {
+      yi0 += val[k]*x[idx[k]];
+    }
+    y[i] = (yi0+yi1)+(yi2+yi3);
+  }
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  double y[R];
+
+#if PREALLOCATE
+  spmv(R, val, idx, x, ptr, y);
+#endif
+
+  setStats(1);
+  spmv(R, val, idx, x, ptr, y);
+  setStats(0);
+
+  finishTest(verify(R, y, verify_data));
+}
diff --git a/benchmarks/towers/bmark.mk b/benchmarks/towers/bmark.mk
new file mode 100644 (file)
index 0000000..0c16a81
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+towers_c_src = \
+       towers_main.c \
+
+towers_riscv_src = \
+       crt.S \
+
+towers_c_objs     = $(patsubst %.c, %.o, $(towers_c_src))
+towers_riscv_objs = $(patsubst %.S, %.o, $(towers_riscv_src))
+
+towers_host_bin = towers.host
+$(towers_host_bin) : $(towers_c_src)
+       $(HOST_COMP) $^ -o $(towers_host_bin)
+
+towers_riscv_bin = towers.riscv
+$(towers_riscv_bin) : $(towers_c_objs) $(towers_riscv_objs)
+       $(RISCV_LINK) $(towers_c_objs) $(towers_riscv_objs) -o $(towers_riscv_bin)
+
+junk += $(towers_c_objs) $(towers_riscv_objs) \
+        $(towers_host_bin) $(towers_riscv_bin)
diff --git a/benchmarks/towers/towers_main.c b/benchmarks/towers/towers_main.c
new file mode 100644 (file)
index 0000000..36526a2
--- /dev/null
@@ -0,0 +1,341 @@
+//**************************************************************************
+// Towers of Hanoi benchmark
+//--------------------------------------------------------------------------
+//
+// Towers of Hanoi is a classic puzzle problem. The game consists of
+// three pegs and a set of discs. Each disc is a different size, and
+// initially all of the discs are on the left most peg with the smallest
+// disc on top and the largest disc on the bottom. The goal is to move all
+// of the discs onto the right most peg. The catch is that you are only
+// allowed to move one disc at a time and you can never place a larger
+// disc on top of a smaller disc.
+//
+// This implementation starts with NUM_DISC discs and uses a recursive
+// algorithm to sovel the puzzle.  The smips-gcc toolchain does not support
+// system calls so printf's can only be used on a host system, not on the
+// smips processor simulator itself. You should not change anything except
+// the HOST_DEBUG and PREALLOCATE macros for your timing run.
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+// This is the number of discs in the puzzle.
+
+#define NUM_DISCS  7
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// List data structure and functions
+
+struct Node
+{
+  int val;
+  struct Node* next;
+};
+
+struct List
+{
+  int size;
+  struct Node* head;
+};
+
+struct List g_nodeFreeList;
+struct Node g_nodePool[NUM_DISCS];
+
+int list_getSize( struct List* list )
+{
+  return list->size;
+}
+
+void list_init( struct List* list )
+{
+  list->size = 0;
+  list->head = 0;
+}
+
+void list_push( struct List* list, int val )
+{
+  struct Node* newNode;
+
+  // Pop the next free node off the free list
+  newNode = g_nodeFreeList.head;
+  g_nodeFreeList.head = g_nodeFreeList.head->next;
+
+  // Push the new node onto the given list
+  newNode->next = list->head;
+  list->head = newNode;
+
+  // Assign the value
+  list->head->val = val;
+
+  // Increment size
+  list->size++;
+
+}
+
+int list_pop( struct List* list )
+{
+  struct Node* freedNode;
+  int val;
+
+  // Get the value from the->head of given list
+  val = list->head->val;
+
+  // Pop the head node off the given list
+  freedNode = list->head;
+  list->head = list->head->next;
+
+  // Push the freed node onto the free list
+  freedNode->next = g_nodeFreeList.head;
+  g_nodeFreeList.head = freedNode;
+
+  // Decrement size
+  list->size--;
+
+  return val;
+}
+
+void list_clear( struct List* list )
+{
+  while ( list_getSize(list) > 0 )
+    list_pop(list);
+}
+
+//--------------------------------------------------------------------------
+// Tower data structure and functions
+
+struct Towers
+{
+  int numDiscs;
+  int numMoves;
+  struct List pegA;
+  struct List pegB;
+  struct List pegC;
+};
+
+void towers_init( struct Towers* this, int n )
+{
+  int i;
+
+  this->numDiscs = n;
+  this->numMoves = 0;
+
+  list_init( &(this->pegA) );
+  list_init( &(this->pegB) );
+  list_init( &(this->pegC) );
+
+  for ( i = 0; i < n; i++ )
+    list_push( &(this->pegA), n-i );
+
+}
+
+void towers_clear( struct Towers* this )
+{
+
+  list_clear( &(this->pegA) );
+  list_clear( &(this->pegB) );
+  list_clear( &(this->pegC) );
+
+  towers_init( this, this->numDiscs );
+
+}
+
+#if HOST_DEBUG
+void towers_print( struct Towers* this )
+{
+  struct Node* ptr;
+  int i, numElements;
+
+  printf( "  pegA: " );
+  for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegA))); i++ )
+    printf( ". " );
+  for ( ptr = this->pegA.head; ptr != 0; ptr = ptr->next )
+    printf( "%d ", ptr->val );
+
+  printf( "  pegB: " );
+  for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegB))); i++ )
+    printf( ". " );
+  for ( ptr = this->pegB.head; ptr != 0; ptr = ptr->next )
+    printf( "%d ", ptr->val );
+
+  printf( "  pegC: " );
+  for ( i = 0; i < ((this->numDiscs)-list_getSize(&(this->pegC))); i++ )
+    printf( ". " );
+  for ( ptr = this->pegC.head; ptr != 0; ptr = ptr->next )
+    printf( "%d ", ptr->val );
+
+  printf( "\n" );
+}
+#endif
+
+void towers_solve_h( struct Towers* this, int n,
+                     struct List* startPeg,
+                     struct List* tempPeg,
+                     struct List* destPeg )
+{
+  int val;
+
+  if ( n == 1 ) {
+#if HOST_DEBUG
+    towers_print(this);
+#endif
+    val = list_pop(startPeg);
+    list_push(destPeg,val);
+    this->numMoves++;
+  }
+  else {
+    towers_solve_h( this, n-1, startPeg, destPeg,  tempPeg );
+    towers_solve_h( this, 1,   startPeg, tempPeg,  destPeg );
+    towers_solve_h( this, n-1, tempPeg,  startPeg, destPeg );
+  }
+
+}
+
+void towers_solve( struct Towers* this )
+{
+  towers_solve_h( this, this->numDiscs, &(this->pegA), &(this->pegB), &(this->pegC) );
+}
+
+int towers_verify( struct Towers* this )
+{
+  struct Node* ptr;
+  int numDiscs = 0;
+
+  if ( list_getSize(&this->pegA) != 0 ) {
+#if HOST_DEBUG
+    printf( "ERROR: Peg A is not empty!\n" );
+#endif
+    return 2;
+  }
+
+  if ( list_getSize(&this->pegB) != 0 ) {
+#if HOST_DEBUG
+    printf( "ERROR: Peg B is not empty!\n" );
+#endif
+    return 3;
+  }
+
+  if ( list_getSize(&this->pegC) != this->numDiscs ) {
+#if HOST_DEBUG
+    printf( " ERROR: Expected %d discs but found only %d discs!\n", \
+            this->numDiscs, list_getSize(&this->pegC) );
+#endif
+    return 4;
+  }
+
+  for ( ptr = this->pegC.head; ptr != 0; ptr = ptr->next ) {
+    numDiscs++;
+    if ( ptr->val != numDiscs ) {
+#if HOST_DEBUG
+      printf( " ERROR: Expecting disc %d on peg C but found disc %d instead!\n", \
+              numDiscs, ptr->val );
+#endif
+      return 5;
+    }
+  }
+
+  if ( this->numMoves != ((1 << this->numDiscs) - 1) ) {
+#if HOST_DEBUG
+    printf( " ERROR: Expecting %d num moves but found %d instead!\n", \
+            ((1 << this->numDiscs) - 1), this->numMoves );
+#endif
+    return 6;
+  }
+
+  return 1;
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  struct Towers towers;
+  int i;
+
+  // Initialize free list
+
+  list_init( &g_nodeFreeList );
+  g_nodeFreeList.head = &(g_nodePool[0]);
+  g_nodeFreeList.size = NUM_DISCS;
+  g_nodePool[NUM_DISCS-1].next = 0;
+  g_nodePool[NUM_DISCS-1].val = 99;
+  for ( i = 0; i < (NUM_DISCS-1); i++ ) {
+    g_nodePool[i].next = &(g_nodePool[i+1]);
+    g_nodePool[i].val = i;
+  }
+
+  towers_init( &towers, NUM_DISCS );
+
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+  towers_solve( &towers );
+#endif
+
+  // Solve it
+
+  towers_clear( &towers );
+  setStats(1);
+  towers_solve( &towers );
+  setStats(0);
+
+  // Print out the results
+
+#if HOST_DEBUG
+  towers_print( &towers );
+#endif
+
+  // Check the results
+
+  finishTest( towers_verify( &towers ) );
+
+}
+
diff --git a/benchmarks/vec-cmplxmult/bmark.mk b/benchmarks/vec-cmplxmult/bmark.mk
new file mode 100644 (file)
index 0000000..ae93506
--- /dev/null
@@ -0,0 +1,30 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+vec_cmplxmult_c_src = \
+       vec_cmplxmult_main.c \
+
+vec_cmplxmult_riscv_src = \
+       crt.S \
+       vec_cmplxmult_asm.S
+
+vec_cmplxmult_c_objs     = $(patsubst %.c, %.o, $(vec_cmplxmult_c_src))
+vec_cmplxmult_riscv_objs = $(patsubst %.S, %.o, $(vec_cmplxmult_riscv_src))
+
+vec_cmplxmult_host_bin = vec-cmplxmult.host
+$(vec_cmplxmult_host_bin) : $(vec_cmplxmult_c_src)
+       $(HOST_COMP) $^ -o $(vec_cmplxmult_host_bin)
+
+vec_cmplxmult_riscv_bin = vec-cmplxmult.riscv
+$(vec_cmplxmult_riscv_bin) : $(vec_cmplxmult_c_objs) $(vec_cmplxmult_riscv_objs)
+       $(RISCV_LINK) $(RISCV_LINK_SYSCALL) $(vec_cmplxmult_c_objs) $(vec_cmplxmult_riscv_objs) -o $(vec_cmplxmult_riscv_bin)
+
+junk += $(vec_cmplxmult_c_objs) $(vec_cmplxmult_riscv_objs) \
+        $(vec_cmplxmult_host_bin) $(vec_cmplxmult_riscv_bin)
diff --git a/benchmarks/vec-cmplxmult/cmplxmult_gendata.pl b/benchmarks/vec-cmplxmult/cmplxmult_gendata.pl
new file mode 100755 (executable)
index 0000000..07881b8
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# vvadd_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the vvadd benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: vvadd_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName    = $_[0];
+  my $arrayRefReal = $_[1];
+  my $arrayRefImag = $_[2];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRefReal});
+
+  print "struct Complex ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("{%3.2f, %3.2f}",$arrayRefReal->[$i], $arrayRefImag->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ",\n  ";
+      }
+    }
+
+  print  "\n};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values_real1;
+  my @values_imag1;
+  my @values_real2;
+  my @values_imag2;
+  my @product_real;
+  my @product_imag;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    my $value_real1 = (rand(9.0));
+    my $value_imag1 = (rand(9.0));
+    my $value_real2 = (rand(9.0));
+    my $value_imag2 = (rand(9.0));
+    push( @values_real1, $value_real1 );
+    push( @values_imag1, $value_imag1 );
+    push( @values_real2, $value_real2 );
+    push( @values_imag2, $value_imag2 );
+    push( @product_real, ($value_real1 * $value_real2) - ($value_imag1 * $value_imag2));
+    push( @product_imag, ($value_imag1 * $value_real2) + ($value_real1 * $value_imag2));
+  }
+
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input1_data", \@values_real1, \@values_imag1 );
+  printArray( "input2_data", \@values_real2, \@values_imag2 );
+  printArray( "verify_data", \@product_real, \@product_imag );
+
+}
+
+main();
+
diff --git a/benchmarks/vec-cmplxmult/dataset.h b/benchmarks/vec-cmplxmult/dataset.h
new file mode 100644 (file)
index 0000000..1e6fa13
--- /dev/null
@@ -0,0 +1,1551 @@
+
+#define DATA_SIZE 512 
+
+struct Complex input1_data[DATA_SIZE] = 
+{
+  {0.37, 4.09},
+  {5.09, 0.02},
+  {6.75, 3.30},
+  {1.19, 0.58},
+  {5.26, 1.95},
+  {5.60, 1.90},
+  {8.39, 3.06},
+  {3.54, 8.09},
+  {8.66, 0.11},
+  {1.05, 6.76},
+  {3.84, 4.51},
+  {5.94, 6.32},
+  {2.88, 8.84},
+  {7.88, 6.27},
+  {4.27, 2.45},
+  {4.86, 5.83},
+  {1.83, 0.80},
+  {6.84, 6.04},
+  {4.61, 4.97},
+  {1.76, 5.34},
+  {2.41, 8.58},
+  {3.04, 5.26},
+  {8.13, 3.32},
+  {8.23, 2.96},
+  {8.41, 5.34},
+  {1.77, 4.90},
+  {5.11, 8.82},
+  {5.85, 7.34},
+  {1.63, 1.88},
+  {7.74, 5.67},
+  {2.60, 6.35},
+  {1.28, 2.28},
+  {7.98, 3.87},
+  {5.20, 4.85},
+  {6.86, 0.04},
+  {4.31, 0.90},
+  {3.63, 6.25},
+  {4.00, 2.67},
+  {6.09, 5.59},
+  {2.02, 3.17},
+  {2.60, 5.83},
+  {5.54, 4.75},
+  {3.51, 7.17},
+  {4.10, 6.49},
+  {3.31, 6.72},
+  {5.26, 8.91},
+  {8.88, 7.69},
+  {3.12, 4.79},
+  {5.04, 4.15},
+  {6.99, 3.23},
+  {7.02, 6.17},
+  {1.29, 4.02},
+  {1.13, 6.70},
+  {8.41, 4.32},
+  {4.98, 8.34},
+  {5.85, 3.22},
+  {2.59, 6.00},
+  {0.45, 5.03},
+  {0.86, 7.69},
+  {5.29, 0.55},
+  {3.44, 3.57},
+  {7.28, 0.16},
+  {7.38, 2.62},
+  {4.06, 4.83},
+  {8.70, 8.26},
+  {7.29, 8.86},
+  {4.84, 0.49},
+  {6.32, 8.57},
+  {5.12, 1.36},
+  {0.20, 5.78},
+  {6.00, 6.58},
+  {3.91, 6.56},
+  {0.02, 3.56},
+  {2.23, 8.21},
+  {3.92, 7.34},
+  {7.83, 2.39},
+  {3.73, 2.13},
+  {4.94, 1.63},
+  {8.00, 4.54},
+  {2.57, 1.56},
+  {4.50, 3.13},
+  {8.08, 0.62},
+  {6.59, 5.93},
+  {2.26, 1.10},
+  {5.01, 7.47},
+  {4.76, 3.91},
+  {2.90, 6.79},
+  {2.59, 5.65},
+  {2.75, 0.10},
+  {6.61, 0.95},
+  {3.30, 7.37},
+  {2.65, 3.66},
+  {5.89, 7.72},
+  {0.82, 0.54},
+  {0.95, 6.02},
+  {3.44, 1.09},
+  {7.44, 3.72},
+  {3.22, 0.11},
+  {0.49, 8.70},
+  {8.61, 5.60},
+  {4.81, 8.30},
+  {4.70, 5.83},
+  {5.34, 7.99},
+  {1.56, 0.33},
+  {1.09, 4.96},
+  {6.83, 8.74},
+  {8.57, 3.91},
+  {1.17, 2.73},
+  {7.64, 7.75},
+  {2.30, 4.31},
+  {3.69, 6.08},
+  {3.60, 8.92},
+  {6.79, 4.06},
+  {1.54, 1.40},
+  {6.55, 4.08},
+  {7.01, 4.59},
+  {6.79, 3.84},
+  {1.82, 4.35},
+  {1.39, 3.06},
+  {3.22, 0.46},
+  {8.31, 5.42},
+  {4.47, 8.73},
+  {4.66, 7.93},
+  {2.49, 7.84},
+  {1.03, 5.44},
+  {8.17, 8.00},
+  {2.14, 3.65},
+  {7.07, 6.72},
+  {3.22, 2.48},
+  {7.38, 2.04},
+  {2.52, 8.50},
+  {4.13, 6.39},
+  {6.40, 0.49},
+  {0.38, 0.48},
+  {3.40, 0.37},
+  {6.31, 3.75},
+  {4.33, 1.98},
+  {4.50, 6.94},
+  {0.45, 4.35},
+  {7.87, 6.53},
+  {8.94, 1.68},
+  {6.50, 0.01},
+  {2.10, 2.23},
+  {6.29, 3.27},
+  {3.14, 2.11},
+  {3.16, 0.37},
+  {5.17, 1.76},
+  {6.75, 6.70},
+  {7.42, 3.21},
+  {1.53, 1.27},
+  {6.08, 2.61},
+  {1.82, 2.88},
+  {7.69, 1.07},
+  {3.56, 0.64},
+  {7.70, 3.50},
+  {1.42, 0.32},
+  {6.90, 6.29},
+  {1.76, 6.10},
+  {1.97, 7.96},
+  {1.60, 6.73},
+  {6.30, 4.61},
+  {6.37, 3.97},
+  {0.76, 6.60},
+  {8.05, 6.33},
+  {3.36, 0.78},
+  {0.13, 1.94},
+  {0.75, 5.87},
+  {7.16, 3.87},
+  {5.79, 0.87},
+  {7.52, 5.94},
+  {4.16, 4.72},
+  {5.06, 5.63},
+  {0.09, 6.44},
+  {8.15, 0.50},
+  {3.67, 2.75},
+  {5.04, 8.12},
+  {4.62, 6.23},
+  {2.73, 4.48},
+  {3.85, 8.48},
+  {3.24, 4.33},
+  {6.17, 7.41},
+  {1.67, 6.13},
+  {0.97, 1.01},
+  {3.49, 1.67},
+  {4.38, 6.48},
+  {6.30, 6.75},
+  {6.94, 7.33},
+  {0.73, 2.94},
+  {3.67, 0.31},
+  {0.27, 8.43},
+  {7.84, 0.80},
+  {1.34, 3.06},
+  {1.33, 4.99},
+  {7.61, 8.60},
+  {1.27, 3.57},
+  {7.36, 2.25},
+  {5.07, 7.50},
+  {5.55, 3.55},
+  {7.32, 4.24},
+  {1.44, 3.03},
+  {7.24, 2.25},
+  {4.91, 4.89},
+  {4.13, 5.73},
+  {7.86, 5.24},
+  {7.26, 6.05},
+  {0.94, 3.77},
+  {2.29, 8.29},
+  {1.23, 6.71},
+  {5.27, 1.25},
+  {3.74, 8.36},
+  {6.37, 4.12},
+  {3.41, 1.66},
+  {8.80, 1.77},
+  {8.54, 3.75},
+  {1.49, 8.98},
+  {0.95, 6.63},
+  {7.17, 7.44},
+  {2.74, 0.46},
+  {5.72, 4.84},
+  {1.07, 2.65},
+  {4.79, 0.99},
+  {0.34, 7.04},
+  {6.67, 3.38},
+  {6.91, 8.08},
+  {0.52, 0.40},
+  {7.07, 7.62},
+  {7.54, 0.89},
+  {0.61, 4.00},
+  {8.98, 1.49},
+  {1.55, 0.26},
+  {5.60, 2.92},
+  {7.44, 3.39},
+  {6.25, 8.09},
+  {2.13, 1.52},
+  {6.71, 1.75},
+  {1.12, 8.43},
+  {8.49, 7.04},
+  {3.34, 5.58},
+  {2.43, 8.41},
+  {6.88, 7.45},
+  {8.25, 8.90},
+  {0.01, 5.85},
+  {8.97, 0.01},
+  {5.05, 3.60},
+  {8.76, 7.13},
+  {4.59, 8.87},
+  {8.74, 5.41},
+  {5.22, 6.15},
+  {2.26, 8.14},
+  {1.16, 8.97},
+  {6.45, 5.61},
+  {6.12, 8.07},
+  {2.17, 7.39},
+  {7.15, 2.04},
+  {0.01, 2.37},
+  {8.89, 2.15},
+  {6.80, 5.50},
+  {1.83, 2.15},
+  {1.62, 7.97},
+  {1.49, 0.97},
+  {8.78, 7.11},
+  {5.04, 0.21},
+  {3.81, 8.02},
+  {5.10, 0.48},
+  {4.44, 1.81},
+  {6.72, 3.68},
+  {3.36, 5.82},
+  {5.99, 0.74},
+  {4.81, 0.47},
+  {8.19, 2.02},
+  {0.30, 6.63},
+  {3.30, 1.51},
+  {7.04, 4.79},
+  {6.35, 1.52},
+  {8.53, 0.92},
+  {0.45, 0.39},
+  {4.28, 5.90},
+  {6.12, 5.64},
+  {8.59, 7.41},
+  {4.30, 5.78},
+  {6.43, 2.21},
+  {4.77, 7.90},
+  {0.70, 5.41},
+  {8.18, 6.98},
+  {1.29, 2.11},
+  {2.16, 4.09},
+  {3.29, 1.89},
+  {0.49, 8.12},
+  {3.96, 5.91},
+  {2.84, 5.36},
+  {6.28, 4.19},
+  {6.54, 0.63},
+  {2.55, 0.29},
+  {5.61, 0.23},
+  {8.02, 4.40},
+  {2.62, 3.69},
+  {6.54, 0.25},
+  {4.94, 4.86},
+  {5.81, 2.73},
+  {2.61, 6.62},
+  {1.47, 4.98},
+  {4.43, 0.97},
+  {1.05, 0.44},
+  {7.74, 1.30},
+  {2.55, 6.53},
+  {8.23, 4.24},
+  {1.76, 3.09},
+  {7.05, 6.10},
+  {6.56, 3.03},
+  {3.88, 4.19},
+  {6.85, 5.32},
+  {2.79, 3.66},
+  {3.19, 6.72},
+  {6.30, 4.73},
+  {4.39, 2.31},
+  {0.91, 4.92},
+  {2.42, 3.31},
+  {0.68, 0.96},
+  {8.90, 3.57},
+  {8.19, 3.87},
+  {0.83, 1.18},
+  {2.50, 8.93},
+  {3.17, 8.93},
+  {7.78, 4.05},
+  {0.91, 5.55},
+  {5.12, 6.37},
+  {3.34, 7.63},
+  {4.16, 2.85},
+  {1.64, 6.72},
+  {1.44, 4.71},
+  {0.20, 1.04},
+  {5.81, 2.04},
+  {7.02, 1.80},
+  {7.71, 6.69},
+  {8.86, 6.35},
+  {5.09, 7.07},
+  {2.28, 8.67},
+  {1.39, 2.65},
+  {2.29, 1.30},
+  {8.10, 7.17},
+  {2.94, 6.11},
+  {2.78, 7.15},
+  {1.44, 5.74},
+  {7.56, 2.18},
+  {4.96, 6.24},
+  {0.74, 5.42},
+  {2.92, 3.59},
+  {0.93, 0.66},
+  {8.71, 8.81},
+  {1.60, 5.03},
+  {3.36, 4.56},
+  {5.40, 5.87},
+  {3.40, 2.89},
+  {5.33, 3.61},
+  {3.97, 7.61},
+  {5.35, 8.41},
+  {8.18, 4.04},
+  {3.40, 0.46},
+  {7.04, 8.11},
+  {4.47, 6.74},
+  {7.27, 0.06},
+  {4.94, 2.57},
+  {0.27, 4.06},
+  {5.68, 6.95},
+  {5.53, 4.82},
+  {1.05, 4.34},
+  {8.15, 3.91},
+  {5.47, 0.38},
+  {1.53, 7.80},
+  {4.57, 3.74},
+  {3.89, 4.86},
+  {1.33, 0.95},
+  {1.01, 5.36},
+  {7.52, 3.15},
+  {8.55, 2.59},
+  {4.40, 1.39},
+  {7.19, 4.86},
+  {6.93, 7.86},
+  {4.37, 5.88},
+  {6.50, 6.74},
+  {7.40, 3.07},
+  {0.00, 1.86},
+  {2.50, 4.56},
+  {6.13, 8.66},
+  {5.00, 5.65},
+  {4.66, 8.75},
+  {4.56, 3.70},
+  {2.22, 0.57},
+  {3.55, 3.57},
+  {1.93, 5.58},
+  {4.73, 5.02},
+  {1.56, 0.61},
+  {5.59, 4.62},
+  {4.82, 0.06},
+  {1.44, 7.95},
+  {7.30, 6.89},
+  {0.68, 4.56},
+  {1.51, 7.49},
+  {7.69, 5.75},
+  {2.92, 0.66},
+  {0.47, 0.54},
+  {0.10, 8.37},
+  {6.58, 8.66},
+  {2.59, 7.19},
+  {0.83, 7.69},
+  {8.22, 5.41},
+  {7.75, 2.10},
+  {6.71, 1.62},
+  {5.54, 6.22},
+  {8.24, 4.46},
+  {2.60, 2.11},
+  {1.16, 7.03},
+  {4.95, 0.20},
+  {8.84, 6.68},
+  {5.61, 3.86},
+  {5.64, 5.44},
+  {3.48, 3.11},
+  {4.26, 2.86},
+  {2.16, 7.76},
+  {7.79, 4.61},
+  {3.21, 0.63},
+  {7.44, 7.69},
+  {3.52, 4.42},
+  {0.35, 2.73},
+  {5.56, 7.33},
+  {1.86, 3.50},
+  {7.06, 8.72},
+  {7.34, 0.44},
+  {6.00, 2.27},
+  {0.85, 6.68},
+  {3.80, 1.59},
+  {6.08, 4.72},
+  {3.37, 8.58},
+  {0.58, 4.79},
+  {6.83, 0.21},
+  {4.51, 7.63},
+  {3.03, 7.70},
+  {2.14, 0.22},
+  {4.22, 2.87},
+  {5.09, 5.97},
+  {4.05, 2.53},
+  {1.23, 2.65},
+  {3.45, 6.61},
+  {2.42, 4.24},
+  {8.18, 6.07},
+  {8.58, 3.96},
+  {3.58, 1.40},
+  {2.09, 8.55},
+  {0.32, 4.01},
+  {3.99, 7.07},
+  {3.50, 8.50},
+  {5.60, 3.30},
+  {5.52, 5.45},
+  {8.59, 3.07},
+  {4.16, 8.21},
+  {7.32, 3.92},
+  {6.06, 0.71},
+  {2.82, 8.56},
+  {0.50, 0.24},
+  {6.79, 1.81},
+  {7.92, 7.91},
+  {5.16, 7.92},
+  {6.50, 1.29},
+  {5.80, 7.32},
+  {8.72, 4.75},
+  {7.57, 7.18},
+  {5.68, 2.65},
+  {7.16, 2.49},
+  {7.98, 3.72},
+  {6.28, 3.48},
+  {0.84, 2.91},
+  {7.07, 4.85},
+  {5.24, 8.65},
+  {8.32, 0.44},
+  {5.88, 8.09},
+  {2.36, 4.46},
+  {5.49, 7.25},
+  {4.86, 3.89},
+  {5.05, 1.73},
+  {0.18, 7.01},
+  {8.80, 3.24},
+  {3.48, 6.73},
+  {5.98, 6.75},
+  {1.91, 3.68},
+  {8.17, 3.98},
+  {6.64, 0.88},
+  {0.23, 3.24},
+  {7.19, 6.06},
+  {4.07, 7.93},
+  {6.16, 2.71},
+  {7.35, 8.32},
+  {5.52, 7.36},
+  {1.05, 2.20},
+  {2.54, 8.26},
+  {2.61, 5.89},
+  {5.81, 3.66},
+  {8.40, 0.98},
+  {6.17, 4.18},
+  {7.89, 0.78},
+  {3.71, 4.02},
+  {5.98, 4.86},
+  {7.06, 0.26},
+  {6.38, 6.63},
+  {4.72, 5.50},
+  {0.34, 6.06},
+  {0.39, 6.90},
+  {1.12, 3.69},
+  {7.34, 1.68},
+  {1.93, 5.12},
+  {5.16, 8.99},
+  {8.62, 4.11},
+  {5.87, 5.10}
+};
+
+struct Complex input2_data[DATA_SIZE] = 
+{
+  {7.51, 3.02},
+  {1.69, 8.91},
+  {3.16, 5.16},
+  {8.56, 1.38},
+  {7.26, 1.26},
+  {0.06, 5.16},
+  {8.02, 5.34},
+  {6.25, 2.06},
+  {1.00, 7.96},
+  {2.67, 5.82},
+  {2.83, 3.93},
+  {6.97, 7.32},
+  {6.12, 1.36},
+  {3.40, 5.08},
+  {8.45, 2.33},
+  {5.13, 4.59},
+  {2.53, 6.34},
+  {5.46, 3.38},
+  {5.93, 8.44},
+  {0.74, 5.13},
+  {2.06, 7.22},
+  {8.51, 5.79},
+  {2.18, 4.41},
+  {7.45, 2.82},
+  {8.88, 3.50},
+  {8.65, 5.85},
+  {3.16, 8.99},
+  {5.92, 0.71},
+  {1.01, 8.99},
+  {0.59, 7.63},
+  {3.15, 8.98},
+  {8.16, 6.45},
+  {2.38, 3.74},
+  {8.83, 6.31},
+  {2.17, 4.46},
+  {4.50, 7.79},
+  {2.00, 3.75},
+  {6.50, 2.58},
+  {2.86, 0.71},
+  {8.45, 4.87},
+  {1.08, 1.53},
+  {5.46, 2.61},
+  {3.16, 7.22},
+  {2.51, 6.84},
+  {3.23, 0.83},
+  {0.57, 2.44},
+  {3.63, 7.10},
+  {4.66, 2.01},
+  {8.18, 2.18},
+  {2.30, 2.99},
+  {5.39, 6.67},
+  {0.31, 2.81},
+  {8.48, 5.02},
+  {7.20, 5.02},
+  {3.89, 7.17},
+  {8.58, 8.03},
+  {0.18, 4.64},
+  {0.78, 7.84},
+  {3.98, 3.97},
+  {5.54, 6.12},
+  {2.53, 0.09},
+  {8.75, 1.54},
+  {3.11, 3.43},
+  {4.62, 1.67},
+  {3.13, 4.86},
+  {7.95, 8.00},
+  {8.53, 5.52},
+  {3.21, 4.32},
+  {8.03, 0.07},
+  {5.12, 3.02},
+  {3.81, 0.86},
+  {1.43, 2.53},
+  {0.76, 6.20},
+  {0.45, 4.30},
+  {7.14, 6.57},
+  {4.38, 1.15},
+  {3.33, 1.93},
+  {4.67, 0.06},
+  {6.15, 5.37},
+  {2.38, 5.80},
+  {2.62, 5.40},
+  {1.94, 7.66},
+  {6.20, 5.58},
+  {7.08, 1.19},
+  {2.72, 6.01},
+  {4.91, 4.40},
+  {8.54, 1.13},
+  {7.42, 0.13},
+  {7.11, 3.64},
+  {8.65, 6.34},
+  {6.51, 8.69},
+  {8.79, 7.88},
+  {6.75, 0.78},
+  {3.41, 5.95},
+  {0.93, 1.38},
+  {5.87, 0.88},
+  {7.57, 2.13},
+  {1.34, 3.82},
+  {1.26, 1.95},
+  {3.09, 3.26},
+  {6.82, 6.44},
+  {7.55, 2.70},
+  {0.12, 6.15},
+  {0.57, 4.45},
+  {1.20, 4.84},
+  {3.35, 5.79},
+  {0.36, 3.74},
+  {1.00, 3.95},
+  {3.94, 1.83},
+  {2.43, 8.90},
+  {5.66, 6.48},
+  {4.95, 3.05},
+  {5.08, 5.70},
+  {0.17, 5.83},
+  {4.52, 3.85},
+  {0.39, 8.91},
+  {0.73, 0.11},
+  {7.69, 1.28},
+  {6.85, 3.52},
+  {8.50, 1.54},
+  {2.96, 0.95},
+  {3.99, 1.09},
+  {5.78, 0.74},
+  {7.08, 5.41},
+  {7.59, 7.85},
+  {2.48, 5.50},
+  {0.30, 2.11},
+  {5.09, 4.74},
+  {7.24, 3.98},
+  {6.77, 6.78},
+  {0.77, 6.54},
+  {4.10, 1.81},
+  {4.14, 6.83},
+  {2.28, 3.58},
+  {4.58, 1.27},
+  {7.75, 6.74},
+  {6.68, 4.31},
+  {6.39, 1.62},
+  {3.35, 6.23},
+  {8.52, 1.56},
+  {4.75, 8.24},
+  {3.92, 8.68},
+  {4.48, 4.19},
+  {0.28, 4.70},
+  {2.26, 1.09},
+  {2.26, 7.02},
+  {7.06, 1.45},
+  {4.53, 3.96},
+  {7.45, 3.63},
+  {1.45, 5.70},
+  {0.29, 7.05},
+  {1.29, 5.73},
+  {0.81, 7.68},
+  {0.97, 7.35},
+  {0.96, 8.60},
+  {0.05, 0.15},
+  {1.84, 6.27},
+  {5.18, 5.39},
+  {4.74, 7.43},
+  {2.16, 4.17},
+  {6.82, 4.81},
+  {0.45, 3.86},
+  {7.21, 6.55},
+  {4.62, 4.93},
+  {4.44, 7.20},
+  {5.60, 0.20},
+  {0.93, 0.54},
+  {8.30, 5.93},
+  {7.93, 8.77},
+  {2.16, 8.70},
+  {1.03, 0.56},
+  {4.77, 2.73},
+  {8.98, 3.69},
+  {3.49, 6.57},
+  {0.95, 3.93},
+  {8.44, 5.34},
+  {3.69, 7.18},
+  {1.82, 1.60},
+  {5.53, 8.97},
+  {4.70, 1.43},
+  {0.20, 5.51},
+  {2.82, 0.13},
+  {2.48, 7.18},
+  {2.19, 0.00},
+  {0.95, 0.87},
+  {8.10, 6.66},
+  {5.81, 3.92},
+  {1.46, 0.34},
+  {8.52, 5.46},
+  {6.92, 0.24},
+  {1.03, 3.98},
+  {0.56, 3.10},
+  {7.55, 3.29},
+  {3.90, 5.76},
+  {1.90, 8.93},
+  {7.40, 3.05},
+  {3.28, 8.78},
+  {4.47, 2.40},
+  {8.26, 3.14},
+  {3.88, 3.78},
+  {1.62, 1.95},
+  {7.57, 8.14},
+  {7.09, 6.58},
+  {7.17, 7.39},
+  {6.83, 8.82},
+  {3.62, 6.04},
+  {8.87, 5.12},
+  {6.57, 5.97},
+  {7.16, 3.48},
+  {4.76, 1.56},
+  {4.99, 2.85},
+  {6.91, 4.30},
+  {2.13, 3.60},
+  {2.07, 7.26},
+  {4.56, 2.43},
+  {6.35, 6.28},
+  {1.26, 4.76},
+  {7.17, 5.62},
+  {5.05, 0.79},
+  {0.08, 7.82},
+  {7.33, 3.59},
+  {5.27, 5.83},
+  {5.58, 8.50},
+  {4.31, 5.31},
+  {8.64, 2.60},
+  {8.88, 6.69},
+  {2.77, 4.71},
+  {7.43, 3.89},
+  {6.75, 8.39},
+  {7.44, 4.16},
+  {1.40, 2.46},
+  {0.39, 3.07},
+  {0.73, 1.43},
+  {6.74, 4.00},
+  {2.40, 5.69},
+  {6.59, 2.47},
+  {3.83, 1.67},
+  {2.89, 2.63},
+  {4.89, 1.41},
+  {6.78, 0.80},
+  {0.13, 5.67},
+  {8.16, 0.29},
+  {7.30, 6.71},
+  {7.87, 8.25},
+  {2.61, 5.00},
+  {5.03, 4.78},
+  {3.65, 3.62},
+  {2.64, 4.87},
+  {7.66, 1.09},
+  {4.08, 4.70},
+  {0.78, 2.02},
+  {1.64, 4.78},
+  {3.03, 5.87},
+  {5.78, 0.87},
+  {2.88, 5.13},
+  {5.83, 1.14},
+  {8.64, 1.73},
+  {1.28, 7.18},
+  {2.70, 5.16},
+  {6.86, 1.27},
+  {5.83, 7.68},
+  {5.58, 6.35},
+  {2.35, 4.33},
+  {4.88, 3.36},
+  {8.93, 4.92},
+  {1.87, 1.08},
+  {8.40, 4.19},
+  {0.31, 2.64},
+  {4.31, 7.93},
+  {1.83, 6.71},
+  {1.93, 7.98},
+  {8.04, 0.02},
+  {6.13, 2.90},
+  {6.20, 4.38},
+  {3.48, 1.60},
+  {0.91, 6.38},
+  {3.60, 8.25},
+  {2.97, 2.18},
+  {4.25, 7.17},
+  {6.54, 2.27},
+  {8.45, 1.36},
+  {7.84, 3.00},
+  {4.91, 8.46},
+  {7.69, 3.58},
+  {8.82, 6.81},
+  {0.95, 3.82},
+  {0.89, 8.67},
+  {0.88, 8.32},
+  {6.89, 4.77},
+  {3.03, 0.82},
+  {6.98, 6.18},
+  {2.92, 6.80},
+  {4.83, 4.46},
+  {5.36, 3.51},
+  {0.68, 0.34},
+  {4.47, 5.76},
+  {4.05, 8.57},
+  {1.22, 0.73},
+  {7.55, 6.52},
+  {6.91, 1.13},
+  {3.75, 2.24},
+  {8.88, 3.26},
+  {5.57, 7.83},
+  {2.12, 7.58},
+  {5.15, 3.02},
+  {5.05, 2.37},
+  {2.18, 7.29},
+  {8.88, 3.06},
+  {3.10, 3.70},
+  {5.52, 0.51},
+  {1.59, 4.38},
+  {3.01, 8.95},
+  {2.79, 2.15},
+  {0.42, 3.03},
+  {4.54, 1.21},
+  {3.54, 6.51},
+  {2.83, 8.50},
+  {3.12, 5.67},
+  {5.41, 1.88},
+  {3.47, 4.72},
+  {4.91, 3.21},
+  {6.02, 6.07},
+  {7.69, 6.49},
+  {2.82, 0.77},
+  {4.80, 1.90},
+  {7.53, 6.64},
+  {8.92, 4.08},
+  {8.22, 8.78},
+  {2.42, 7.18},
+  {6.95, 5.57},
+  {7.70, 6.55},
+  {0.16, 1.49},
+  {8.21, 7.48},
+  {1.24, 1.69},
+  {6.46, 6.05},
+  {6.48, 7.98},
+  {7.08, 5.93},
+  {1.77, 5.59},
+  {4.03, 1.56},
+  {0.05, 0.65},
+  {5.55, 0.72},
+  {1.58, 6.17},
+  {1.11, 8.72},
+  {6.45, 8.09},
+  {2.07, 3.36},
+  {5.65, 6.50},
+  {8.35, 4.98},
+  {0.16, 1.58},
+  {1.43, 2.93},
+  {5.35, 1.67},
+  {3.55, 7.75},
+  {6.72, 5.17},
+  {7.80, 3.15},
+  {4.98, 8.02},
+  {3.12, 7.97},
+  {2.62, 8.84},
+  {4.91, 8.91},
+  {4.11, 2.99},
+  {0.99, 6.46},
+  {8.07, 4.00},
+  {6.31, 3.55},
+  {3.07, 6.34},
+  {7.48, 5.88},
+  {4.92, 4.37},
+  {8.76, 5.04},
+  {2.83, 4.57},
+  {8.75, 3.10},
+  {7.16, 7.07},
+  {8.08, 3.80},
+  {8.26, 7.85},
+  {3.06, 1.46},
+  {2.03, 4.34},
+  {5.23, 1.04},
+  {1.21, 8.69},
+  {1.82, 2.10},
+  {3.57, 5.43},
+  {4.31, 8.50},
+  {5.17, 1.09},
+  {3.06, 7.31},
+  {4.06, 3.26},
+  {6.71, 8.20},
+  {5.36, 5.16},
+  {1.08, 8.77},
+  {6.82, 3.20},
+  {7.64, 7.66},
+  {3.42, 8.21},
+  {8.15, 6.94},
+  {2.19, 7.88},
+  {3.88, 4.35},
+  {2.20, 5.82},
+  {3.60, 2.96},
+  {2.75, 7.97},
+  {5.36, 8.76},
+  {6.30, 4.62},
+  {6.76, 5.07},
+  {4.10, 3.30},
+  {0.84, 7.09},
+  {0.15, 3.45},
+  {4.46, 4.08},
+  {0.71, 0.76},
+  {1.01, 8.40},
+  {3.09, 8.33},
+  {6.13, 0.62},
+  {8.66, 8.88},
+  {5.64, 7.97},
+  {5.55, 3.51},
+  {6.70, 7.15},
+  {4.31, 6.97},
+  {4.58, 6.99},
+  {7.30, 1.26},
+  {8.78, 3.89},
+  {5.23, 3.35},
+  {7.82, 5.89},
+  {2.43, 7.35},
+  {5.88, 1.26},
+  {8.92, 2.84},
+  {2.92, 8.01},
+  {1.48, 2.34},
+  {1.71, 3.40},
+  {2.09, 2.74},
+  {1.38, 0.32},
+  {2.96, 5.20},
+  {7.64, 2.94},
+  {3.63, 3.88},
+  {4.92, 6.39},
+  {0.02, 8.67},
+  {8.02, 3.99},
+  {7.50, 7.49},
+  {3.70, 2.90},
+  {2.22, 1.62},
+  {1.91, 1.05},
+  {0.09, 6.89},
+  {3.85, 6.35},
+  {0.48, 7.25},
+  {7.31, 5.51},
+  {3.95, 3.38},
+  {2.96, 8.75},
+  {3.75, 5.76},
+  {6.17, 6.52},
+  {2.75, 5.83},
+  {5.39, 1.43},
+  {7.95, 7.98},
+  {8.45, 7.81},
+  {1.04, 2.67},
+  {0.45, 4.26},
+  {3.30, 0.05},
+  {2.32, 4.57},
+  {6.01, 5.41},
+  {8.93, 2.00},
+  {1.93, 3.15},
+  {0.12, 1.35},
+  {0.48, 4.00},
+  {8.42, 6.49},
+  {7.47, 8.76},
+  {5.60, 2.90},
+  {4.71, 0.45},
+  {0.52, 6.86},
+  {3.18, 2.15},
+  {8.76, 2.04},
+  {3.75, 1.59},
+  {7.79, 4.06},
+  {1.47, 0.90},
+  {0.11, 0.29},
+  {4.57, 6.95},
+  {7.04, 4.40},
+  {2.18, 1.75},
+  {7.30, 8.71},
+  {3.93, 3.11},
+  {5.40, 1.78},
+  {5.80, 1.05},
+  {6.40, 6.13},
+  {1.01, 4.99},
+  {0.12, 7.88},
+  {5.55, 4.57},
+  {3.24, 4.86},
+  {2.10, 6.88},
+  {6.18, 2.58},
+  {1.06, 7.54},
+  {6.66, 7.44},
+  {2.86, 5.28},
+  {5.17, 3.18},
+  {6.96, 0.10},
+  {4.55, 0.05},
+  {8.01, 5.80},
+  {3.79, 3.32},
+  {4.65, 1.53},
+  {1.98, 4.75},
+  {6.46, 0.63},
+  {6.23, 2.69},
+  {4.14, 2.95},
+  {2.92, 7.47},
+  {2.23, 4.48},
+  {3.18, 8.84},
+  {6.66, 6.43},
+  {8.20, 4.54},
+  {5.64, 4.90},
+  {1.98, 2.74},
+  {3.36, 8.60},
+  {5.83, 7.23},
+  {8.61, 0.25},
+  {7.66, 5.90},
+  {3.54, 4.24},
+  {3.80, 8.48},
+  {6.15, 4.07},
+  {1.41, 2.14},
+  {6.92, 6.43},
+  {4.95, 7.83},
+  {2.26, 4.29},
+  {1.91, 0.40},
+  {8.10, 1.26},
+  {5.49, 4.23},
+  {3.92, 3.68}
+};
+
+struct Complex verify_data[DATA_SIZE] = 
+{
+  {-9.55, 31.87},
+  {8.45, 45.39},
+  {4.34, 45.27},
+  {9.41, 6.59},
+  {35.73, 20.80},
+  {-9.46, 29.00},
+  {50.95, 69.43},
+  {5.47, 57.90},
+  {7.79, 69.03},
+  {-36.53, 24.18},
+  {-6.85, 27.86},
+  {-4.86, 87.57},
+  {5.59, 57.99},
+  {-5.10, 61.38},
+  {30.42, 30.70},
+  {-1.81, 52.19},
+  {-0.43, 13.62},
+  {16.97, 56.10},
+  {-14.63, 68.37},
+  {-26.08, 12.95},
+  {-56.93, 35.07},
+  {-4.61, 62.42},
+  {3.10, 43.03},
+  {52.89, 45.25},
+  {55.98, 76.85},
+  {-13.41, 52.73},
+  {-63.15, 73.78},
+  {29.38, 47.60},
+  {-15.25, 16.57},
+  {-38.76, 62.42},
+  {-48.83, 43.31},
+  {-4.32, 26.85},
+  {4.49, 39.11},
+  {15.24, 75.60},
+  {14.71, 30.66},
+  {12.39, 37.66},
+  {-16.19, 26.14},
+  {19.10, 27.68},
+  {13.49, 20.33},
+  {1.62, 36.60},
+  {-6.13, 10.25},
+  {17.87, 40.40},
+  {-40.70, 48.05},
+  {-34.10, 44.30},
+  {5.13, 24.45},
+  {-18.80, 17.91},
+  {-22.36, 91.00},
+  {4.95, 28.61},
+  {32.18, 44.95},
+  {6.40, 28.33},
+  {-3.28, 80.04},
+  {-10.91, 4.86},
+  {-24.07, 62.47},
+  {38.92, 73.33},
+  {-40.44, 68.15},
+  {24.28, 74.58},
+  {-27.37, 13.08},
+  {-39.05, 7.43},
+  {-27.07, 33.97},
+  {25.94, 35.40},
+  {8.40, 9.34},
+  {63.51, 12.56},
+  {13.94, 33.44},
+  {10.67, 29.11},
+  {-12.93, 68.17},
+  {-12.91, 128.67},
+  {38.58, 30.92},
+  {-16.80, 54.81},
+  {41.01, 11.31},
+  {-16.46, 30.20},
+  {17.23, 30.21},
+  {-10.98, 19.28},
+  {-22.07, 2.83},
+  {-34.27, 13.24},
+  {-20.25, 78.23},
+  {31.56, 19.48},
+  {8.30, 14.29},
+  {22.98, 7.89},
+  {24.83, 70.87},
+  {-2.96, 18.61},
+  {-5.10, 32.50},
+  {10.92, 63.09},
+  {7.76, 73.56},
+  {14.73, 10.45},
+  {-31.23, 50.42},
+  {6.18, 40.10},
+  {17.09, 61.26},
+  {18.50, 42.26},
+  {19.17, 10.67},
+  {51.10, 50.14},
+  {-42.52, 76.67},
+  {-5.54, 53.06},
+  {33.70, 56.65},
+  {-0.44, 6.76},
+  {-7.42, 6.89},
+  {19.24, 9.46},
+  {48.41, 43.99},
+  {3.87, 12.42},
+  {-16.32, 11.94},
+  {8.37, 45.34},
+  {-20.69, 87.66},
+  {19.71, 56.72},
+  {-48.50, 33.76},
+  {-0.57, 7.13},
+  {-22.71, 11.26},
+  {-27.73, 68.86},
+  {-11.59, 33.48},
+  {-9.62, 7.36},
+  {15.89, 44.50},
+  {-32.81, 30.96},
+  {-18.53, 58.34},
+  {-9.41, 55.15},
+  {11.33, 59.36},
+  {-7.88, 9.24},
+  {13.91, 43.66},
+  {-38.15, 64.22},
+  {4.54, 3.59},
+  {8.44, 35.80},
+  {-1.29, 25.84},
+  {26.64, 8.86},
+  {19.44, 23.93},
+  {8.31, 39.70},
+  {21.07, 49.26},
+  {-24.77, 69.02},
+  {-34.89, 49.32},
+  {-23.70, 64.79},
+  {-7.06, 5.59},
+  {4.13, 67.73},
+  {13.44, 30.78},
+  {36.07, 63.89},
+  {-53.67, 23.06},
+  {5.35, 33.70},
+  {23.17, 45.78},
+  {-0.85, 2.44},
+  {15.12, 6.04},
+  {23.63, 71.56},
+  {20.37, 31.88},
+  {17.50, 51.67},
+  {-25.60, 17.35},
+  {56.86, 67.97},
+  {28.63, 81.59},
+  {25.38, 56.49},
+  {0.05, 18.79},
+  {-13.60, 30.47},
+  {4.80, 8.17},
+  {4.55, 23.00},
+  {33.94, 19.94},
+  {4.04, 57.01},
+  {43.61, 50.83},
+  {-5.06, 10.59},
+  {-16.60, 43.62},
+  {-14.17, 14.19},
+  {-1.97, 59.94},
+  {-1.25, 26.76},
+  {-22.66, 69.63},
+  {0.03, 0.23},
+  {-26.76, 54.82},
+  {-23.82, 41.05},
+  {-49.83, 52.38},
+  {-24.58, 21.18},
+  {20.76, 61.75},
+  {-12.48, 26.36},
+  {-37.73, 52.56},
+  {6.00, 68.90},
+  {9.32, 27.67},
+  {0.36, 10.88},
+  {-2.45, 5.87},
+  {36.49, 74.56},
+  {38.31, 57.71},
+  {-35.46, 78.25},
+  {1.62, 7.20},
+  {8.75, 40.70},
+  {-22.91, 58.17},
+  {25.14, 55.26},
+  {-7.33, 17.05},
+  {-0.86, 95.47},
+  {-27.65, 56.11},
+  {-2.21, 12.53},
+  {-54.69, 81.45},
+  {9.02, 24.97},
+  {-39.56, 35.42},
+  {3.90, 17.48},
+  {-4.84, 9.43},
+  {7.63, 3.67},
+  {-1.49, 9.99},
+  {6.07, 96.66},
+  {11.55, 69.81},
+  {0.06, 4.54},
+  {29.61, 22.63},
+  {-0.18, 58.41},
+  {4.87, 32.02},
+  {-8.74, 5.88},
+  {-6.42, 42.08},
+  {-19.85, 77.38},
+  {-29.51, 18.18},
+  {47.64, 39.05},
+  {-49.21, 69.14},
+  {16.27, 29.14},
+  {47.13, 57.96},
+  {-5.88, 17.20},
+  {7.39, 17.73},
+  {-2.63, 76.94},
+  {-8.43, 67.80},
+  {17.66, 95.65},
+  {-3.78, 105.43},
+  {-19.35, 19.33},
+  {-22.13, 85.25},
+  {-32.01, 51.45},
+  {33.34, 27.27},
+  {4.76, 45.63},
+  {20.07, 38.73},
+  {16.43, 26.11},
+  {12.41, 35.49},
+  {-9.54, 69.75},
+  {-15.05, 44.52},
+  {-35.58, 48.02},
+  {-26.35, 43.57},
+  {17.04, 18.66},
+  {25.06, 28.94},
+  {-20.65, 8.61},
+  {31.60, 24.50},
+  {-39.23, 39.05},
+  {8.47, 75.50},
+  {-13.14, 71.52},
+  {3.44, 4.81},
+  {11.79, 114.92},
+  {16.71, 37.99},
+  {-11.03, 32.07},
+  {48.07, 85.39},
+  {10.42, 8.37},
+  {0.67, 17.83},
+  {-7.51, 24.17},
+  {-6.98, 14.83},
+  {8.26, 18.75},
+  {6.14, 42.31},
+  {-13.44, 58.32},
+  {20.77, 41.19},
+  {-5.08, 24.90},
+  {0.02, 44.55},
+  {40.65, 56.02},
+  {-49.38, 47.95},
+  {-1.62, 47.74},
+  {65.36, 60.27},
+  {10.12, 69.99},
+  {-12.80, 62.38},
+  {-19.28, 66.58},
+  {12.35, 51.40},
+  {-16.15, 41.69},
+  {8.46, 64.81},
+  {-37.44, 42.07},
+  {-6.31, 17.43},
+  {-28.52, 42.42},
+  {-36.85, 35.12},
+  {39.58, 17.97},
+  {-12.11, 6.90},
+  {49.39, 22.67},
+  {49.25, 59.28},
+  {-13.11, 15.93},
+  {-36.76, 29.92},
+  {9.02, 8.57},
+  {-3.52, 108.92},
+  {26.81, 33.21},
+  {-25.78, 35.35},
+  {23.31, 19.43},
+  {30.72, 38.03},
+  {8.59, 14.15},
+  {3.84, 62.92},
+  {-0.07, 16.04},
+  {16.99, 40.18},
+  {1.44, 58.64},
+  {-52.31, 15.21},
+  {26.47, 12.18},
+  {29.26, 49.76},
+  {32.75, 37.25},
+  {28.24, 16.85},
+  {-2.05, 3.25},
+  {-33.27, 56.51},
+  {5.90, 30.11},
+  {-16.63, 93.02},
+  {14.99, 47.54},
+  {51.31, 27.46},
+  {13.69, 76.22},
+  {-42.35, 32.55},
+  {37.88, 82.98},
+  {-2.92, 27.40},
+  {-13.59, 12.14},
+  {-13.48, 30.24},
+  {-67.06, 11.26},
+  {-0.87, 59.62},
+  {4.24, 18.59},
+  {17.98, 68.03},
+  {14.82, 46.36},
+  {11.00, 12.77},
+  {29.22, 20.92},
+  {3.95, 5.68},
+  {-9.54, 31.57},
+  {24.37, 57.06},
+  {2.50, 9.51},
+  {26.05, 58.50},
+  {10.56, 48.73},
+  {-5.65, 21.94},
+  {36.16, 23.04},
+  {2.42, 10.68},
+  {6.56, 61.46},
+  {-6.60, 41.32},
+  {31.49, 40.93},
+  {-18.71, 19.55},
+  {43.97, 75.72},
+  {9.14, 33.64},
+  {19.30, 25.13},
+  {-12.38, 38.43},
+  {-24.39, 35.99},
+  {-5.55, 25.66},
+  {-11.71, 21.07},
+  {17.12, 15.80},
+  {-28.85, 23.36},
+  {-21.31, 29.96},
+  {-3.33, 6.83},
+  {41.43, 36.06},
+  {10.13, 52.06},
+  {0.30, 8.45},
+  {-39.11, 68.91},
+  {-33.57, 89.22},
+  {18.81, 17.35},
+  {-6.22, 28.36},
+  {-3.80, 82.00},
+  {-1.35, 81.71},
+  {9.18, 59.90},
+  {-44.29, 28.03},
+  {-16.17, 40.76},
+  {-5.22, 9.32},
+  {-2.14, 9.00},
+  {44.18, 67.32},
+  {-1.76, 21.32},
+  {18.82, 94.67},
+  {-23.49, 86.50},
+  {-35.23, 74.91},
+  {-12.32, 12.48},
+  {7.18, 8.81},
+  {-4.30, 5.64},
+  {11.90, 36.04},
+  {-39.71, 28.47},
+  {-48.46, 18.94},
+  {31.11, 75.20},
+  {-10.67, 29.61},
+  {-31.00, 35.43},
+  {6.53, 44.56},
+  {-0.88, 1.57},
+  {-13.32, 38.14},
+  {0.14, 29.57},
+  {-23.39, 42.20},
+  {5.95, 67.32},
+  {17.38, 33.26},
+  {-2.36, 60.71},
+  {-48.30, 55.33},
+  {-60.27, 69.27},
+  {4.13, 92.76},
+  {12.63, 12.06},
+  {-45.40, 53.50},
+  {9.11, 72.28},
+  {45.68, 26.21},
+  {-1.17, 39.19},
+  {-21.89, 31.92},
+  {-2.45, 59.04},
+  {24.16, 70.02},
+  {-16.86, 17.05},
+  {59.15, 59.47},
+  {36.45, 41.38},
+  {-17.30, 68.80},
+  {8.35, 66.77},
+  {4.78, 20.56},
+  {-1.41, 7.70},
+  {-0.27, 29.10},
+  {-18.33, 69.13},
+  {10.10, 22.61},
+  {8.17, 28.85},
+  {-10.28, 82.05},
+  {27.25, 48.21},
+  {-29.61, 49.95},
+  {4.42, 48.59},
+  {24.46, 81.28},
+  {-9.60, 10.00},
+  {-37.27, 26.90},
+  {14.15, 78.71},
+  {-5.04, 81.46},
+  {-55.91, 68.15},
+  {11.48, 61.76},
+  {0.33, 18.74},
+  {-1.75, 29.29},
+  {-28.27, 23.57},
+  {2.14, 32.10},
+  {-0.58, 14.09},
+  {-10.48, 73.71},
+  {30.11, 22.64},
+  {-30.62, 61.05},
+  {7.14, 52.31},
+  {-31.75, 8.68},
+  {-25.60, 6.33},
+  {10.81, 57.00},
+  {1.58, 2.68},
+  {-4.03, 4.49},
+  {-69.40, 26.65},
+  {34.97, 57.23},
+  {-41.39, 85.26},
+  {-56.66, 50.02},
+  {26.67, 58.89},
+  {36.97, 69.48},
+  {17.62, 53.74},
+  {-18.06, 67.20},
+  {54.54, 42.92},
+  {14.62, 28.66},
+  {-17.46, 40.70},
+  {37.49, 30.72},
+  {-27.58, 81.20},
+  {28.17, 29.78},
+  {34.89, 64.55},
+  {-14.73, 36.98},
+  {-0.38, 14.23},
+  {-22.73, 20.62},
+  {3.66, 30.99},
+  {4.21, 1.91},
+  {-17.97, 61.45},
+  {13.89, 44.10},
+  {-9.36, 11.27},
+  {-19.45, 71.53},
+  {-30.31, 16.20},
+  {21.83, 98.07},
+  {51.73, 58.32},
+  {15.61, 25.75},
+  {-8.92, 16.21},
+  {5.57, 7.03},
+  {-31.94, 42.30},
+  {-41.53, 54.41},
+  {-34.46, 6.55},
+  {48.82, 39.18},
+  {-7.99, 45.35},
+  {-58.46, 49.26},
+  {6.76, 13.13},
+  {7.31, 45.21},
+  {-20.81, 46.15},
+  {18.17, 19.43},
+  {-11.37, 30.95},
+  {-22.46, 82.83},
+  {-8.81, 10.85},
+  {-22.15, 37.62},
+  {28.11, 13.51},
+  {1.90, 19.58},
+  {-33.67, 62.66},
+  {-5.18, 36.44},
+  {-14.59, 26.19},
+  {-11.07, 5.77},
+  {-10.54, 23.97},
+  {11.13, 81.69},
+  {37.26, 98.19},
+  {-0.45, 58.06},
+  {32.69, 21.79},
+  {-1.75, 41.90},
+  {-9.42, 33.26},
+  {3.90, 3.16},
+  {22.57, 17.60},
+  {29.61, 93.77},
+  {0.47, 16.32},
+  {0.35, 2.00},
+  {-24.37, 73.72},
+  {40.52, 71.85},
+  {3.95, 28.92},
+  {18.43, 68.77},
+  {20.38, 32.06},
+  {36.49, 34.30},
+  {32.78, 26.76},
+  {-12.45, 23.75},
+  {-17.04, 40.20},
+  {-67.58, 42.30},
+  {44.14, 40.41},
+  {-20.29, 54.82},
+  {-25.76, 25.64},
+  {15.24, 59.03},
+  {-24.18, 40.82},
+  {20.78, 49.10},
+  {-36.53, 21.06},
+  {35.15, 44.67},
+  {23.56, 47.18},
+  {26.83, 31.04},
+  {-6.04, 40.57},
+  {17.77, 42.20},
+  {29.56, 14.24},
+  {-14.93, 7.49},
+  {42.65, 43.61},
+  {4.09, 60.41},
+  {17.54, 29.38},
+  {-40.77, 79.19},
+  {-20.66, 41.15},
+  {-16.10, 16.23},
+  {-36.23, 71.30},
+  {-5.32, 60.14},
+  {14.84, 49.12},
+  {13.98, 25.01},
+  {-15.22, 67.15},
+  {40.35, 61.61},
+  {30.94, 35.53},
+  {17.11, 72.57},
+  {23.87, 30.84},
+  {-31.95, 79.27},
+  {6.63, 52.97},
+  {-12.48, 9.24},
+  {-41.66, 50.25},
+  {-23.34, 27.06},
+  {9.40, 35.27},
+  {1.66, 10.57},
+  {30.45, 79.29},
+  {29.85, 59.03},
+  {4.19, 41.60}
+};
+
diff --git a/benchmarks/vec-cmplxmult/dataset_test.h b/benchmarks/vec-cmplxmult/dataset_test.h
new file mode 100644 (file)
index 0000000..a522516
--- /dev/null
@@ -0,0 +1,27 @@
+
+#define DATA_SIZE 4 
+
+struct Complex input1_data[DATA_SIZE] = 
+{
+  {0.37, 4.09},
+  {5.09, 0.02},
+  {6.75, 3.30},
+  {1.19, 0.58}
+};
+
+struct Complex input2_data[DATA_SIZE] = 
+{
+  {7.51, 3.02},
+  {1.69, 8.91},
+  {3.16, 5.16},
+  {8.56, 1.38}
+};
+
+struct Complex verify_data[DATA_SIZE] = 
+{
+  {-9.55, 31.87},
+  {8.45, 45.39},
+  {4.34, 45.27},
+  {9.41, 6.59}
+};
+
diff --git a/benchmarks/vec-cmplxmult/vec_cmplxmult_asm.S b/benchmarks/vec-cmplxmult/vec_cmplxmult_asm.S
new file mode 100644 (file)
index 0000000..0771965
--- /dev/null
@@ -0,0 +1,146 @@
+#*****************************************************************************
+# cmplxmult function (assembly version)
+#-----------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------
+# Headers and Defines
+#--------------------------------------------------------------------------
+# Here are some defines that make writing assembly code easier.
+
+# I'm using the knowledge that rN will be placed in register a0, rA will be
+# placed into register a1, etc., based on the calling convention for functions.
+
+#define rN      a0
+#define rA      a1
+#define rB      a2
+#define rC      a3
+
+#define rVlen   a6
+#define rStride a7
+
+#define rAI a8
+#define rBI a9
+#define rCI a10
+
+# WARNING: do not write to the s0,...,s9 registers without first saving them to
+# the stack.  
+
+#--------------------------------------------------------------------------
+# void scalar_cmplxmult_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+
+        .text
+        .align 2
+        .globl scalar_cmplxmult_asm
+        .type  scalar_cmplxmult_asm,@function
+
+scalar_cmplxmult_asm:
+
+        # *****   Scalar Example   *****
+
+        blez rN, done    # exit early if n < 0 
+
+loop:
+      # The following code is a naive implementation...
+      # Re-ordering instructions may increase performance, also, 
+      # RISC-V supports instrucitons such as the "fmuladd" and "fmulsub".
+      # fmsub.s fa2,fa4,fa3,ft1
+      # Finally, unrolling and other fun transformations can also provide
+      # performance gains.
+
+        flw  f2, 0(rA)  
+        flw  f3, 4(rA)  
+        flw  f4, 0(rB)  
+        flw  f5, 4(rB)  
+        fmul.s f6, f2, f4
+        fmul.s f7, f3, f5
+        fmul.s f8, f3, f4
+        fmul.s f9, f2, f5
+        fsub.s f10, f6, f7
+        fadd.s f11, f8, f9
+        fsw  f10, 0(rC)  
+        fsw  f11, 4(rC)  
+        addi rN, rN, -1
+        addi rA, rA, 8 
+        addi rB, rB, 8 
+        addi rC, rC, 8 
+        bne  rN, zero, loop
+done:
+        ret
+
+#--------------------------------------------------------------------------
+# void vt_cmplxmult_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+
+        # ***** Vector-Thread Example *****
+
+        .globl vt_cmplxmult_asm
+        .type  vt_cmplxmult_asm,@function
+
+        # HINT: because you are dealing with an array of structures, a regular,
+        # vanilla vector-load/vector-store won't work here!
+
+vt_cmplxmult_asm:
+        
+        blez rN, cpdone  
+        la a4, vtcode
+        li rStride, 8
+
+        vvcfgivl rVlen, rN, 1, 7
+
+stripmineloop:
+
+         # ADD YOUR CODE HERE....
+        vsetvl rVlen, rN   # set the vector length
+                           # rN is the desired (application) vector length
+                           # rVLen is what vector length we were given
+
+        vflstw vf2, rA, rStride       # real number vector load of A
+        addi rAI, rA, 4
+        vflstw vf4, rB, rStride  # real number vector load of B
+        addi rBI, rB, 4
+        vflstw vf3, rAI, rStride #imaginary number vector load of A
+        vflstw vf5, rBI, rStride #imaginary vector number load of B
+
+        vf 0(a4)           # jump to vector-fetch code
+
+        vfsstw vf0, rC, rStride       # real number vector store C
+        addi rCI, rC, 4
+        vfsstw vf1, rCI, rStride # imaginary
+
+        slli a5, rVlen, 3
+        sub rN, rN, rVlen  # book keeping
+        add rA, rA, a5
+        add rB, rB, a5
+        add rC, rC, a5
+        bne rN, zero, stripmineloop
+         # Step 0: set the vector length 
+         # Step 1: perform your vector loads
+         # Step 2: jump to the vector-fetch code to perform the calculation
+         # Step 3: perform the vector store
+         # Step 4: book keeping, update the pointers, etc.
+
+cpdone:    
+        fence.v.l 
+        ret
+
+vtcode:
+        # ADD YOUR VECTOR-ELEMENT CODE HERE ... 
+        fmul.s f0, f2, f4
+        fmsub.s f0, f3, f5, f0
+
+        fmul.s f1, f2, f5
+        fmadd.s f1, f3, f4, f1
+        stop
+        
+        # The C code uses a jalr instruction to call this function
+        # so we can use a jr to return back to where the function
+        # was called.  Also known as "ret", for "return".
+
+        ret
+
diff --git a/benchmarks/vec-cmplxmult/vec_cmplxmult_main.c b/benchmarks/vec-cmplxmult/vec_cmplxmult_main.c
new file mode 100644 (file)
index 0000000..3251ef9
--- /dev/null
@@ -0,0 +1,316 @@
+//**************************************************************************
+// Vector-Thread Complex Multiply benchmark
+//--------------------------------------------------------------------------
+//
+// This benchmark multiplies two complex numbers together.  The input data (and
+// reference data) should be generated using the cmplxmult_gendata.pl perl
+// script and dumped to a file named dataset.h. The riscv-gcc toolchain does
+// not support system calls so printf's can only be used on a host system, not
+// on the riscv-v processor simulator itself. 
+//
+// HOWEVER: printstr() and printhex() are provided, for a primitive form of
+// printing strings and hexadecimal values to stdout.
+
+// Choose which implementation you wish to test... but leave only one on!
+// (only the first one will be executed).
+//#define SCALAR_C
+//#define SCALAR_ASM
+#define VT_ASM
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Host Platform Includes
+
+#if HOST_DEBUG
+   #include <stdio.h>
+   #include <stdlib.h>
+#else
+void printstr(const char*);
+void exit();
+#endif
+
+
+//--------------------------------------------------------------------------
+// Complex Value Structs
+
+struct Complex                                                               
+{                                                                            
+  float real;                                                                
+  float imag;                                                                
+};                                                                           
+
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+//#include "dataset_test.h"
+#include "dataset.h"
+
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+float absolute( float in)
+{
+  if (in > 0)
+    return in;
+  else
+    return -in;
+}
+
+
+// are two floating point numbers "close enough"?
+// this is pretty loose, because Perl is giving me pretty terrible answers
+int close_enough(float a, float b)
+{
+   int close_enough = 1;
+
+   if (  absolute(a) > 1.10*absolute(b) 
+      || absolute(a) < 0.90*absolute(b)
+      || absolute(a) > 1.10*absolute(b)
+      || absolute(a) < 0.90*absolute(b))
+   {
+      if (absolute(absolute(a) - absolute(b)) > 0.1)
+      {
+         close_enough = 0;
+      }
+   }
+
+   return close_enough;
+}
+
+int verify( int n, struct Complex test[], struct Complex correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if (  !close_enough(test[i].real, correct[i].real) 
+       || !close_enough(test[i].imag, correct[i].imag))
+    {
+#if HOST_DEBUG
+      printf("    test[%d] : {%3.2f, %3.2f}\n", i, test[i].real, test[i].imag);
+      printf("    corr[%d] : {%3.2f, %3.2f}\n", i, correct[i].real, correct[i].imag);
+#endif
+      // tell us which index fails + 10
+      // (so that if i==0,i==1 fails, we don't 
+     // think it was a 'not-finished yet' or pass)
+//      return i+10; 
+      return 2;
+    }
+  }
+  return 1;
+}
+
+//#if HOST_DEBUG
+void printComplexArray( char name[], int n, struct Complex arr[] )
+{
+#if HOST_DEBUG
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " {%03.2f,%03.2f} ", arr[i].real, arr[i].imag );
+  printf( "\n" );
+#else
+  int i;
+  printstr( name );
+  for ( i = 0; i < n; i++ ) 
+  {
+    printstr(" {");
+    printhex((int) arr[i].real);
+    printstr(",");
+    printhex((int) arr[i].imag);
+    printstr("}");
+  }
+  printstr( "\n" );
+#endif
+}
+//#endif
+
+void finishTest( int correct, long long num_cycles, long long num_retired )
+{
+   int toHostValue = correct;
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  // we no longer run in -testrun mode, which means we can't use
+  // the tohost register to communicate "test is done" and "test results"
+  // so instead we will communicate through print* functions!
+  if ( correct == 1 )
+  {
+    printstr( "*** PASSED *** (num_cycles = 0x" );
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  else
+  {
+    printstr( "*** FAILED *** (num_cycles = 0x");
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  exit();
+#endif
+}
+
+
+
+// deprecated - cr10/stats-enable register no longer exists
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+long long getCycles()
+{
+   long long cycles = 1337;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdcycle %0" : "=r" (cycles) );
+#endif
+  return cycles;
+}
+          
+long long getInstRetired()
+{
+   long long inst_retired = 1338;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdinstret %0" : "=r" (inst_retired) );
+#endif
+  return inst_retired;
+}
+//--------------------------------------------------------------------------
+// complex multiply function
+
+// scalar C implementation 
+void cmplxmult( int n, struct Complex a[], struct Complex b[], struct Complex c[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) 
+  {
+    c[i].real = (a[i].real * b[i].real) - (a[i].imag * b[i].imag);
+    c[i].imag = (a[i].imag * b[i].real) + (a[i].real * b[i].imag);
+  }
+}
+
+// assembly implementations can be found in *_asm.S
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  struct Complex results_data[DATA_SIZE];
+  long long start_cycles = 0;
+  long long stop_cycles = 0;
+  long long num_cycles; 
+  long long start_retired = 0;
+  long long stop_retired = 0;
+  long long num_retired;
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printComplexArray( "input1", DATA_SIZE, input1_data );
+  printComplexArray( "input2", DATA_SIZE, input2_data );
+  printComplexArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+  // --------------------------------------------------
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+
+#ifdef SCALAR_C
+  cmplxmult( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef SCALAR_ASM
+  scalar_cmplxmult_asm( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef VT_ASM
+  vt_cmplxmult_asm( DATA_SIZE, input1_data, input2_data, results_data );
+#endif
+#endif
+#endif
+
+#endif
+
+  // --------------------------------------------------
+  // Do the cmplxmult
+
+  start_cycles = getCycles();
+  start_retired = getInstRetired();
+  
+#ifdef SCALAR_C
+  cmplxmult( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef SCALAR_ASM
+  #if HOST_DEBUG==0
+  scalar_cmplxmult_asm( DATA_SIZE, input1_data, input2_data, results_data );
+  #endif
+#else
+#ifdef VT_ASM
+  #if HOST_DEBUG==0
+  vt_cmplxmult_asm( DATA_SIZE, input1_data, input2_data, results_data );
+  #endif
+#endif
+#endif
+#endif
+  
+  stop_cycles  = getCycles();
+  stop_retired = getInstRetired();
+  num_cycles = stop_cycles - start_cycles;
+  num_retired = stop_retired - start_retired;
+
+  // --------------------------------------------------
+  // Print out the results
+
+#if HOST_DEBUG
+  printComplexArray( "results", DATA_SIZE, results_data );
+  printComplexArray( "verify ", DATA_SIZE, verify_data );
+#endif
+
+
+  // --------------------------------------------------
+  // Check the results
+  int correct = verify( DATA_SIZE, results_data, verify_data );
+  finishTest(correct, num_cycles, num_retired);
+
+}
diff --git a/benchmarks/vec-matmul/bmark.mk b/benchmarks/vec-matmul/bmark.mk
new file mode 100644 (file)
index 0000000..a503f7b
--- /dev/null
@@ -0,0 +1,30 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+vec_matmul_c_src = \
+       vec_matmul_main.c \
+
+vec_matmul_riscv_src = \
+       crt.S \
+       vec_matmul_asm.S
+
+vec_matmul_c_objs     = $(patsubst %.c, %.o, $(vec_matmul_c_src))
+vec_matmul_riscv_objs = $(patsubst %.S, %.o, $(vec_matmul_riscv_src))
+
+vec_matmul_host_bin = vec-matmul.host
+$(vec_matmul_host_bin) : $(vec_matmul_c_src)
+       $(HOST_COMP) $^ -o $(vec_matmul_host_bin)
+
+vec_matmul_riscv_bin = vec-matmul.riscv
+$(vec_matmul_riscv_bin) : $(vec_matmul_c_objs) $(vec_matmul_riscv_objs)
+       $(RISCV_LINK) $(RISCV_LINK_SYSCALL) $(vec_matmul_c_objs) $(vec_matmul_riscv_objs) -o $(vec_matmul_riscv_bin)
+
+junk += $(vec_matmul_c_objs) $(vec_matmul_riscv_objs) \
+        $(vec_matmul_host_bin) $(vec_matmul_riscv_bin)
diff --git a/benchmarks/vec-matmul/dataset.h b/benchmarks/vec-matmul/dataset.h
new file mode 100644 (file)
index 0000000..a2dccb4
--- /dev/null
@@ -0,0 +1,633 @@
+
+#define ARRAY_SIZE 4096 
+
+
+#define DIM_SIZE 64 
+
+float input1_data[ARRAY_SIZE] = 
+{
+  0.37, 7.51, 5.09, 1.69, 6.75, 3.16, 1.19, 8.56, 5.26, 7.26, 5.60, 0.06, 8.39, 8.02, 3.54, 6.25, 8.66, 1.00, 1.05, 2.67, 
+  3.84, 2.83, 5.94, 6.97, 2.88, 6.12, 7.88, 3.40, 4.27, 8.45, 4.86, 5.13, 1.83, 2.53, 6.84, 5.46, 4.61, 5.93, 1.76, 0.74, 
+  2.41, 2.06, 3.04, 8.51, 8.13, 2.18, 8.23, 7.45, 8.41, 8.88, 1.77, 8.65, 5.11, 3.16, 5.85, 5.92, 1.63, 1.01, 7.74, 0.59, 
+  2.60, 3.15, 1.28, 8.16, 7.98, 2.38, 5.20, 8.83, 6.86, 2.17, 4.31, 4.50, 3.63, 2.00, 4.00, 6.50, 6.09, 2.86, 2.02, 8.45, 
+  2.60, 1.08, 5.54, 5.46, 3.51, 3.16, 4.10, 2.51, 3.31, 3.23, 5.26, 0.57, 8.88, 3.63, 3.12, 4.66, 5.04, 8.18, 6.99, 2.30, 
+  7.02, 5.39, 1.29, 0.31, 1.13, 8.48, 8.41, 7.20, 4.98, 3.89, 5.85, 8.58, 2.59, 0.18, 0.45, 0.78, 0.86, 3.98, 5.29, 5.54, 
+  3.44, 2.53, 7.28, 8.75, 7.38, 3.11, 4.06, 4.62, 8.70, 3.13, 7.29, 7.95, 4.84, 8.53, 6.32, 3.21, 5.12, 8.03, 0.20, 5.12, 
+  6.00, 3.81, 3.91, 1.43, 0.02, 0.76, 2.23, 0.45, 3.92, 7.14, 7.83, 4.38, 3.73, 3.33, 4.94, 4.67, 8.00, 6.15, 2.57, 2.38, 
+  4.50, 2.62, 8.08, 1.94, 6.59, 6.20, 2.26, 7.08, 5.01, 2.72, 4.76, 4.91, 2.90, 8.54, 2.59, 7.42, 2.75, 7.11, 6.61, 8.65, 
+  3.30, 6.51, 2.65, 8.79, 5.89, 6.75, 0.82, 3.41, 0.95, 0.93, 3.44, 5.87, 7.44, 7.57, 3.22, 1.34, 0.49, 1.26, 8.61, 3.09, 
+  4.81, 6.82, 4.70, 7.55, 5.34, 0.12, 1.56, 0.57, 1.09, 1.20, 6.83, 3.35, 8.57, 0.36, 1.17, 1.00, 7.64, 3.94, 2.30, 2.43, 
+  3.69, 5.66, 3.60, 4.95, 6.79, 5.08, 1.54, 0.17, 6.55, 4.52, 7.01, 0.39, 6.79, 0.73, 1.82, 7.69, 1.39, 6.85, 3.22, 8.50, 
+  8.31, 2.96, 4.47, 3.99, 4.66, 5.78, 2.49, 7.08, 1.03, 7.59, 8.17, 2.48, 2.14, 0.30, 7.07, 5.09, 3.22, 7.24, 7.38, 6.77, 
+  2.52, 0.77, 4.13, 4.10, 6.40, 4.14, 0.38, 2.28, 3.40, 4.58, 6.31, 7.75, 4.33, 6.68, 4.50, 6.39, 0.45, 3.35, 7.87, 8.52, 
+  8.94, 4.75, 6.50, 3.92, 2.10, 4.48, 6.29, 0.28, 3.14, 2.26, 3.16, 2.26, 5.17, 7.06, 6.75, 4.53, 7.42, 7.45, 1.53, 1.45, 
+  6.08, 0.29, 1.82, 1.29, 7.69, 0.81, 3.56, 0.97, 7.70, 0.96, 1.42, 0.05, 6.90, 1.84, 1.76, 5.18, 1.97, 4.74, 1.60, 2.16, 
+  6.30, 6.82, 6.37, 0.45, 0.76, 7.21, 8.05, 4.62, 3.36, 4.44, 0.13, 5.60, 0.75, 0.93, 7.16, 8.30, 5.79, 7.93, 7.52, 2.16, 
+  4.16, 1.03, 5.06, 4.77, 0.09, 8.98, 8.15, 3.49, 3.67, 0.95, 5.04, 8.44, 4.62, 3.69, 2.73, 1.82, 3.85, 5.53, 3.24, 4.70, 
+  6.17, 0.20, 1.67, 2.82, 0.97, 2.48, 3.49, 2.19, 4.38, 0.95, 6.30, 8.10, 6.94, 5.81, 0.73, 1.46, 3.67, 8.52, 0.27, 6.92, 
+  7.84, 1.03, 1.34, 0.56, 1.33, 7.55, 7.61, 3.90, 1.27, 1.90, 7.36, 7.40, 5.07, 3.28, 5.55, 4.47, 7.32, 8.26, 1.44, 3.88, 
+  7.24, 1.62, 4.91, 7.57, 4.13, 7.09, 7.86, 7.17, 7.26, 6.83, 0.94, 3.62, 2.29, 8.87, 1.23, 6.57, 5.27, 7.16, 3.74, 4.76, 
+  6.37, 4.99, 3.41, 6.91, 8.80, 2.13, 8.54, 2.07, 1.49, 4.56, 0.95, 6.35, 7.17, 1.26, 2.74, 7.17, 5.72, 5.05, 1.07, 0.08, 
+  4.79, 7.33, 0.34, 5.27, 6.67, 5.58, 6.91, 4.31, 0.52, 8.64, 7.07, 8.88, 7.54, 2.77, 0.61, 7.43, 8.98, 6.75, 1.55, 7.44, 
+  5.60, 1.40, 7.44, 0.39, 6.25, 0.73, 2.13, 6.74, 6.71, 2.40, 1.12, 6.59, 8.49, 3.83, 3.34, 2.89, 2.43, 4.89, 6.88, 6.78, 
+  8.25, 0.13, 0.01, 8.16, 8.97, 7.30, 5.05, 7.87, 8.76, 2.61, 4.59, 5.03, 8.74, 3.65, 5.22, 2.64, 2.26, 7.66, 1.16, 4.08, 
+  6.45, 0.78, 6.12, 1.64, 2.17, 3.03, 7.15, 5.78, 0.01, 2.88, 8.89, 5.83, 6.80, 8.64, 1.83, 1.28, 1.62, 2.70, 1.49, 6.86, 
+  8.78, 5.83, 5.04, 5.58, 3.81, 2.35, 5.10, 4.88, 4.44, 8.93, 6.72, 1.87, 3.36, 8.40, 5.99, 0.31, 4.81, 4.31, 8.19, 1.83, 
+  0.30, 1.93, 3.30, 8.04, 7.04, 6.13, 6.35, 6.20, 8.53, 3.48, 0.45, 0.91, 4.28, 3.60, 6.12, 2.97, 8.59, 4.25, 4.30, 6.54, 
+  6.43, 8.45, 4.77, 7.84, 0.70, 4.91, 8.18, 7.69, 1.29, 8.82, 2.16, 0.95, 3.29, 0.89, 0.49, 0.88, 3.96, 6.89, 2.84, 3.03, 
+  6.28, 6.98, 6.54, 2.92, 2.55, 4.83, 5.61, 5.36, 8.02, 0.68, 2.62, 4.47, 6.54, 4.05, 4.94, 1.22, 5.81, 7.55, 2.61, 6.91, 
+  1.47, 3.75, 4.43, 8.88, 1.05, 5.57, 7.74, 2.12, 2.55, 5.15, 8.23, 5.05, 1.76, 2.18, 7.05, 8.88, 6.56, 3.10, 3.88, 5.52, 
+  6.85, 1.59, 2.79, 3.01, 3.19, 2.79, 6.30, 0.42, 4.39, 4.54, 0.91, 3.54, 2.42, 2.83, 0.68, 3.12, 8.90, 5.41, 8.19, 3.47, 
+  0.83, 4.91, 2.50, 6.02, 3.17, 7.69, 7.78, 2.82, 0.91, 4.80, 5.12, 7.53, 3.34, 8.92, 4.16, 8.22, 1.64, 2.42, 1.44, 6.95, 
+  0.20, 7.70, 5.81, 0.16, 7.02, 8.21, 7.71, 1.24, 8.86, 6.46, 5.09, 6.48, 2.28, 7.08, 1.39, 1.77, 2.29, 4.03, 8.10, 0.05, 
+  2.94, 5.55, 2.78, 1.58, 1.44, 1.11, 7.56, 6.45, 4.96, 2.07, 0.74, 5.65, 2.92, 8.35, 0.93, 0.16, 8.71, 1.43, 1.60, 5.35, 
+  3.36, 3.55, 5.40, 6.72, 3.40, 7.80, 5.33, 4.98, 3.97, 3.12, 5.35, 2.62, 8.18, 4.91, 3.40, 4.11, 7.04, 0.99, 4.47, 8.07, 
+  7.27, 6.31, 4.94, 3.07, 0.27, 7.48, 5.68, 4.92, 5.53, 8.76, 1.05, 2.83, 8.15, 8.75, 5.47, 7.16, 1.53, 8.08, 4.57, 8.26, 
+  3.89, 3.06, 1.33, 2.03, 1.01, 5.23, 7.52, 1.21, 8.55, 1.82, 4.40, 3.57, 7.19, 4.31, 6.93, 5.17, 4.37, 3.06, 6.50, 4.06, 
+  7.40, 6.71, 0.00, 5.36, 2.50, 1.08, 6.13, 6.82, 5.00, 7.64, 4.66, 3.42, 4.56, 8.15, 2.22, 2.19, 3.55, 3.88, 1.93, 2.20, 
+  4.73, 3.60, 1.56, 2.75, 5.59, 5.36, 4.82, 6.30, 1.44, 6.76, 7.30, 4.10, 0.68, 0.84, 1.51, 0.15, 7.69, 4.46, 2.92, 0.71, 
+  0.47, 1.01, 0.10, 3.09, 6.58, 6.13, 2.59, 8.66, 0.83, 5.64, 8.22, 5.55, 7.75, 6.70, 6.71, 4.31, 5.54, 4.58, 8.24, 7.30, 
+  2.60, 8.78, 1.16, 5.23, 4.95, 7.82, 8.84, 2.43, 5.61, 5.88, 5.64, 8.92, 3.48, 2.92, 4.26, 1.48, 2.16, 1.71, 7.79, 2.09, 
+  3.21, 1.38, 7.44, 2.96, 3.52, 7.64, 0.35, 3.63, 5.56, 4.92, 1.86, 0.02, 7.06, 8.02, 7.34, 7.50, 6.00, 3.70, 0.85, 2.22, 
+  3.80, 1.91, 6.08, 0.09, 3.37, 3.85, 0.58, 0.48, 6.83, 7.31, 4.51, 3.95, 3.03, 2.96, 2.14, 3.75, 4.22, 6.17, 5.09, 2.75, 
+  4.05, 5.39, 1.23, 7.95, 3.45, 8.45, 2.42, 1.04, 8.18, 0.45, 8.58, 3.30, 3.58, 2.32, 2.09, 6.01, 0.32, 8.93, 3.99, 1.93, 
+  3.50, 0.12, 5.60, 0.48, 5.52, 8.42, 8.59, 7.47, 4.16, 5.60, 7.32, 4.71, 6.06, 0.52, 2.82, 3.18, 0.50, 8.76, 6.79, 3.75, 
+  7.92, 7.79, 5.16, 1.47, 6.50, 0.11, 5.80, 4.57, 8.72, 7.04, 7.57, 2.18, 5.68, 7.30, 7.16, 3.93, 7.98, 5.40, 6.28, 5.80, 
+  0.84, 6.40, 7.07, 1.01, 5.24, 0.12, 8.32, 5.55, 5.88, 3.24, 2.36, 2.10, 5.49, 6.18, 4.86, 1.06, 5.05, 6.66, 0.18, 2.86, 
+  8.80, 5.17, 3.48, 6.96, 5.98, 4.55, 1.91, 8.01, 8.17, 3.79, 6.64, 4.65, 0.23, 1.98, 7.19, 6.46, 4.07, 6.23, 6.16, 4.14, 
+  7.35, 2.92, 5.52, 2.23, 1.05, 3.18, 2.54, 6.66, 2.61, 8.20, 5.81, 5.64, 8.40, 1.98, 6.17, 3.36, 7.89, 5.83, 3.71, 8.61, 
+  5.98, 7.66, 7.06, 3.54, 6.38, 3.80, 4.72, 6.15, 0.34, 1.41, 0.39, 6.92, 1.12, 4.95, 7.34, 2.26, 1.93, 1.91, 5.16, 8.10, 
+  8.62, 5.49, 5.87, 3.92, 8.17, 8.75, 5.77, 6.19, 5.78, 2.39, 2.45, 8.76, 7.34, 7.43, 1.09, 4.20, 4.22, 5.69, 2.54, 3.76, 
+  2.84, 2.12, 5.65, 2.67, 4.53, 0.25, 6.02, 2.94, 5.21, 7.94, 2.74, 3.74, 0.00, 1.80, 8.42, 1.92, 4.83, 0.37, 4.76, 7.53, 
+  3.14, 3.05, 2.08, 7.86, 3.38, 1.29, 8.97, 3.47, 7.64, 4.39, 5.30, 0.07, 4.39, 6.57, 8.51, 6.21, 7.85, 1.41, 5.62, 2.43, 
+  0.43, 2.26, 4.43, 7.95, 1.92, 2.09, 2.94, 1.19, 5.81, 3.80, 2.95, 0.52, 6.10, 4.68, 6.99, 2.12, 5.83, 0.86, 2.35, 6.43, 
+  1.79, 4.44, 8.50, 0.78, 2.01, 7.60, 3.04, 6.78, 0.48, 0.78, 8.01, 2.42, 1.69, 6.59, 4.86, 6.84, 8.67, 5.47, 0.09, 5.05, 
+  1.10, 8.62, 2.60, 5.45, 1.16, 0.98, 1.58, 5.32, 3.72, 3.12, 2.25, 5.72, 4.64, 7.20, 7.95, 8.47, 1.42, 7.99, 1.55, 8.78, 
+  8.31, 2.92, 7.06, 7.50, 0.90, 6.96, 6.77, 6.27, 5.86, 8.89, 1.73, 7.19, 0.36, 5.90, 6.86, 8.04, 7.22, 2.50, 4.07, 8.71, 
+  3.25, 0.58, 8.37, 8.24, 4.83, 2.20, 2.39, 7.93, 5.77, 1.88, 2.73, 2.66, 7.33, 5.17, 3.12, 8.69, 4.35, 5.46, 0.92, 1.10, 
+  3.92, 4.09, 0.19, 0.63, 0.21, 2.30, 2.49, 8.02, 3.86, 4.89, 5.61, 6.30, 6.97, 2.67, 2.50, 0.94, 0.72, 5.69, 7.35, 7.67, 
+  6.60, 3.54, 6.85, 1.14, 1.52, 7.60, 1.71, 5.31, 8.44, 2.31, 2.10, 0.68, 1.72, 3.82, 6.77, 6.82, 7.90, 0.43, 7.72, 6.94, 
+  5.75, 4.40, 1.59, 4.27, 4.16, 5.46, 8.32, 0.00, 5.70, 2.53, 8.36, 2.71, 4.07, 6.34, 6.41, 5.59, 4.00, 7.11, 5.51, 2.09, 
+  4.78, 7.13, 6.60, 2.60, 6.55, 7.27, 1.55, 8.09, 4.11, 8.49, 5.47, 7.22, 4.53, 6.68, 7.27, 5.71, 8.56, 8.54, 0.37, 3.18, 
+  1.76, 7.16, 6.31, 2.59, 2.41, 6.98, 5.86, 1.80, 2.38, 2.85, 8.53, 8.47, 5.44, 7.51, 5.76, 4.71, 2.31, 3.77, 2.40, 8.27, 
+  7.09, 7.05, 4.77, 4.45, 2.72, 1.76, 3.53, 6.58, 8.22, 7.19, 4.26, 7.45, 3.31, 1.04, 2.10, 7.66, 7.70, 4.97, 7.72, 2.83, 
+  7.41, 3.81, 1.58, 4.24, 7.49, 2.81, 1.86, 1.30, 0.96, 5.75, 1.21, 5.61, 3.96, 8.23, 5.43, 8.98, 5.00, 4.34, 2.04, 2.93, 
+  7.67, 4.83, 1.21, 1.84, 6.27, 7.13, 1.52, 5.61, 0.78, 4.36, 0.83, 4.25, 4.85, 2.73, 7.01, 6.33, 4.78, 4.14, 8.23, 8.68, 
+  6.17, 2.95, 1.48, 3.94, 1.34, 0.02, 0.96, 6.69, 2.74, 6.26, 4.54, 0.36, 0.35, 0.64, 5.75, 7.60, 2.34, 4.79, 4.43, 6.25, 
+  2.51, 8.74, 4.93, 4.54, 8.61, 6.28, 7.59, 2.93, 2.01, 0.76, 6.60, 2.88, 6.34, 8.83, 4.02, 8.04, 6.21, 0.91, 1.77, 3.10, 
+  5.74, 3.31, 0.43, 7.75, 6.27, 6.53, 1.72, 3.53, 4.60, 8.79, 5.13, 6.52, 6.24, 0.44, 0.44, 0.79, 8.11, 4.38, 3.83, 6.84, 
+  3.97, 0.52, 5.74, 3.65, 5.69, 1.33, 4.02, 3.34, 8.97, 8.70, 6.58, 6.62, 4.21, 6.22, 2.64, 6.19, 3.91, 3.27, 6.54, 6.65, 
+  3.34, 6.68, 4.01, 2.79, 2.52, 3.04, 4.53, 4.66, 7.95, 4.86, 1.32, 3.03, 7.11, 0.71, 3.31, 7.72, 3.82, 0.75, 8.30, 0.79, 
+  4.81, 5.67, 3.09, 5.16, 5.07, 8.93, 4.66, 1.25, 8.37, 6.94, 2.63, 2.03, 5.08, 6.35, 3.44, 5.37, 6.09, 2.09, 5.44, 6.51, 
+  6.72, 7.39, 0.53, 6.51, 2.31, 6.10, 3.97, 5.27, 4.28, 6.01, 0.84, 3.01, 8.33, 1.87, 6.93, 7.91, 7.42, 4.07, 2.90, 5.40, 
+  7.81, 2.58, 6.22, 0.91, 1.94, 4.86, 5.95, 1.32, 4.10, 3.07, 6.98, 4.87, 5.22, 6.54, 6.73, 5.38, 6.92, 4.24, 3.74, 7.73, 
+  7.61, 5.09, 0.53, 8.72, 7.34, 8.81, 3.82, 8.41, 7.31, 0.79, 3.26, 4.74, 1.10, 6.10, 3.31, 2.13, 6.17, 4.51, 5.56, 0.43, 
+  5.57, 1.67, 3.37, 2.13, 7.75, 6.25, 6.17, 5.25, 0.04, 5.95, 3.64, 5.72, 6.50, 5.69, 4.22, 1.38, 0.00, 6.21, 1.98, 3.88, 
+  4.72, 8.70, 3.01, 8.97, 1.71, 2.46, 4.89, 0.68, 5.97, 4.16, 8.50, 2.54, 3.13, 1.23, 1.28, 2.44, 7.82, 0.41, 7.61, 3.72, 
+  4.07, 7.20, 7.54, 1.34, 1.20, 5.22, 3.96, 3.09, 7.16, 1.21, 5.86, 7.72, 3.88, 6.19, 1.79, 4.62, 7.91, 3.12, 5.46, 7.61, 
+  4.60, 1.81, 2.05, 3.05, 8.98, 5.49, 8.15, 2.94, 2.96, 0.75, 4.96, 3.33, 6.48, 7.07, 4.26, 6.62, 8.26, 7.99, 6.56, 4.74, 
+  5.94, 8.64, 1.02, 1.39, 6.70, 0.90, 6.02, 0.47, 2.16, 6.65, 6.77, 0.15, 7.63, 8.45, 6.71, 0.70, 3.14, 4.56, 4.69, 5.16, 
+  2.91, 4.03, 5.26, 8.58, 0.88, 1.11, 5.94, 8.32, 8.46, 8.66, 1.31, 6.44, 0.60, 6.71, 4.30, 5.42, 8.56, 2.51, 8.45, 3.32, 
+  6.74, 6.68, 7.77, 0.07, 3.57, 1.08, 4.59, 7.61, 0.88, 8.17, 0.75, 1.72, 3.95, 6.36, 4.92, 7.28, 3.24, 3.84, 7.68, 6.90, 
+  4.96, 4.93, 2.05, 6.12, 5.62, 2.78, 8.29, 8.76, 5.32, 6.75, 5.97, 4.92, 6.73, 2.08, 5.91, 1.33, 0.64, 4.09, 5.05, 7.53, 
+  5.48, 0.12, 3.33, 1.25, 1.57, 1.89, 4.12, 8.17, 7.51, 1.58, 3.37, 3.76, 2.82, 3.51, 1.40, 8.48, 4.06, 2.55, 8.99, 8.27, 
+  2.55, 8.65, 1.75, 7.20, 1.12, 0.37, 0.56, 7.92, 2.87, 1.80, 4.62, 6.40, 8.19, 3.06, 4.89, 1.61, 5.32, 1.65, 5.58, 8.75, 
+  6.33, 6.45, 3.84, 8.75, 8.61, 1.30, 8.30, 0.15, 7.18, 8.33, 8.70, 5.64, 0.06, 0.06, 0.52, 4.73, 2.23, 5.36, 7.82, 1.97, 
+  6.39, 6.31, 3.10, 4.11, 8.46, 1.42, 0.90, 1.27, 1.96, 0.76, 6.44, 1.35, 5.10, 4.70, 3.17, 4.93, 5.44, 4.85, 6.80, 8.05, 
+  8.23, 1.74, 3.26, 6.33, 5.66, 5.40, 6.19, 5.45, 1.38, 7.12, 5.44, 4.19, 7.04, 1.55, 4.01, 4.52, 0.41, 1.67, 0.64, 4.04, 
+  1.81, 1.72, 1.57, 8.48, 2.30, 6.25, 1.36, 5.52, 2.05, 7.07, 7.03, 7.06, 1.62, 0.48, 7.42, 2.96, 6.12, 2.71, 3.65, 8.60, 
+  8.79, 1.11, 6.12, 1.42, 1.14, 6.64, 8.20, 0.79, 6.54, 4.80, 4.27, 7.99, 6.45, 4.13, 6.93, 3.45, 7.96, 6.46, 2.17, 5.20, 
+  3.35, 2.16, 8.51, 0.95, 4.20, 0.49, 1.56, 5.85, 3.49, 8.86, 5.87, 3.00, 5.77, 0.61, 6.97, 2.54, 6.56, 6.41, 0.74, 7.82, 
+  5.72, 8.04, 0.11, 5.63, 5.49, 5.55, 4.33, 4.16, 1.47, 4.20, 4.24, 5.58, 1.05, 2.81, 1.68, 6.50, 6.93, 1.30, 6.58, 3.81, 
+  8.53, 5.12, 4.26, 3.43, 7.09, 6.40, 4.23, 6.57, 5.09, 1.28, 3.09, 7.12, 7.43, 8.85, 0.19, 4.35, 2.81, 4.62, 5.40, 7.24, 
+  8.66, 4.13, 3.43, 6.95, 2.63, 5.68, 7.62, 3.92, 0.64, 6.61, 8.10, 8.23, 0.55, 8.87, 2.20, 8.43, 8.65, 5.67, 1.31, 0.07, 
+  3.95, 5.32, 1.48, 1.77, 2.18, 2.15, 6.08, 4.10, 8.87, 6.47, 0.75, 5.36, 1.01, 3.26, 6.48, 2.29, 8.51, 4.07, 3.12, 6.50, 
+  4.23, 0.18, 8.89, 0.37, 6.33, 3.63, 5.91, 5.20, 0.43, 0.17, 0.97, 1.74, 0.63, 1.55, 3.57, 1.72, 4.30, 6.81, 3.92, 4.34, 
+  8.37, 3.35, 1.46, 6.83, 4.26, 6.71, 1.84, 0.48, 0.51, 2.88, 0.92, 6.50, 4.94, 4.92, 2.53, 6.90, 1.44, 6.36, 8.51, 3.87, 
+  8.61, 0.68, 8.88, 1.30, 3.97, 7.55, 7.33, 2.36, 6.86, 4.36, 6.70, 4.18, 2.10, 2.52, 1.80, 3.43, 2.14, 0.80, 4.78, 6.86, 
+  4.56, 8.82, 6.26, 4.33, 8.98, 0.24, 3.34, 6.76, 2.71, 1.92, 3.38, 1.91, 4.99, 5.61, 3.28, 8.60, 3.45, 8.26, 8.19, 1.23, 
+  1.92, 5.99, 8.87, 4.88, 6.12, 2.39, 7.14, 3.52, 4.44, 0.30, 5.79, 5.90, 2.60, 4.83, 2.61, 3.94, 4.38, 3.65, 6.57, 2.19, 
+  0.99, 5.84, 8.72, 4.90, 7.66, 8.99, 6.03, 6.02, 3.77, 8.07, 8.44, 8.07, 3.00, 4.78, 6.10, 5.49, 8.09, 6.89, 1.22, 4.39, 
+  0.26, 8.00, 2.15, 0.28, 8.79, 7.83, 2.73, 1.47, 7.08, 1.66, 4.82, 2.03, 4.18, 3.37, 4.39, 4.46, 3.90, 1.57, 2.82, 2.06, 
+  7.67, 4.14, 1.86, 3.15, 6.80, 2.17, 8.32, 0.79, 6.94, 6.13, 5.56, 2.79, 3.62, 3.51, 4.83, 7.05, 3.98, 2.61, 2.92, 3.14, 
+  1.28, 8.84, 6.70, 7.30, 1.45, 7.71, 6.01, 3.48, 1.36, 1.31, 0.67, 6.24, 1.02, 6.96, 5.65, 5.71, 2.17, 0.70, 1.07, 8.49, 
+  0.71, 4.29, 6.19, 7.86, 2.14, 6.27, 2.59, 2.22, 7.35, 4.08, 2.54, 0.45, 8.05, 3.20, 3.79, 8.00, 1.74, 3.53, 6.26, 7.57, 
+  0.44, 4.99, 6.66, 6.21, 3.07, 0.22, 4.53, 0.81, 8.36, 7.99, 8.00, 8.63, 3.70, 4.72, 8.58, 2.15, 7.18, 5.89, 0.34, 2.41, 
+  6.41, 4.71, 7.80, 1.52, 3.16, 7.77, 2.78, 0.17, 2.57, 0.74, 8.48, 0.82, 4.98, 5.15, 8.94, 1.09, 2.10, 1.83, 5.18, 3.34, 
+  7.44, 6.97, 2.70, 2.33, 2.88, 6.38, 4.91, 3.98, 7.04, 2.64, 5.75, 4.93, 6.13, 5.19, 1.73, 1.80, 8.19, 3.51, 5.94, 5.19, 
+  5.99, 0.49, 8.51, 4.70, 8.17, 0.27, 4.94, 1.16, 1.17, 1.27, 2.84, 7.26, 5.08, 0.37, 2.77, 0.65, 6.46, 2.44, 6.46, 6.04, 
+  3.56, 5.31, 0.14, 1.97, 8.44, 2.45, 6.53, 1.93, 3.89, 6.35, 2.74, 1.38, 0.86, 8.45, 5.76, 4.33, 7.68, 7.18, 4.88, 2.68, 
+  3.24, 7.19, 4.26, 0.20, 3.50, 3.44, 4.08, 6.82, 4.80, 8.19, 6.35, 6.25, 5.88, 4.18, 1.57, 6.15, 2.90, 6.79, 4.01, 0.93, 
+  7.74, 2.59, 8.84, 1.73, 1.34, 5.29, 7.57, 2.92, 5.12, 3.71, 1.50, 1.03, 7.44, 7.19, 7.79, 7.16, 3.68, 2.94, 7.33, 0.67, 
+  5.57, 1.14, 7.51, 4.79, 8.46, 0.38, 4.22, 6.21, 4.62, 7.38, 2.42, 0.58, 0.84, 3.50, 8.21, 8.07, 6.67, 0.50, 8.74, 6.50, 
+  7.65, 8.65, 5.05, 6.07, 7.68, 1.92, 3.81, 1.59, 0.85, 8.35, 1.88, 6.29, 8.07, 7.48, 7.85, 3.51, 7.40, 1.39, 0.97, 6.03, 
+  4.48, 2.95, 6.43, 3.08, 1.00, 3.17, 5.59, 3.26, 8.13, 7.34, 0.41, 1.85, 4.92, 1.89, 8.54, 5.79, 2.42, 5.40, 4.36, 7.67, 
+  0.23, 6.39, 5.78, 0.01, 6.89, 1.63, 5.76, 7.47, 0.96, 0.85, 8.31, 2.91, 2.59, 7.70, 7.44, 1.93, 3.07, 1.62, 0.17, 8.85, 
+  7.36, 2.14, 8.14, 8.78, 2.23, 8.83, 0.22, 4.15, 6.80, 2.60, 3.06, 6.81, 7.96, 7.72, 0.08, 0.52, 6.82, 6.20, 7.78, 1.81, 
+  1.34, 5.62, 3.44, 4.02, 7.92, 5.57, 3.06, 2.14, 2.54, 3.14, 6.50, 0.82, 0.79, 2.80, 6.22, 8.54, 1.96, 7.09, 5.31, 7.20, 
+  3.90, 8.27, 0.22, 8.43, 6.35, 5.93, 0.38, 8.36, 3.92, 5.08, 2.60, 2.83, 3.71, 2.03, 7.62, 0.15, 4.29, 5.64, 0.90, 6.58, 
+  3.43, 7.94, 5.66, 7.70, 2.47, 5.57, 5.26, 0.56, 5.16, 6.38, 4.01, 2.51, 6.34, 2.00, 3.26, 6.02, 3.38, 1.78, 4.60, 1.61, 
+  4.93, 2.85, 0.22, 3.33, 2.53, 5.47, 0.78, 4.76, 8.58, 0.82, 6.60, 4.66, 1.33, 5.94, 6.72, 3.81, 6.02, 5.02, 7.03, 7.40, 
+  6.55, 4.70, 4.72, 3.70, 3.08, 0.53, 2.34, 7.37, 3.36, 2.66, 6.10, 5.75, 3.91, 5.43, 1.46, 1.19, 1.04, 4.17, 0.42, 5.15, 
+  5.10, 0.87, 5.07, 8.22, 4.78, 8.95, 2.37, 2.88, 2.90, 7.36, 6.55, 0.99, 0.62, 0.76, 2.56, 7.41, 7.49, 6.39, 2.27, 4.17, 
+  6.95, 6.36, 8.93, 3.94, 6.12, 2.93, 5.60, 3.26, 5.10, 4.21, 7.69, 6.03, 8.37, 4.51, 7.06, 8.69, 4.88, 3.97, 7.90, 0.83, 
+  2.91, 0.91, 5.41, 2.09, 8.08, 8.62, 3.05, 6.34, 8.68, 3.64, 2.66, 6.70, 4.39, 5.01, 0.38, 2.39, 0.12, 8.81, 2.43, 4.36, 
+  1.18, 4.88, 0.77, 3.21, 1.98, 0.93, 7.88, 8.49, 1.10, 7.81, 3.33, 1.83, 2.99, 0.87, 0.33, 1.97, 5.49, 2.65, 3.16, 4.66, 
+  6.07, 1.03, 7.29, 8.93, 6.93, 0.33, 6.82, 8.06, 4.17, 2.29, 2.36, 4.73, 8.65, 3.17, 2.46, 4.63, 5.86, 0.49, 2.44, 0.69, 
+  2.43, 6.98, 3.87, 1.62, 3.15, 6.37, 1.06, 3.43, 1.18, 8.66, 1.54, 8.64, 1.17, 5.25, 8.77, 0.76, 8.60, 3.11, 7.70, 8.60, 
+  6.86, 7.94, 5.95, 2.52, 8.36, 0.57, 6.10, 8.60, 1.66, 4.63, 2.53, 4.91, 3.66, 7.74, 6.57, 0.07, 6.77, 4.66, 5.40, 0.98, 
+  5.42, 8.34, 1.95, 1.50, 0.70, 5.54, 2.44, 0.55, 4.16, 7.94, 4.92, 8.54, 0.00, 6.61, 2.58, 6.72, 8.35, 3.13, 2.62, 2.28, 
+  4.46, 5.11, 2.34, 6.47, 0.07, 7.50, 2.27, 6.97, 5.10, 4.70, 3.56, 8.31, 2.84, 7.95, 1.09, 1.55, 3.86, 5.54, 2.52, 8.94, 
+  0.31, 6.21, 4.31, 4.72, 4.74, 1.52, 7.44, 7.17, 3.98, 5.77, 0.94, 7.47, 1.75, 3.44, 0.19, 5.79, 4.18, 4.43, 7.75, 5.12, 
+  0.03, 0.87, 2.74, 7.03, 8.07, 1.17, 5.52, 5.54, 0.94, 3.31, 6.48, 0.81, 2.20, 1.30, 8.46, 8.97, 0.92, 5.72, 1.70, 0.96, 
+  3.14, 5.78, 5.58, 2.55, 2.55, 5.57, 4.63, 7.06, 1.93, 0.26, 1.21, 5.62, 2.06, 2.00, 8.95, 5.60, 6.64, 6.35, 5.93, 6.32, 
+  1.10, 0.69, 6.72, 0.61, 2.13, 8.11, 2.80, 1.04, 2.76, 4.66, 1.00, 2.99, 8.80, 0.65, 5.52, 8.76, 7.94, 0.88, 6.63, 0.12, 
+  0.97, 5.46, 3.86, 6.42, 3.56, 8.64, 2.12, 1.57, 6.18, 6.89, 7.61, 3.66, 8.46, 5.88, 4.44, 6.87, 6.53, 0.74, 6.86, 0.79, 
+  1.70, 2.10, 0.12, 4.82, 3.85, 6.08, 1.32, 7.72, 1.66, 6.35, 8.14, 7.64, 0.32, 1.54, 1.94, 7.15, 8.31, 1.55, 3.41, 0.04, 
+  8.81, 1.88, 0.23, 8.42, 0.41, 2.26, 7.78, 9.00, 2.17, 6.53, 1.85, 7.64, 1.53, 5.26, 0.99, 7.77, 1.05, 4.32, 7.46, 5.12, 
+  6.13, 4.99, 7.87, 8.50, 7.13, 4.70, 5.82, 8.19, 0.22, 4.51, 0.79, 7.37, 3.80, 5.08, 1.76, 3.90, 7.18, 0.42, 5.26, 6.26, 
+  5.66, 4.23, 4.45, 5.23, 1.77, 3.20, 6.86, 4.24, 5.40, 2.67, 3.00, 6.75, 5.60, 3.61, 7.27, 7.44, 1.88, 5.63, 3.49, 2.93, 
+  4.36, 5.27, 2.91, 0.16, 7.47, 1.06, 5.78, 8.46, 4.65, 2.58, 4.35, 2.11, 7.15, 4.53, 7.83, 4.37, 1.34, 1.45, 0.77, 6.32, 
+  5.62, 4.30, 1.40, 5.77, 6.61, 2.68, 0.86, 8.01, 4.64, 1.70, 6.19, 8.38, 6.18, 4.85, 5.14, 4.44, 6.40, 2.60, 2.93, 5.39, 
+  7.43, 5.05, 0.47, 0.70, 6.31, 6.78, 6.04, 7.22, 4.38, 4.90, 7.25, 4.62, 3.94, 8.30, 5.66, 8.15, 1.66, 4.61, 4.69, 5.64, 
+  8.75, 4.22, 6.35, 7.96, 8.04, 6.07, 2.90, 6.18, 1.76, 2.39, 4.66, 1.05, 2.17, 3.18, 2.01, 5.64, 5.56, 2.94, 2.46, 0.72, 
+  1.41, 2.96, 3.30, 1.36, 3.18, 2.92, 1.68, 6.47, 7.18, 6.15, 6.13, 1.14, 6.58, 3.13, 0.78, 4.56, 6.99, 4.25, 7.31, 7.95, 
+  2.04, 7.92, 6.21, 4.23, 0.12, 7.31, 3.84, 3.05, 5.55, 1.86, 2.67, 6.28, 6.73, 1.91, 2.56, 0.73, 4.98, 6.21, 7.87, 0.88, 
+  4.71, 2.11, 5.94, 7.28, 8.72, 5.79, 7.09, 3.84, 1.72, 7.29, 8.92, 6.94, 8.95, 6.70, 5.87, 7.77, 1.96, 7.18, 7.88, 0.84, 
+  2.87, 1.71, 0.47, 5.72, 7.99, 5.56, 6.81, 1.45, 1.38, 0.70, 0.99, 4.37, 1.35, 0.30, 8.44, 3.73, 2.25, 6.15, 1.35, 8.82, 
+  1.83, 3.90, 6.90, 2.11, 5.55, 5.60, 8.45, 8.42, 0.88, 1.50, 1.04, 7.23, 8.00, 0.78, 2.20, 4.43, 8.14, 7.14, 4.66, 0.64, 
+  4.58, 5.55, 6.34, 5.26, 2.42, 2.76, 5.14, 2.17, 1.39, 1.04, 2.05, 7.65, 3.38, 6.11, 4.29, 3.74, 0.68, 0.60, 4.02, 2.01, 
+  5.84, 2.73, 7.33, 2.50, 2.59, 1.39, 8.28, 6.85, 6.52, 1.43, 8.49, 8.87, 6.99, 6.78, 1.02, 3.95, 4.45, 7.15, 5.43, 5.78, 
+  1.32, 8.84, 3.24, 8.69, 2.58, 4.05, 5.61, 0.08, 3.64, 2.65, 2.90, 7.76, 4.22, 8.19, 7.29, 3.09, 6.91, 7.15, 6.01, 3.10, 
+  0.23, 8.16, 3.68, 4.57, 6.49, 6.81, 8.63, 6.91, 8.34, 1.52, 6.64, 6.80, 6.31, 0.28, 8.98, 5.83, 2.85, 3.94, 7.73, 7.34, 
+  1.05, 2.86, 0.93, 4.94, 7.56, 0.36, 3.60, 1.78, 5.54, 4.46, 0.62, 2.97, 5.79, 7.61, 8.07, 7.54, 7.02, 4.30, 7.10, 4.92, 
+  7.82, 6.20, 2.29, 4.47, 6.03, 2.59, 7.02, 0.03, 6.04, 5.37, 1.88, 4.91, 8.08, 2.93, 0.90, 6.73, 0.69, 3.51, 8.01, 0.33, 
+  1.39, 0.22, 3.60, 0.05, 2.02, 4.56, 7.66, 1.86, 3.31, 3.16, 0.80, 7.59, 7.13, 1.07, 1.63, 7.21, 8.17, 7.84, 7.70, 5.14, 
+  5.94, 7.81, 5.06, 7.79, 4.80, 2.81, 0.35, 1.36, 1.01, 7.44, 3.46, 8.15, 8.91, 7.80, 5.22, 1.20, 1.13, 4.37, 2.56, 4.93, 
+  3.94, 5.86, 4.91, 8.10, 4.96, 7.91, 6.39, 0.98, 1.28, 0.53, 4.16, 1.96, 2.04, 1.38, 3.55, 6.38, 0.87, 8.62, 8.51, 3.45, 
+  3.05, 1.63, 7.50, 7.42, 4.54, 8.32, 3.32, 4.23, 5.15, 0.40, 1.22, 3.84, 2.64, 8.93, 5.04, 4.18, 7.67, 4.21, 7.84, 0.96, 
+  0.90, 5.47, 6.75, 2.54, 6.55, 4.83, 6.82, 7.37, 3.46, 6.79, 2.57, 8.65, 6.33, 2.53, 2.89, 1.29, 5.46, 4.06, 7.42, 4.84, 
+  0.52, 8.63, 7.86, 1.95, 5.79, 0.85, 0.08, 3.38, 8.69, 1.03, 4.00, 6.45, 7.86, 2.90, 7.70, 8.74, 8.64, 6.85, 4.55, 5.00, 
+  5.39, 3.53, 3.17, 4.53, 0.39, 2.15, 5.55, 1.49, 6.56, 2.27, 8.96, 5.76, 8.99, 5.56, 3.20, 4.73, 8.24, 6.97, 2.33, 3.54, 
+  6.24, 6.27, 1.20, 3.00, 4.91, 7.79, 2.06, 0.07, 3.91, 8.54, 6.97, 8.50, 2.53, 3.48, 8.11, 1.65, 6.12, 8.86, 8.69, 0.01, 
+  0.67, 1.07, 7.89, 1.26, 5.76, 3.35, 8.42, 7.87, 7.34, 1.92, 3.86, 2.57, 5.27, 8.06, 8.85, 2.84, 0.55, 7.50, 1.86, 4.69, 
+  8.23, 5.20, 6.49, 8.82, 4.52, 8.61, 0.38, 4.01, 2.32, 0.49, 1.17, 6.24, 1.01, 4.77, 5.45, 8.77, 1.82, 1.20, 7.33, 5.58, 
+  1.21, 4.07, 8.12, 1.42, 3.66, 5.52, 0.46, 6.54, 3.15, 0.62, 7.58, 1.79, 1.67, 6.35, 4.48, 1.61, 2.60, 1.39, 3.36, 8.58, 
+  7.54, 5.67, 6.19, 5.14, 2.92, 5.27, 8.24, 3.84, 2.62, 1.98, 5.90, 1.23, 7.29, 1.37, 0.81, 0.35, 7.62, 5.63, 2.88, 2.89, 
+  6.29, 2.06, 8.77, 6.10, 0.76, 3.94, 4.39, 3.40, 2.85, 2.26, 3.32, 7.26, 2.12, 7.33, 5.16, 7.86, 1.86, 1.83, 7.49, 1.32, 
+  4.96, 4.14, 3.88, 2.15, 2.11, 5.37, 3.98, 6.39, 4.44, 4.54, 7.88, 7.04, 3.35, 5.44, 4.99, 1.70, 7.06, 5.93, 7.05, 7.10, 
+  7.53, 3.21, 0.20, 8.93, 5.51, 1.64, 7.87, 5.44, 4.59, 5.07, 5.66, 3.82, 5.05, 4.82, 4.83, 7.73, 7.35, 8.53, 6.41, 7.13, 
+  0.41, 6.92, 2.84, 1.97, 4.36, 1.67, 2.03, 4.12, 2.83, 0.01, 8.28, 2.69, 7.80, 2.80, 6.54, 0.89, 2.86, 4.98, 7.84, 5.90, 
+  6.70, 7.16, 0.22, 6.35, 8.97, 5.26, 1.30, 8.80, 7.11, 6.75, 4.22, 0.70, 6.98, 2.70, 3.86, 8.05, 1.12, 8.80, 1.28, 7.60, 
+  3.09, 0.62, 7.72, 0.21, 5.60, 7.24, 3.75, 2.39, 8.83, 0.32, 3.03, 1.49, 8.27, 8.31, 5.66, 3.28, 0.24, 0.44, 7.28, 7.16, 
+  2.46, 6.19, 7.73, 1.02, 2.27, 0.04, 0.95, 2.03, 6.51, 5.16, 0.45, 6.68, 1.86, 8.25, 1.90, 0.95, 1.80, 6.87, 8.59, 3.62, 
+  7.63, 2.79, 0.66, 1.22, 4.90, 0.55, 5.87, 6.52, 8.76, 6.94, 2.92, 1.46, 5.21, 5.27, 5.59, 0.26, 2.68, 6.50, 4.62, 0.14, 
+  6.13, 8.68, 5.47, 2.01, 1.67, 6.86, 6.58, 6.93, 4.65, 8.79, 6.92, 5.74, 3.37, 1.49, 6.44, 2.65, 7.88, 7.64, 7.62, 2.97, 
+  1.87, 3.11, 7.48, 2.28, 6.94, 6.00, 3.12, 5.66, 1.90, 3.48, 4.59, 8.50, 2.12, 5.53, 8.68, 8.40, 0.30, 8.77, 0.32, 5.63, 
+  4.42, 8.80, 6.68, 0.27, 0.61, 2.59, 6.88, 1.88, 3.74, 1.34, 6.42, 4.17, 2.79, 6.43, 1.55, 4.46, 4.31, 0.53, 8.94, 6.47, 
+  2.09, 3.98, 2.85, 2.80, 5.26, 6.95, 5.24, 2.12, 6.79, 2.55, 5.35, 1.92, 4.28, 1.58, 3.14, 4.74, 5.20, 2.61, 8.00, 5.89, 
+  5.87, 8.90, 8.53, 8.27, 4.20, 0.16, 4.50, 6.73, 8.60, 4.90, 5.83, 6.20, 2.29, 4.49, 3.92, 0.16, 2.36, 0.36, 2.84, 5.48, 
+  5.70, 2.38, 8.61, 7.31, 8.54, 2.06, 0.36, 1.55, 0.30, 0.06, 4.20, 2.03, 0.59, 6.77, 1.27, 0.20, 1.17, 6.25, 1.18, 6.49, 
+  3.45, 5.13, 4.83, 3.16, 7.13, 2.19, 7.36, 7.34, 6.78, 1.73, 6.58, 2.64, 4.63, 0.49, 2.10, 4.39, 3.97, 6.15, 7.98, 5.08, 
+  5.76, 0.19, 3.40, 1.78, 3.31, 5.59, 6.58, 8.09, 8.26, 7.44, 5.91, 5.95, 3.95, 4.47, 2.64, 0.16, 1.79, 5.46, 2.55, 7.09, 
+  3.36, 2.19, 6.20, 1.63, 2.94, 2.97, 7.49, 3.58, 6.52, 7.62, 4.15, 5.07, 4.64, 4.15, 0.46, 5.82, 0.05, 2.41, 1.85, 8.97, 
+  6.89, 6.65, 2.63, 2.47, 0.89, 1.01, 4.22, 7.52, 1.17, 1.51, 1.71, 0.83, 3.46, 6.85, 1.47, 8.72, 7.79, 4.77, 3.90, 3.06, 
+  2.23, 8.28, 8.83, 2.26, 7.03, 0.23, 6.78, 7.30, 8.11, 7.21, 4.90, 7.73, 3.00, 7.67, 4.43, 8.11, 6.32, 3.40, 2.61, 3.34, 
+  2.34, 7.38, 3.19, 8.56, 3.34, 3.94, 2.86, 4.94, 7.35, 2.95, 2.02, 4.98, 7.34, 3.40, 6.21, 1.20, 8.15, 2.49, 1.25, 6.35, 
+  4.11, 8.57, 8.34, 1.25, 5.91, 6.97, 7.18, 8.50, 2.32, 3.94, 6.12, 3.96, 2.23, 6.12, 1.94, 7.97, 7.76, 8.18, 7.51, 5.90, 
+  0.36, 3.20, 3.44, 6.99, 4.77, 5.38, 4.53, 5.47, 2.64, 1.58, 0.36, 8.85, 7.15, 4.71, 6.10, 7.87, 0.44, 5.89, 8.57, 4.94, 
+  0.04, 7.85, 4.64, 1.74, 8.59, 2.23, 2.33, 1.92, 1.79, 7.34, 4.36, 6.83, 0.86, 1.61, 7.21, 4.86, 8.75, 6.66, 7.99, 5.97, 
+  1.14, 7.80, 4.60, 0.50, 2.32, 0.69, 4.27, 0.06, 2.33, 7.04, 2.25, 4.72, 2.00, 1.83, 1.26, 4.04, 8.14, 7.38, 6.15, 7.00, 
+  5.97, 1.13, 8.59, 1.94, 0.17, 4.68, 0.70, 6.54, 5.69, 7.91, 0.04, 7.57, 4.08, 6.42, 1.12, 4.06, 1.43, 7.89, 7.06, 1.38, 
+  7.84, 3.87, 1.33, 4.71, 2.59, 5.86, 1.16, 2.46, 0.07, 1.35, 2.87, 8.53, 7.61, 6.29, 8.33, 5.92, 3.18, 6.58, 6.69, 3.32, 
+  5.43, 3.40, 0.87, 3.99, 4.80, 5.27, 4.62, 3.91, 6.93, 0.75, 5.21, 5.63, 8.60, 8.62, 1.05, 4.23, 8.90, 1.23, 2.70, 7.37, 
+  4.67, 3.23, 7.19, 7.63, 2.40, 0.96, 3.55, 5.79, 3.85, 4.64, 6.65, 6.29, 4.58, 4.75, 1.12, 8.92, 3.81, 3.58, 1.46, 7.78, 
+  5.22, 1.77, 2.47, 6.31, 8.82, 1.45, 6.80, 2.11, 0.73, 4.81, 8.81, 3.62, 2.33, 0.89, 8.79, 7.67, 2.27, 6.29, 2.23, 4.94, 
+  7.95, 8.18, 1.39, 4.09, 6.18, 3.77, 5.88, 8.37, 7.41, 8.00, 4.14, 2.84, 7.04, 6.70, 8.42, 1.29, 8.60, 7.80, 1.24, 5.03, 
+  0.89, 1.65, 4.56, 7.54, 0.70, 8.63, 5.33, 2.91, 0.48, 8.27, 0.82, 6.46, 4.07, 4.43, 1.83, 3.87, 5.68, 0.67, 8.93, 5.31, 
+  1.46, 6.00, 8.85, 3.92, 0.26, 2.06, 6.54, 8.74, 7.58, 7.04, 3.85, 2.14, 3.71, 5.75, 0.07, 0.23, 5.12, 1.19, 1.78, 5.42, 
+  1.97, 7.87, 2.90, 7.68, 8.88, 7.88, 4.16, 2.48, 6.02, 7.48, 5.26, 3.57, 8.49, 4.39, 0.42, 5.09, 3.78, 2.84, 5.50, 4.35, 
+  1.84, 5.37, 6.58, 4.87, 4.86, 6.06, 3.61, 6.99, 0.37, 2.91, 2.88, 2.18, 1.96, 1.35, 4.10, 5.97, 6.64, 3.73, 3.08, 4.95, 
+  8.10, 8.68, 5.74, 2.90, 2.96, 7.15, 4.45, 5.39, 6.85, 2.51, 2.68, 4.71, 0.99, 2.96, 1.80, 8.04, 6.37, 4.85, 5.93, 8.14, 
+  6.53, 8.20, 7.95, 4.57, 2.80, 7.94, 6.29, 6.84, 7.93, 1.68, 7.46, 0.23, 3.39, 5.19, 0.19, 5.40, 8.90, 4.53, 6.73, 0.91, 
+  0.46, 6.23, 4.04, 0.04, 2.61, 8.29, 3.58, 7.20, 5.91, 4.19, 2.94, 4.94, 2.25, 3.23, 7.87, 0.94
+};
+
+float input2_data[ARRAY_SIZE] = 
+{
+  4.09, 3.02, 0.02, 8.91, 3.30, 5.16, 0.58, 1.38, 1.95, 1.26, 1.90, 5.16, 3.06, 5.34, 8.09, 2.06, 0.11, 7.96, 6.76, 5.82, 
+  4.51, 3.93, 6.32, 7.32, 8.84, 1.36, 6.27, 5.08, 2.45, 2.33, 5.83, 4.59, 0.80, 6.34, 6.04, 3.38, 4.97, 8.44, 5.34, 5.13, 
+  8.58, 7.22, 5.26, 5.79, 3.32, 4.41, 2.96, 2.82, 5.34, 3.50, 4.90, 5.85, 8.82, 8.99, 7.34, 0.71, 1.88, 8.99, 5.67, 7.63, 
+  6.35, 8.98, 2.28, 6.45, 3.87, 3.74, 4.85, 6.31, 0.04, 4.46, 0.90, 7.79, 6.25, 3.75, 2.67, 2.58, 5.59, 0.71, 3.17, 4.87, 
+  5.83, 1.53, 4.75, 2.61, 7.17, 7.22, 6.49, 6.84, 6.72, 0.83, 8.91, 2.44, 7.69, 7.10, 4.79, 2.01, 4.15, 2.18, 3.23, 2.99, 
+  6.17, 6.67, 4.02, 2.81, 6.70, 5.02, 4.32, 5.02, 8.34, 7.17, 3.22, 8.03, 6.00, 4.64, 5.03, 7.84, 7.69, 3.97, 0.55, 6.12, 
+  3.57, 0.09, 0.16, 1.54, 2.62, 3.43, 4.83, 1.67, 8.26, 4.86, 8.86, 8.00, 0.49, 5.52, 8.57, 4.32, 1.36, 0.07, 5.78, 3.02, 
+  6.58, 0.86, 6.56, 2.53, 3.56, 6.20, 8.21, 4.30, 7.34, 6.57, 2.39, 1.15, 2.13, 1.93, 1.63, 0.06, 4.54, 5.37, 1.56, 5.80, 
+  3.13, 5.40, 0.62, 7.66, 5.93, 5.58, 1.10, 1.19, 7.47, 6.01, 3.91, 4.40, 6.79, 1.13, 5.65, 0.13, 0.10, 3.64, 0.95, 6.34, 
+  7.37, 8.69, 3.66, 7.88, 7.72, 0.78, 0.54, 5.95, 6.02, 1.38, 1.09, 0.88, 3.72, 2.13, 0.11, 3.82, 8.70, 1.95, 5.60, 3.26, 
+  8.30, 6.44, 5.83, 2.70, 7.99, 6.15, 0.33, 4.45, 4.96, 4.84, 8.74, 5.79, 3.91, 3.74, 2.73, 3.95, 7.75, 1.83, 4.31, 8.90, 
+  6.08, 6.48, 8.92, 3.05, 4.06, 5.70, 1.40, 5.83, 4.08, 3.85, 4.59, 8.91, 3.84, 0.11, 4.35, 1.28, 3.06, 3.52, 0.46, 1.54, 
+  5.42, 0.95, 8.73, 1.09, 7.93, 0.74, 7.84, 5.41, 5.44, 7.85, 8.00, 5.50, 3.65, 2.11, 6.72, 4.74, 2.48, 3.98, 2.04, 6.78, 
+  8.50, 6.54, 6.39, 1.81, 0.49, 6.83, 0.48, 3.58, 0.37, 1.27, 3.75, 6.74, 1.98, 4.31, 6.94, 1.62, 4.35, 6.23, 6.53, 1.56, 
+  1.68, 8.24, 0.01, 8.68, 2.23, 4.19, 3.27, 4.70, 2.11, 1.09, 0.37, 7.02, 1.76, 1.45, 6.70, 3.96, 3.21, 3.63, 1.27, 5.70, 
+  2.61, 7.05, 2.88, 5.73, 1.07, 7.68, 0.64, 7.35, 3.50, 8.60, 0.32, 0.15, 6.29, 6.27, 6.10, 5.39, 7.96, 7.43, 6.73, 4.17, 
+  4.61, 4.81, 3.97, 3.86, 6.60, 6.55, 6.33, 4.93, 0.78, 7.20, 1.94, 0.20, 5.87, 0.54, 3.87, 5.93, 0.87, 8.77, 5.94, 8.70, 
+  4.72, 0.56, 5.63, 2.73, 6.44, 3.69, 0.50, 6.57, 2.75, 3.93, 8.12, 5.34, 6.23, 7.18, 4.48, 1.60, 8.48, 8.97, 4.33, 1.43, 
+  7.41, 5.51, 6.13, 0.13, 1.01, 7.18, 1.67, 0.00, 6.48, 0.87, 6.75, 6.66, 7.33, 3.92, 2.94, 0.34, 0.31, 5.46, 8.43, 0.24, 
+  0.80, 3.98, 3.06, 3.10, 4.99, 3.29, 8.60, 5.76, 3.57, 8.93, 2.25, 3.05, 7.50, 8.78, 3.55, 2.40, 4.24, 3.14, 3.03, 3.78, 
+  2.25, 1.95, 4.89, 8.14, 5.73, 6.58, 5.24, 7.39, 6.05, 8.82, 3.77, 6.04, 8.29, 5.12, 6.71, 5.97, 1.25, 3.48, 8.36, 1.56, 
+  4.12, 2.85, 1.66, 4.30, 1.77, 3.60, 3.75, 7.26, 8.98, 2.43, 6.63, 6.28, 7.44, 4.76, 0.46, 5.62, 4.84, 0.79, 2.65, 7.82, 
+  0.99, 3.59, 7.04, 5.83, 3.38, 8.50, 8.08, 5.31, 0.40, 2.60, 7.62, 6.69, 0.89, 4.71, 4.00, 3.89, 1.49, 8.39, 0.26, 4.16, 
+  2.92, 2.46, 3.39, 3.07, 8.09, 1.43, 1.52, 4.00, 1.75, 5.69, 8.43, 2.47, 7.04, 1.67, 5.58, 2.63, 8.41, 1.41, 7.45, 0.80, 
+  8.90, 5.67, 5.85, 0.29, 0.01, 6.71, 3.60, 8.25, 7.13, 5.00, 8.87, 4.78, 5.41, 3.62, 6.15, 4.87, 8.14, 1.09, 8.97, 4.70, 
+  5.61, 2.02, 8.07, 4.78, 7.39, 5.87, 2.04, 0.87, 2.37, 5.13, 2.15, 1.14, 5.50, 1.73, 2.15, 7.18, 7.97, 5.16, 0.97, 1.27, 
+  7.11, 7.68, 0.21, 6.35, 8.02, 4.33, 0.48, 3.36, 1.81, 4.92, 3.68, 1.08, 5.82, 4.19, 0.74, 2.64, 0.47, 7.93, 2.02, 6.71, 
+  6.63, 7.98, 1.51, 0.02, 4.79, 2.90, 1.52, 4.38, 0.92, 1.60, 0.39, 6.38, 5.90, 8.25, 5.64, 2.18, 7.41, 7.17, 5.78, 2.27, 
+  2.21, 1.36, 7.90, 3.00, 5.41, 8.46, 6.98, 3.58, 2.11, 6.81, 4.09, 3.82, 1.89, 8.67, 8.12, 8.32, 5.91, 4.77, 5.36, 0.82, 
+  4.19, 6.18, 0.63, 6.80, 0.29, 4.46, 0.23, 3.51, 4.40, 0.34, 3.69, 5.76, 0.25, 8.57, 4.86, 0.73, 2.73, 6.52, 6.62, 1.13, 
+  4.98, 2.24, 0.97, 3.26, 0.44, 7.83, 1.30, 7.58, 6.53, 3.02, 4.24, 2.37, 3.09, 7.29, 6.10, 3.06, 3.03, 3.70, 4.19, 0.51, 
+  5.32, 4.38, 3.66, 8.95, 6.72, 2.15, 4.73, 3.03, 2.31, 1.21, 4.92, 6.51, 3.31, 8.50, 0.96, 5.67, 3.57, 1.88, 3.87, 4.72, 
+  1.18, 3.21, 8.93, 6.07, 8.93, 6.49, 4.05, 0.77, 5.55, 1.90, 6.37, 6.64, 7.63, 4.08, 2.85, 8.78, 6.72, 7.18, 4.71, 5.57, 
+  1.04, 6.55, 2.04, 1.49, 1.80, 7.48, 6.69, 1.69, 6.35, 6.05, 7.07, 7.98, 8.67, 5.93, 2.65, 5.59, 1.30, 1.56, 7.17, 0.65, 
+  6.11, 0.72, 7.15, 6.17, 5.74, 8.72, 2.18, 8.09, 6.24, 3.36, 5.42, 6.50, 3.59, 4.98, 0.66, 1.58, 8.81, 2.93, 5.03, 1.67, 
+  4.56, 7.75, 5.87, 5.17, 2.89, 3.15, 3.61, 8.02, 7.61, 7.97, 8.41, 8.84, 4.04, 8.91, 0.46, 2.99, 8.11, 6.46, 6.74, 4.00, 
+  0.06, 3.55, 2.57, 6.34, 4.06, 5.88, 6.95, 4.37, 4.82, 5.04, 4.34, 4.57, 3.91, 3.10, 0.38, 7.07, 7.80, 3.80, 3.74, 7.85, 
+  4.86, 1.46, 0.95, 4.34, 5.36, 1.04, 3.15, 8.69, 2.59, 2.10, 1.39, 5.43, 4.86, 8.50, 7.86, 1.09, 5.88, 7.31, 6.74, 3.26, 
+  3.07, 8.20, 1.86, 5.16, 4.56, 8.77, 8.66, 3.20, 5.65, 7.66, 8.75, 8.21, 3.70, 6.94, 0.57, 7.88, 3.57, 4.35, 5.58, 5.82, 
+  5.02, 2.96, 0.61, 7.97, 4.62, 8.76, 0.06, 4.62, 7.95, 5.07, 6.89, 3.30, 4.56, 7.09, 7.49, 3.45, 5.75, 4.08, 0.66, 0.76, 
+  0.54, 8.40, 8.37, 8.33, 8.66, 0.62, 7.19, 8.88, 7.69, 7.97, 5.41, 3.51, 2.10, 7.15, 1.62, 6.97, 6.22, 6.99, 4.46, 1.26, 
+  2.11, 3.89, 7.03, 3.35, 0.20, 5.89, 6.68, 7.35, 3.86, 1.26, 5.44, 2.84, 3.11, 8.01, 2.86, 2.34, 7.76, 3.40, 4.61, 2.74, 
+  0.63, 0.32, 7.69, 5.20, 4.42, 2.94, 2.73, 3.88, 7.33, 6.39, 3.50, 8.67, 8.72, 3.99, 0.44, 7.49, 2.27, 2.90, 6.68, 1.62, 
+  1.59, 1.05, 4.72, 6.89, 8.58, 6.35, 4.79, 7.25, 0.21, 5.51, 7.63, 3.38, 7.70, 8.75, 0.22, 5.76, 2.87, 6.52, 5.97, 5.83, 
+  2.53, 1.43, 2.65, 7.98, 6.61, 7.81, 4.24, 2.67, 6.07, 4.26, 3.96, 0.05, 1.40, 4.57, 8.55, 5.41, 4.01, 2.00, 7.07, 3.15, 
+  8.50, 1.35, 3.30, 4.00, 5.45, 6.49, 3.07, 8.76, 8.21, 2.90, 3.92, 0.45, 0.71, 6.86, 8.56, 2.15, 0.24, 2.04, 1.81, 1.59, 
+  7.91, 4.06, 7.92, 0.90, 1.29, 0.29, 7.32, 6.95, 4.75, 4.40, 7.18, 1.75, 2.65, 8.71, 2.49, 3.11, 3.72, 1.78, 3.48, 1.05, 
+  2.91, 6.13, 4.85, 4.99, 8.65, 7.88, 0.44, 4.57, 8.09, 4.86, 4.46, 6.88, 7.25, 2.58, 3.89, 7.54, 1.73, 7.44, 7.01, 5.28, 
+  3.24, 3.18, 6.73, 0.10, 6.75, 0.05, 3.68, 5.80, 3.98, 3.32, 0.88, 1.53, 3.24, 4.75, 6.06, 0.63, 7.93, 2.69, 2.71, 2.95, 
+  8.32, 7.47, 7.36, 4.48, 2.20, 8.84, 8.26, 6.43, 5.89, 4.54, 3.66, 4.90, 0.98, 2.74, 4.18, 8.60, 0.78, 7.23, 4.02, 0.25, 
+  4.86, 5.90, 0.26, 4.24, 6.63, 8.48, 5.50, 4.07, 6.06, 2.14, 6.90, 6.43, 3.69, 7.83, 1.68, 4.29, 5.12, 0.40, 8.99, 1.26, 
+  4.11, 4.23, 5.10, 3.68, 6.81, 5.17, 7.91, 0.22, 4.56, 3.32, 3.59, 8.56, 0.99, 5.37, 7.72, 4.65, 4.26, 7.14, 6.63, 6.39, 
+  8.81, 4.78, 3.78, 4.94, 7.70, 1.66, 7.09, 2.06, 6.66, 2.39, 7.28, 4.42, 5.62, 4.36, 0.95, 4.91, 1.39, 4.26, 6.42, 6.02, 
+  2.12, 2.77, 3.02, 4.70, 2.03, 6.72, 1.30, 1.23, 4.92, 3.91, 7.54, 4.11, 3.91, 1.03, 8.75, 2.85, 6.01, 2.74, 7.33, 6.57, 
+  4.85, 6.81, 7.56, 3.65, 0.51, 4.25, 6.83, 4.45, 2.95, 8.94, 3.93, 5.87, 3.18, 1.79, 3.19, 5.84, 0.03, 7.59, 3.11, 8.22, 
+  7.04, 5.70, 1.28, 5.55, 0.86, 6.70, 8.50, 0.79, 1.10, 2.38, 5.23, 6.00, 0.62, 2.08, 0.65, 2.97, 4.94, 5.35, 2.89, 7.20, 
+  0.30, 5.82, 4.06, 1.45, 7.93, 1.99, 7.37, 3.84, 1.96, 1.85, 0.57, 7.74, 0.13, 6.90, 5.50, 3.38, 1.09, 8.68, 8.86, 6.80, 
+  5.15, 3.18, 7.80, 8.61, 4.44, 4.78, 3.25, 2.90, 0.63, 4.98, 0.50, 0.83, 5.07, 5.09, 4.90, 1.51, 1.11, 0.23, 7.47, 7.04, 
+  1.52, 3.58, 5.08, 3.03, 4.31, 2.32, 4.30, 3.51, 6.32, 2.96, 4.00, 4.70, 8.24, 1.06, 4.74, 4.58, 0.28, 3.75, 0.64, 0.83, 
+  2.56, 1.46, 3.26, 3.74, 7.24, 7.57, 5.29, 0.33, 2.22, 7.80, 8.59, 3.31, 7.24, 1.21, 4.77, 2.07, 4.17, 2.34, 0.34, 2.14, 
+  2.19, 7.81, 1.77, 5.69, 2.72, 5.53, 3.01, 2.23, 1.77, 5.35, 8.61, 2.76, 2.97, 1.39, 6.22, 7.26, 4.86, 1.11, 4.27, 3.50, 
+  1.13, 8.77, 1.83, 6.25, 0.74, 3.90, 0.64, 3.35, 1.86, 5.44, 6.19, 1.08, 7.17, 7.30, 6.38, 3.22, 0.89, 8.14, 0.84, 3.39, 
+  2.70, 0.01, 2.69, 1.18, 7.52, 2.25, 6.39, 1.11, 0.05, 4.17, 2.91, 1.88, 3.80, 1.65, 2.33, 4.81, 5.36, 0.28, 8.87, 1.93, 
+  0.45, 8.82, 1.96, 7.40, 6.61, 5.00, 3.26, 2.13, 0.89, 7.30, 8.87, 8.03, 1.63, 3.01, 2.58, 0.30, 1.82, 4.21, 6.46, 1.14, 
+  6.27, 3.68, 8.30, 1.87, 8.34, 7.25, 8.57, 4.98, 3.89, 0.30, 2.37, 6.74, 7.53, 3.36, 3.17, 8.20, 6.20, 7.96, 0.22, 5.00, 
+  8.88, 8.26, 1.56, 3.19, 1.88, 7.51, 5.88, 7.42, 1.14, 6.21, 2.77, 7.24, 3.81, 3.15, 3.83, 3.88, 1.30, 6.81, 8.93, 1.87, 
+  2.73, 7.44, 7.66, 6.16, 5.01, 6.87, 4.81, 1.75, 6.53, 3.97, 7.84, 0.78, 0.43, 7.38, 5.88, 8.11, 4.71, 2.89, 5.04, 8.68, 
+  3.33, 4.24, 2.56, 8.62, 5.56, 0.98, 2.67, 1.10, 1.18, 8.43, 8.44, 7.96, 8.11, 2.07, 5.90, 7.80, 2.27, 0.48, 8.74, 3.78, 
+  7.01, 3.99, 4.11, 0.62, 1.16, 5.62, 3.24, 4.65, 4.75, 4.23, 6.53, 0.94, 7.11, 0.99, 7.49, 0.21, 7.97, 7.12, 4.59, 7.46, 
+  5.23, 7.64, 3.92, 2.63, 4.72, 8.18, 7.26, 8.57, 1.48, 2.33, 8.31, 2.10, 2.96, 5.89, 0.32, 4.06, 7.70, 6.31, 4.64, 4.90, 
+  5.69, 3.12, 7.34, 7.98, 5.49, 8.58, 8.29, 1.39, 7.34, 7.89, 8.95, 6.91, 1.47, 4.33, 6.17, 0.94, 8.49, 0.26, 1.48, 2.98, 
+  1.16, 8.58, 2.18, 3.42, 3.03, 5.48, 1.19, 3.32, 0.79, 6.19, 2.10, 4.12, 2.23, 1.74, 0.66, 8.92, 8.52, 8.71, 8.83, 4.99, 
+  0.30, 5.09, 2.94, 3.88, 0.98, 3.87, 1.61, 7.64, 4.67, 1.45, 0.68, 2.68, 2.11, 8.54, 1.47, 1.47, 3.79, 0.64, 3.30, 7.98, 
+  5.73, 6.61, 3.36, 7.88, 0.24, 4.07, 1.84, 3.92, 5.23, 4.94, 7.33, 0.44, 4.58, 3.36, 6.15, 4.04, 0.42, 2.48, 6.00, 0.45, 
+  5.14, 3.99, 3.48, 4.31, 6.43, 2.15, 3.10, 1.28, 2.61, 6.89, 4.67, 8.81, 2.00, 0.06, 5.74, 7.45, 3.23, 0.50, 4.59, 1.09, 
+  8.87, 5.26, 6.80, 8.29, 0.99, 8.76, 0.31, 6.30, 0.85, 1.89, 3.55, 5.59, 8.96, 8.86, 6.30, 4.51, 0.88, 1.67, 1.40, 0.81, 
+  3.80, 3.06, 7.73, 6.90, 6.21, 3.98, 8.40, 2.45, 1.03, 8.61, 2.44, 5.68, 5.37, 6.93, 0.86, 8.86, 3.68, 2.64, 5.28, 6.03, 
+  1.70, 8.20, 5.19, 4.57, 1.20, 4.73, 7.95, 8.25, 5.50, 8.62, 1.97, 1.76, 8.97, 5.31, 6.38, 0.03, 4.22, 6.69, 8.68, 7.75, 
+  5.73, 8.16, 3.43, 2.52, 3.09, 1.54, 6.63, 8.27, 6.64, 7.74, 4.38, 0.57, 6.10, 6.04, 1.11, 5.16, 8.00, 3.07, 7.45, 3.38, 
+  7.43, 1.98, 1.81, 4.71, 0.69, 8.31, 2.44, 7.29, 2.57, 5.68, 0.83, 8.63, 8.83, 4.45, 2.08, 3.68, 3.74, 0.33, 1.05, 7.60, 
+  4.45, 3.56, 6.84, 5.98, 1.41, 6.91, 5.59, 6.73, 0.88, 3.60, 4.13, 0.43, 5.02, 0.65, 7.65, 6.36, 0.30, 0.75, 6.27, 5.96, 
+  1.11, 3.15, 3.90, 8.16, 3.75, 3.80, 7.60, 8.41, 2.62, 7.76, 3.31, 1.39, 6.29, 5.92, 4.61, 4.02, 4.99, 0.87, 5.01, 3.75, 
+  1.29, 6.95, 8.93, 2.66, 0.16, 2.13, 2.57, 8.23, 2.12, 1.07, 3.66, 5.58, 3.95, 3.73, 1.93, 4.87, 1.46, 0.38, 2.33, 1.33, 
+  0.13, 6.35, 6.61, 5.29, 7.17, 4.86, 3.36, 8.38, 4.20, 0.38, 7.16, 0.52, 7.46, 2.59, 3.99, 5.41, 1.89, 4.45, 4.89, 0.42, 
+  8.76, 5.41, 5.97, 7.37, 5.57, 5.49, 3.36, 8.64, 3.45, 1.23, 1.42, 6.86, 6.40, 6.72, 2.14, 5.12, 6.46, 3.68, 1.75, 7.21, 
+  6.77, 5.45, 2.80, 1.27, 4.44, 3.96, 3.51, 6.59, 5.23, 3.42, 3.23, 1.70, 5.76, 0.87, 3.55, 1.85, 6.27, 2.23, 3.73, 4.86, 
+  3.88, 8.56, 6.85, 1.87, 3.36, 0.96, 5.32, 6.97, 1.62, 6.39, 8.95, 6.83, 3.22, 7.02, 1.46, 2.39, 3.38, 4.91, 8.77, 1.53, 
+  8.29, 1.02, 1.92, 2.90, 1.49, 7.96, 2.33, 4.64, 2.80, 5.95, 4.55, 1.79, 3.08, 4.28, 8.58, 1.65, 7.90, 8.12, 3.27, 8.77, 
+  2.21, 7.21, 1.40, 5.74, 3.74, 1.60, 6.47, 4.96, 2.18, 1.37, 1.52, 7.02, 4.61, 7.11, 5.57, 2.43, 6.27, 8.35, 8.75, 4.68, 
+  8.28, 8.64, 7.53, 8.26, 5.18, 8.79, 6.00, 4.08, 2.34, 5.12, 3.56, 0.92, 1.12, 0.48, 7.82, 6.87, 5.18, 8.16, 1.26, 2.53, 
+  2.22, 6.24, 2.49, 6.63, 4.73, 7.42, 5.95, 8.19, 4.71, 0.84, 7.90, 4.51, 2.33, 0.26, 1.98, 4.54, 0.09, 7.06, 4.68, 8.04, 
+  2.18, 3.78, 4.20, 5.29, 2.11, 1.75, 7.51, 5.05, 5.31, 6.24, 0.91, 7.12, 0.46, 3.58, 6.31, 6.23, 6.09, 5.69, 7.11, 5.57, 
+  2.39, 5.56, 6.89, 8.92, 0.53, 7.04, 8.46, 5.51, 1.66, 2.84, 6.29, 7.11, 0.03, 4.11, 1.84, 8.41, 4.53, 8.15, 1.82, 3.76, 
+  1.39, 2.35, 6.98, 5.55, 1.75, 4.01, 8.50, 1.84, 1.06, 5.12, 7.69, 8.87, 2.68, 7.51, 8.51, 6.84, 0.02, 5.94, 7.76, 0.04, 
+  7.12, 3.27, 0.81, 3.51, 1.89, 3.97, 2.30, 4.96, 8.33, 5.94, 6.94, 7.13, 8.95, 8.61, 0.50, 7.91, 6.39, 3.38, 7.85, 3.67, 
+  5.33, 1.12, 3.62, 6.83, 3.92, 1.23, 5.13, 0.44, 8.46, 3.44, 6.99, 0.63, 3.80, 5.64, 5.98, 6.26, 2.54, 1.77, 6.31, 7.47, 
+  3.32, 7.44, 3.93, 5.21, 1.80, 5.62, 0.31, 8.35, 8.95, 6.68, 1.99, 8.40, 7.50, 3.21, 1.90, 0.49, 7.76, 1.78, 1.80, 0.47, 
+  3.13, 8.55, 0.10, 5.35, 5.03, 4.46, 1.02, 4.60, 8.33, 1.67, 6.42, 4.28, 5.65, 0.04, 7.97, 6.39, 7.31, 6.60, 6.58, 2.14, 
+  8.33, 0.22, 3.22, 0.78, 1.89, 5.20, 0.73, 7.29, 2.80, 4.03, 5.69, 5.93, 0.39, 8.05, 2.47, 6.95, 7.35, 0.68, 6.57, 6.73, 
+  8.11, 2.80, 4.33, 0.74, 6.57, 5.65, 4.87, 0.22, 5.99, 6.76, 0.65, 4.87, 2.07, 7.03, 2.56, 2.40, 5.68, 2.69, 7.91, 4.37, 
+  4.45, 7.04, 8.71, 3.91, 1.32, 7.01, 6.87, 4.28, 3.94, 4.31, 4.90, 8.65, 0.47, 8.88, 3.32, 8.68, 4.46, 7.23, 6.84, 3.35, 
+  4.20, 6.98, 1.04, 2.04, 0.92, 0.53, 8.13, 5.76, 6.24, 3.75, 7.38, 0.19, 7.08, 4.89, 8.39, 7.71, 2.60, 8.54, 4.64, 6.93, 
+  0.32, 3.17, 6.35, 1.42, 5.18, 4.04, 2.99, 2.15, 3.02, 3.67, 2.54, 8.83, 1.24, 3.63, 4.74, 8.82, 0.65, 0.44, 4.70, 0.57, 
+  0.69, 5.82, 0.15, 0.35, 1.40, 6.57, 4.06, 7.20, 0.70, 4.83, 0.09, 6.14, 5.26, 5.93, 1.06, 7.57, 4.96, 2.86, 5.27, 1.34, 
+  2.84, 3.89, 8.29, 0.52, 3.61, 7.73, 2.81, 6.06, 1.09, 8.96, 5.51, 2.32, 1.81, 1.97, 2.37, 2.69, 3.04, 4.26, 4.17, 2.45, 
+  7.29, 6.36, 0.20, 1.94, 6.02, 6.41, 2.91, 2.74, 6.39, 3.74, 4.63, 5.80, 4.10, 5.21, 4.63, 5.92, 5.54, 3.38, 7.11, 4.56, 
+  0.50, 3.17, 7.36, 2.07, 1.08, 7.30, 0.71, 3.61, 2.46, 6.80, 0.04, 3.61, 3.87, 1.45, 6.50, 5.55, 8.74, 4.11, 5.72, 1.66, 
+  4.20, 7.43, 7.56, 1.93, 2.58, 0.90, 1.07, 7.09, 7.79, 7.31, 7.42, 3.63, 1.09, 1.70, 1.97, 8.52, 6.04, 6.67, 8.94, 6.67, 
+  7.11, 3.40, 4.63, 6.00, 6.69, 7.99, 0.29, 8.03, 0.13, 0.03, 4.71, 2.32, 1.65, 1.87, 0.35, 8.66, 5.94, 8.11, 4.11, 6.96, 
+  2.65, 4.82, 2.65, 5.80, 7.83, 7.64, 7.48, 2.28, 7.89, 3.63, 0.83, 6.41, 4.72, 1.64, 3.77, 3.51, 7.91, 1.48, 2.05, 5.19, 
+  1.45, 3.65, 2.20, 4.38, 6.33, 3.25, 0.03, 8.43, 7.18, 7.90, 5.49, 7.77, 6.25, 4.90, 7.50, 6.93, 2.55, 7.72, 3.38, 0.49, 
+  5.35, 8.60, 7.23, 1.47, 1.00, 4.65, 8.53, 4.17, 0.02, 7.24, 7.08, 6.71, 7.67, 6.29, 6.57, 2.87, 1.11, 0.37, 8.61, 6.40, 
+  5.43, 4.63, 8.75, 0.83, 3.09, 7.61, 7.14, 6.41, 1.20, 0.71, 2.50, 6.56, 3.72, 2.35, 8.45, 0.91, 5.49, 8.68, 1.84, 3.08, 
+  2.46, 5.97, 4.48, 2.58, 0.88, 1.59, 6.45, 2.12, 7.31, 0.13, 5.60, 1.90, 1.92, 6.56, 3.95, 3.54, 0.80, 0.73, 4.34, 1.72, 
+  5.47, 1.08, 8.39, 7.27, 7.25, 0.68, 8.86, 5.75, 1.68, 2.72, 4.38, 2.47, 0.58, 3.50, 7.27, 3.72, 2.05, 8.35, 1.21, 4.91, 
+  6.25, 3.44, 5.69, 7.16, 7.24, 8.70, 7.70, 8.59, 6.20, 3.62, 5.75, 3.20, 1.56, 8.95, 1.88, 8.04, 4.72, 4.35, 5.75, 1.91, 
+  0.39, 6.55, 7.78, 7.12, 3.73, 3.76, 3.83, 3.90, 7.91, 5.52, 6.62, 3.97, 6.91, 1.24, 1.80, 5.25, 5.86, 4.90, 6.44, 7.46, 
+  3.57, 5.36, 1.42, 6.07, 6.29, 0.21, 1.94, 7.53, 2.31, 5.30, 5.44, 0.19, 5.42, 2.95, 8.93, 3.94, 6.74, 2.08, 1.60, 6.86, 
+  2.15, 4.54, 8.83, 2.57, 7.90, 8.84, 0.25, 0.33, 3.85, 2.22, 0.96, 7.22, 7.16, 4.14, 0.62, 0.70, 7.34, 8.96, 2.70, 1.40, 
+  4.64, 4.11, 5.66, 6.68, 8.36, 7.17, 1.68, 6.85, 7.51, 7.68, 0.95, 1.74, 4.87, 6.84, 1.55, 1.53, 6.74, 3.48, 4.31, 7.05, 
+  6.90, 1.54, 8.13, 4.43, 8.04, 3.92, 6.91, 3.17, 4.89, 5.17, 2.83, 6.40, 7.20, 2.64, 7.13, 4.31, 3.82, 3.65, 6.70, 4.90, 
+  8.99, 5.44, 7.42, 3.72, 7.28, 8.67, 7.55, 6.36, 2.24, 8.15, 8.87, 6.32, 0.56, 7.36, 1.97, 6.46, 4.04, 4.24, 4.37, 6.97, 
+  1.40, 8.61, 1.11, 5.65, 8.87, 8.03, 0.42, 8.71, 6.69, 2.02, 4.64, 2.64, 5.25, 0.88, 1.07, 6.89, 7.59, 8.08, 3.32, 0.69, 
+  8.31, 6.68, 6.49, 2.25, 4.78, 3.99, 0.86, 0.96, 5.10, 1.43, 0.23, 0.11, 2.67, 6.97, 3.22, 4.23, 8.78, 2.87, 0.11, 0.26, 
+  8.85, 5.30, 6.52, 8.74, 5.97, 4.47, 7.20, 2.46, 4.25, 5.29, 8.03, 2.97, 6.87, 5.05, 4.57, 0.37, 4.59, 5.81, 4.10, 8.57, 
+  4.78, 0.96, 6.62, 2.32, 3.14, 2.33, 3.89, 5.94, 5.43, 7.67, 0.09, 2.47, 1.02, 7.42, 0.36, 8.85, 0.05, 0.10, 7.28, 8.11, 
+  0.37, 5.14, 3.77, 8.37, 2.07, 4.95, 8.90, 6.06, 0.15, 1.93, 2.66, 2.98, 8.05, 5.07, 6.60, 5.64, 0.50, 5.79, 7.17, 1.38, 
+  7.03, 1.52, 3.19, 0.56, 5.88, 1.90, 8.08, 3.72, 2.51, 5.83, 5.08, 0.65, 1.41, 3.97, 1.95, 5.02, 4.80, 6.62, 0.35, 7.29, 
+  5.00, 2.05, 1.19, 4.11, 7.30, 2.66, 3.51, 7.14, 3.45, 7.41, 4.02, 3.28, 8.06, 7.07, 8.07, 6.27, 5.45, 1.85, 0.64, 4.57, 
+  4.70, 1.93, 5.13, 3.92, 6.10, 5.60, 4.06, 1.37, 1.38, 4.90, 3.85, 4.61, 1.56, 3.51, 6.31, 2.62, 5.65, 6.45, 0.49, 7.97, 
+  5.82, 2.34, 6.16, 2.99, 4.17, 6.70, 7.28, 7.95, 5.71, 8.20, 4.43, 3.71, 7.63, 5.14, 2.37, 7.97, 8.65, 3.62, 0.56, 1.90, 
+  5.52, 5.59, 6.68, 7.29, 6.85, 5.69, 8.10, 3.69, 6.46, 2.30, 0.29, 5.66, 7.83, 1.27, 1.14, 1.37, 0.22, 4.99, 5.66, 3.93, 
+  4.48, 7.18, 2.91, 1.41, 3.71, 1.14, 1.10, 7.41, 3.19, 1.97, 8.15, 3.07, 4.59, 7.97, 4.91, 4.85, 5.53, 8.60, 8.89, 0.95, 
+  5.13, 8.91, 7.27, 6.57, 3.67, 7.07, 8.66, 5.77, 2.65, 3.40, 4.94, 2.09, 6.57, 6.03, 2.52, 8.00, 5.60, 5.35, 0.12, 6.07, 
+  8.45, 1.70, 1.19, 0.47, 7.02, 7.67, 7.12, 3.71, 2.12, 4.70, 0.23, 6.80, 1.13, 4.67, 4.77, 4.75, 7.33, 2.72, 4.15, 2.38, 
+  5.10, 4.23, 8.58, 3.67, 5.12, 7.99, 1.79, 3.29, 5.38, 8.91, 7.17, 5.95, 4.69, 8.01, 7.40, 7.28, 2.08, 1.69, 4.45, 3.23, 
+  3.53, 0.07, 5.23, 3.83, 3.26, 0.80, 6.63, 7.90, 8.66, 4.49, 6.61, 2.77, 3.20, 7.78, 1.93, 7.40, 1.23, 7.54, 7.75, 6.10, 
+  7.97, 7.96, 1.60, 7.29, 7.91, 3.56, 7.82, 2.91, 2.81, 4.78, 5.76, 0.85, 3.80, 1.70, 6.03, 6.59, 1.21, 8.72, 2.94, 2.68, 
+  3.66, 0.30, 6.69, 2.71, 2.71, 2.86, 6.51, 6.81, 7.85, 5.84, 0.58, 2.22, 3.77, 8.14, 7.31, 2.05, 2.28, 4.98, 1.03, 0.99, 
+  1.26, 4.95, 3.18, 8.57, 7.09, 7.12, 8.55, 8.61, 2.32, 0.72, 7.17, 3.22, 0.08, 7.44, 5.00, 6.19, 2.83, 4.43, 1.70, 7.83, 
+  1.92, 1.50, 8.48, 0.47, 6.59, 4.34, 5.89, 5.48, 0.80, 4.70, 6.58, 2.48, 6.96, 2.36, 2.79, 8.70, 7.93, 5.25, 1.56, 3.61, 
+  7.65, 7.82, 6.41, 2.91, 7.18, 6.47, 7.70, 6.77, 8.84, 3.58, 1.58, 3.61, 4.72, 1.53, 4.83, 1.09, 3.77, 7.73, 5.07, 0.08, 
+  0.28, 4.94, 7.70, 5.15, 6.61, 5.32, 3.66, 1.77, 0.74, 6.51, 7.90, 8.99, 8.21, 3.88, 3.94, 0.40, 0.86, 3.38, 6.35, 7.12, 
+  1.89, 0.69, 7.99, 5.62, 2.48, 7.58, 5.57, 2.34, 7.63, 2.98, 1.37, 7.74, 1.52, 0.06, 4.27, 6.26, 7.11, 1.65, 6.04, 2.77, 
+  0.58, 3.14, 3.02, 1.61, 1.52, 8.03, 1.02, 0.88, 7.93, 4.00, 4.95, 4.80, 1.15, 4.91, 1.95, 4.99, 4.32, 4.41, 6.85, 0.41, 
+  1.11, 6.84, 8.05, 2.11, 4.74, 6.03, 5.02, 7.47, 8.73, 4.27, 3.87, 3.62, 3.11, 3.85, 6.73, 8.75, 1.40, 0.29, 7.93, 1.64, 
+  3.67, 8.66, 4.29, 7.35, 2.10, 8.87, 0.27, 8.09, 3.30, 4.63, 5.91, 0.48, 2.66, 2.80, 4.27, 3.26, 7.25, 2.28, 3.95, 4.02, 
+  7.57, 8.97, 6.51, 0.85, 0.92, 7.64, 6.25, 3.34, 4.99, 1.43, 3.31, 6.78, 0.68, 0.15, 6.54, 4.59, 7.18, 1.56, 6.34, 2.37, 
+  2.86, 5.65, 6.24, 3.14, 7.42, 4.20, 3.49, 3.62, 3.42, 1.72, 4.09, 3.17, 0.33, 8.51, 8.70, 7.60, 1.94, 6.92, 7.44, 8.53, 
+  7.03, 2.13, 3.64, 8.30, 4.89, 5.81, 4.06, 6.16, 4.57, 1.60, 8.34, 5.44, 0.39, 2.95, 6.95, 1.97, 2.62, 2.41, 7.19, 4.06, 
+  4.85, 6.02, 7.41, 8.90, 0.24, 8.97, 7.86, 4.79, 5.25, 1.83, 7.32, 6.32, 7.40, 2.34, 0.10, 5.32, 0.94, 0.02, 6.48, 0.32, 
+  3.35, 2.63, 6.52, 8.43, 0.16, 5.53, 3.43, 1.45, 3.23, 7.38, 5.75, 7.34, 8.84, 8.15, 7.04, 8.80, 1.30, 3.26, 5.50, 2.62, 
+  6.08, 7.89, 4.86, 1.65, 2.89, 7.95, 5.57, 7.66, 2.67, 6.81, 7.05, 5.05, 7.82, 2.06, 6.86, 2.53, 1.41, 8.61, 8.23, 1.02, 
+  8.88, 0.39, 8.64, 4.76, 5.01, 6.19, 8.72, 8.28, 7.75, 0.98, 2.00, 5.26, 3.03, 2.82, 4.99, 7.59, 8.26, 2.64, 4.98, 5.55, 
+  7.01, 6.81, 5.19, 4.30, 3.07, 4.95, 7.88, 7.87, 6.73, 4.69, 2.21, 8.50, 8.02, 6.06, 4.86, 1.02, 2.31, 1.35, 0.52, 3.98, 
+  2.76, 6.49, 2.59, 4.84, 7.59, 1.65, 6.84, 5.86, 7.49, 3.02, 6.80, 4.71, 3.97, 8.38, 4.34, 3.58, 5.86, 3.29, 7.82, 5.61, 
+  5.70, 5.68, 4.92, 1.70, 2.30, 4.60, 6.57, 5.41, 4.18, 7.28, 5.77, 4.48, 0.43, 8.22, 7.59, 4.60, 1.89, 8.09, 3.29, 8.55, 
+  6.32, 8.03, 6.88, 0.60, 7.01, 4.08, 3.03, 6.77, 0.68, 2.34, 4.93, 7.23, 5.75, 4.46, 3.25, 0.24, 6.24, 8.32, 5.07, 7.18, 
+  3.97, 7.57, 3.29, 8.22, 1.00, 6.25, 4.85, 8.42, 6.70, 4.08, 0.72, 5.14, 6.06, 4.56, 8.48, 8.93, 4.57, 1.26, 6.22, 4.14, 
+  4.15, 4.45, 0.14, 0.16, 2.30, 1.54, 8.33, 4.74, 4.18, 5.41, 0.90, 7.22, 0.67, 5.60, 2.81, 1.63, 2.34, 6.12, 0.57, 3.51, 
+  7.67, 4.73, 5.04, 1.71, 6.57, 2.33, 8.57, 8.47, 3.90, 1.06, 2.85, 7.69, 5.55, 3.88, 1.88, 3.63, 5.13, 7.09, 6.66, 1.14, 
+  8.37, 4.93, 0.34, 6.92, 7.81, 4.53, 5.70, 4.66, 4.63, 5.92, 7.19, 8.34, 0.87, 7.32, 0.93, 8.45, 2.60, 8.05, 4.39, 3.06, 
+  5.11, 6.50, 8.71, 7.69, 8.70, 2.12, 6.18, 0.68, 4.00, 0.15, 3.49, 3.34, 2.40, 3.05, 5.04, 8.37, 1.66, 7.61, 3.93, 1.37, 
+  8.34, 3.59, 6.69, 5.90, 4.49, 5.74, 5.38, 2.43, 0.28, 1.76, 2.21, 4.85, 4.51, 5.94, 3.50, 3.49, 4.06, 7.22, 6.10, 7.58, 
+  8.54, 7.08, 5.48, 8.05, 3.90, 5.62, 3.93, 7.71, 6.69, 2.71, 8.26, 7.91, 5.50, 6.52, 6.08, 5.13, 0.86, 7.04, 6.45, 0.55, 
+  8.91, 5.51, 1.44, 1.89, 0.13, 3.72, 5.13, 0.58, 6.05, 8.57, 3.25, 1.39, 0.35, 2.35, 5.60, 5.91, 3.36, 7.84, 3.44, 8.80, 
+  3.23, 3.13, 6.68, 7.68, 0.10, 7.32, 5.08, 5.65, 6.71, 5.30, 3.29, 8.81, 8.03, 1.20, 7.87, 8.84, 8.59, 8.10, 2.37, 0.88, 
+  2.67, 7.82, 3.72, 2.77, 4.43, 0.43, 6.25, 3.90, 4.39, 3.35, 5.87, 3.14, 8.42, 0.64, 6.14, 5.77, 3.83, 6.95, 2.15, 0.70, 
+  1.68, 2.76, 3.40, 0.76, 6.62, 3.76, 4.25, 3.05, 3.09, 3.40, 6.60, 4.32, 6.33, 7.05, 7.16, 8.10, 0.72, 6.12, 8.65, 4.89, 
+  3.05, 4.46, 8.11, 5.97, 6.38, 1.72, 4.51, 4.64, 7.10, 4.01, 2.71, 0.38, 3.04, 6.09, 4.15, 6.33, 5.74, 1.49, 4.07, 6.79, 
+  6.81, 5.44, 6.94, 3.63, 7.95, 8.27, 7.13, 4.80, 0.06, 2.93, 4.51, 7.55, 5.54, 1.64, 2.53, 4.71, 6.71, 3.16, 0.73, 0.04, 
+  6.17, 4.31, 2.64, 3.08, 7.70, 7.10, 3.54, 4.74, 8.21, 6.73, 8.62, 0.78, 8.41, 2.18, 8.57, 8.38, 5.29, 6.06, 2.74, 6.94, 
+  5.28, 6.87, 5.89, 8.47, 3.08, 6.29, 7.17, 8.62, 6.09, 5.84, 7.35, 6.21, 5.71, 5.72, 0.98, 5.23, 8.48, 1.50, 4.23, 8.78, 
+  3.72, 0.71, 2.30, 2.01, 5.84, 4.66, 1.28, 8.33, 6.58, 0.56, 3.50, 3.03, 1.57, 5.42, 5.36, 6.52, 3.13, 5.77, 8.14, 1.65, 
+  6.29, 3.74, 2.15, 2.30, 5.46, 3.18, 5.97, 4.24, 3.61, 1.07, 1.80, 7.28, 1.05, 6.72, 4.12, 8.71, 7.47, 1.12, 2.36, 1.93, 
+  0.31, 3.65, 0.41, 5.17, 3.11, 6.74, 1.38, 0.45, 8.72, 1.64, 3.33, 5.62, 7.32, 2.26, 8.15, 7.04, 7.21, 5.10, 7.24, 3.69, 
+  8.46, 2.98, 2.26, 8.90, 8.67, 3.46, 4.56, 1.64, 8.33, 3.49, 2.60, 0.19, 8.39, 2.36, 2.33, 1.31, 2.95, 1.13, 7.96, 6.80, 
+  0.14, 5.15, 3.31, 1.63, 2.87, 2.73, 4.78, 2.70, 6.05, 6.87, 4.29, 2.83, 6.54, 6.37, 5.83, 7.07, 8.44, 2.68, 3.57, 1.64, 
+  4.70, 5.98, 4.69, 5.66, 6.45, 5.65, 2.63, 8.92, 6.14, 5.82, 3.53, 7.97, 8.88, 8.05, 7.50, 6.69, 5.05, 7.23, 3.37, 5.22, 
+  1.81, 2.70, 1.29, 6.29, 1.77, 4.26, 1.94, 1.27, 3.73, 3.11, 5.90, 3.36, 1.95, 0.04, 0.77, 2.81, 8.44, 3.29, 1.99, 4.78, 
+  2.11, 3.89, 8.09, 1.62, 4.74, 0.54, 0.60, 8.61, 8.23, 7.62, 7.82, 1.71, 3.76, 8.72, 3.97, 0.01, 0.99, 4.62, 2.51, 2.50, 
+  6.63, 0.52, 0.61, 1.33, 6.57, 0.52, 6.24, 4.54, 0.48, 8.05, 6.54, 1.04, 2.27, 2.51, 0.61, 7.30, 1.24, 0.58, 5.25, 2.19, 
+  0.33, 3.82, 4.56, 7.07, 1.66, 7.24, 0.95, 1.48, 7.66, 8.71, 5.47, 5.04, 0.53, 0.16, 5.92, 0.20, 2.48, 2.05, 5.87, 1.98, 
+  2.97, 1.20, 1.21, 6.64, 7.91, 3.46, 0.67, 3.25, 1.30, 4.35, 1.99, 0.58, 3.19, 6.38, 8.77, 5.95, 1.87, 1.38, 1.15, 4.18, 
+  8.93, 0.70, 5.51, 5.43, 3.85, 4.35, 8.22, 0.29, 1.61, 0.75, 1.11, 6.60, 8.91, 6.17, 6.38, 8.80, 7.33, 2.77, 8.32, 0.62, 
+  8.16, 2.07, 4.37, 3.94, 7.29, 5.22, 4.84, 4.92, 2.93, 8.86, 1.58, 5.34, 0.84, 2.54, 7.11, 5.71, 1.16, 2.43, 2.36, 3.33, 
+  6.74, 0.14, 5.69, 4.44, 5.51, 2.49, 1.67, 1.95, 2.18, 1.78, 0.28, 2.75, 2.49, 4.93, 1.46, 6.35, 7.69, 3.70, 6.03, 5.91, 
+  0.19, 4.10, 2.28, 8.81, 6.82, 5.00, 3.79, 0.95, 2.35, 7.80, 7.23, 2.53, 3.49, 1.26, 7.42, 2.73, 7.01, 4.01, 5.11, 0.74, 
+  0.14, 2.35, 0.27, 2.82, 2.83, 2.43, 1.42, 4.95, 6.19, 0.94, 8.47, 8.89, 1.82, 6.48, 5.60, 3.39, 8.50, 0.12, 4.66, 4.93, 
+  5.27, 7.40, 2.54, 1.82, 8.72, 4.14, 4.30, 6.67, 8.83, 4.33, 1.47, 1.42, 0.75, 4.30, 7.71, 1.75, 2.23, 2.82, 5.51, 2.35, 
+  6.80, 3.29, 1.35, 7.79, 2.04, 9.00, 8.63, 6.18, 4.63, 6.71, 0.14, 6.20, 5.42, 3.27, 2.88, 1.37, 4.01, 2.44, 6.82, 7.46, 
+  6.86, 5.52, 7.89, 8.40, 1.56, 5.17, 0.56, 1.27, 6.19, 3.93, 2.21, 2.24, 4.42, 2.18, 6.37, 6.69, 1.57, 8.01, 7.02, 0.37, 
+  0.39, 8.27, 2.03, 7.28, 8.06, 2.47, 7.99, 3.42, 6.54, 7.36, 6.56, 8.66, 1.07, 4.01, 6.71, 0.13, 6.50, 2.19, 3.49, 8.30, 
+  0.78, 2.09, 8.68, 7.37, 2.77, 8.14, 2.45, 2.26, 3.35, 8.35, 0.85, 1.18, 7.86, 1.08, 4.73, 3.15, 6.44, 0.22, 0.35, 2.22, 
+  7.12, 1.82, 1.00, 0.70, 1.36, 5.86, 6.62, 5.14, 0.49, 5.51, 5.27, 5.58, 4.07, 3.48, 6.40, 1.61, 7.57, 6.07, 5.66, 4.39, 
+  1.53, 3.64, 2.99, 7.03, 3.80, 8.52, 2.77, 7.02, 7.34, 1.26, 7.92, 3.37, 0.53, 4.86, 2.63, 0.71, 8.67, 8.16, 7.00, 0.40, 
+  7.36, 8.68, 4.40, 5.54, 2.76, 1.56, 5.10, 6.40, 4.02, 2.82, 7.46, 5.20, 8.64, 3.86, 4.48, 7.09, 6.60, 7.73, 1.61, 6.32, 
+  4.88, 7.48, 7.26, 0.32, 0.02, 3.32, 5.25, 4.58, 7.29, 0.72, 0.51, 0.90, 5.91, 6.36, 3.01, 7.41, 8.12, 1.89, 0.97, 4.39, 
+  8.43, 4.94, 5.15, 4.17, 4.14, 2.17, 5.32, 8.89, 2.61, 2.41, 3.60, 1.93, 1.52, 7.84, 8.76, 7.15, 0.22, 2.73, 6.56, 4.22, 
+  4.47, 6.05, 4.98, 7.50, 1.37, 5.31, 3.01, 1.58, 6.13, 4.11, 0.00, 0.35, 5.22, 7.75, 7.54, 8.57, 2.07, 6.96, 2.46, 5.36, 
+  0.55, 7.94, 5.28, 4.65, 4.36, 6.48, 0.24, 3.59, 5.11, 8.51, 5.98, 7.19, 0.30, 4.54, 7.53, 1.99, 8.93, 1.64, 4.47, 3.24, 
+  8.91, 4.19, 7.77, 3.28, 3.05, 4.63, 6.94, 0.15, 4.03, 4.23, 7.02, 7.02, 7.34, 2.75, 5.90, 7.02, 5.68, 8.09, 0.71, 8.29, 
+  4.41, 0.37, 4.75, 4.43, 4.73, 5.91, 0.89, 7.46, 3.70, 5.24, 6.25, 7.23, 0.32, 7.96, 3.26, 1.87, 3.29, 7.51, 7.34, 3.10, 
+  8.45, 3.08, 0.74, 4.41, 6.03, 7.89, 0.17, 2.22, 1.69, 5.57, 8.44, 1.35, 6.07, 7.95, 8.24, 3.38, 2.99, 5.87, 4.04, 6.86, 
+  7.79, 3.54, 8.91, 8.16, 0.93, 1.87, 5.08, 5.09, 6.72, 6.74, 0.88, 1.16, 3.99, 2.60, 2.80, 4.86
+};
+
+float verify_data[ARRAY_SIZE] = 
+{
+  1354.01, 1395.87, 1543.01, 1599.53, 1344.29, 1352.43, 1217.77, 1342.96, 1258.09, 1233.96, 1257.44, 1240.52, 1417.05, 1133.66, 1303.01, 1394.43, 1397.95, 1498.21, 1297.75, 1314.17, 
+  1267.56, 1570.65, 1350.75, 1214.41, 1293.15, 1281.52, 1383.14, 1328.95, 1376.30, 1474.75, 1233.98, 1467.32, 1385.80, 1516.00, 1383.32, 1498.40, 1349.81, 1387.99, 1407.33, 1276.53, 
+  1346.93, 1398.80, 1512.83, 1286.52, 1361.78, 1434.00, 1346.92, 1349.11, 1168.83, 1159.40, 1665.83, 1344.38, 1467.49, 1415.67, 1419.02, 1570.37, 1301.99, 1414.36, 1520.39, 1306.54, 
+  1094.96, 1373.59, 1448.26, 1375.64, 1258.80, 1185.72, 1350.71, 1563.55, 1316.17, 1301.19, 1161.06, 1230.95, 1212.56, 1154.43, 1151.65, 1135.04, 1347.27, 1181.36, 1228.32, 1167.81, 
+  1156.78, 1400.19, 1281.56, 1208.90, 1142.65, 1360.37, 1253.98, 1222.83, 1280.18, 1338.35, 1283.13, 1329.33, 1251.23, 1359.60, 1233.32, 1306.39, 1272.46, 1390.59, 1328.05, 1409.97, 
+  1267.51, 1339.74, 1282.41, 1220.99, 1298.74, 1220.26, 1411.56, 1343.96, 1225.86, 1372.56, 1276.61, 1267.04, 1131.05, 1256.09, 1469.12, 1268.12, 1476.59, 1405.91, 1301.43, 1389.66, 
+  1273.65, 1288.05, 1571.70, 1269.64, 1112.05, 1363.37, 1378.76, 1304.14, 1396.36, 1336.56, 1370.00, 1644.75, 1315.29, 1396.68, 1281.25, 1262.70, 1299.40, 1249.69, 1175.23, 1181.40, 
+  1454.54, 1216.33, 1207.56, 1376.62, 1143.42, 1534.02, 1401.90, 1323.66, 1178.84, 1410.94, 1260.04, 1289.08, 1394.97, 1377.33, 1317.83, 1439.55, 1349.56, 1435.91, 1333.42, 1428.67, 
+  1296.20, 1504.97, 1349.81, 1435.84, 1453.81, 1455.28, 1336.01, 1281.53, 1344.39, 1378.58, 1520.28, 1362.65, 1349.20, 1461.86, 1258.32, 1233.64, 1244.44, 1205.92, 1618.34, 1355.04, 
+  1562.53, 1473.65, 1461.36, 1521.75, 1228.12, 1506.90, 1493.48, 1374.98, 1185.69, 1493.79, 1345.46, 1369.70, 1161.75, 1116.09, 1290.69, 1477.64, 1140.02, 1264.17, 1074.87, 1269.37, 
+  1056.11, 1127.10, 1090.32, 1055.62, 1302.05, 1118.96, 1092.37, 1273.94, 1075.51, 1266.97, 1125.54, 1136.88, 1098.92, 1359.13, 1142.29, 1101.04, 1308.78, 1291.21, 1182.88, 1179.02, 
+  1114.94, 1287.37, 1059.56, 1279.27, 1250.69, 1275.44, 1288.61, 1145.96, 1235.53, 1291.31, 1188.66, 1052.27, 1174.23, 1190.70, 1397.36, 1275.87, 1317.88, 1243.39, 1131.48, 1260.10, 
+  1192.54, 1178.11, 1432.50, 1106.75, 1343.19, 1255.30, 1263.46, 1388.74, 1137.68, 1257.01, 1350.52, 1180.76, 1066.27, 1314.34, 1193.60, 1265.57, 1210.52, 1183.99, 1230.33, 1387.46, 
+  1151.10, 1077.39, 1149.84, 1215.06, 1119.25, 1199.23, 977.74, 1111.13, 1335.71, 1168.84, 1036.50, 1005.27, 1178.64, 1275.66, 1208.78, 1075.36, 1100.36, 1163.28, 1075.87, 1190.77, 
+  1176.13, 1074.33, 1152.84, 1062.11, 1314.44, 1298.88, 1192.93, 1199.16, 1043.27, 1263.14, 1123.87, 1159.83, 1233.00, 1222.81, 1054.01, 1078.97, 1233.10, 1122.61, 1260.10, 1132.02, 
+  1169.08, 1203.75, 1166.90, 1081.17, 1092.89, 1127.70, 1311.74, 1267.25, 1353.53, 1251.22, 1208.01, 1377.83, 1170.55, 1183.10, 1210.08, 1079.78, 1022.47, 1267.79, 1280.86, 1107.99, 
+  1220.63, 1231.38, 1297.16, 1349.99, 1132.89, 1057.39, 1167.18, 1238.74, 1058.25, 1242.15, 966.69, 1056.35, 1312.60, 1080.69, 1157.51, 1057.53, 1096.31, 1256.06, 1222.67, 1225.06, 
+  1084.64, 1147.07, 1166.91, 1215.04, 1214.49, 1119.43, 1151.76, 1214.63, 1167.99, 1353.90, 1138.60, 1258.90, 1082.25, 1209.09, 1209.70, 1129.26, 1276.81, 1264.27, 1085.23, 927.81, 
+  1128.21, 1080.52, 1231.94, 1182.54, 1235.60, 1292.99, 1235.59, 1127.82, 1124.34, 1079.43, 1432.82, 1249.15, 1327.01, 1301.50, 1246.96, 1376.32, 1061.28, 1204.55, 1329.92, 1103.78, 
+  931.53, 1368.76, 1190.03, 1163.34, 1396.89, 1433.26, 1527.05, 1598.78, 1278.53, 1415.12, 1430.83, 1481.94, 1199.17, 1329.99, 1335.39, 1231.51, 1470.62, 1375.58, 1375.26, 1395.02, 
+  1399.26, 1608.00, 1308.94, 1431.51, 1243.43, 1463.41, 1403.81, 1364.34, 1434.32, 1417.88, 1495.77, 1363.22, 1464.28, 1487.78, 1364.68, 1381.91, 1349.18, 1528.36, 1396.53, 1392.29, 
+  1414.73, 1422.36, 1300.79, 1310.37, 1443.54, 1385.04, 1608.70, 1404.34, 1432.32, 1504.10, 1442.82, 1397.85, 1334.88, 1305.33, 1663.19, 1432.12, 1613.45, 1523.58, 1466.45, 1595.38, 
+  1366.08, 1411.41, 1496.29, 1258.22, 1156.74, 1532.48, 1488.98, 1406.65, 1397.03, 1292.21, 1440.31, 1634.74, 1358.90, 1495.89, 1347.00, 1449.85, 1225.68, 1390.38, 1157.20, 1369.11, 
+  1596.16, 1259.06, 1245.06, 1294.82, 1291.60, 1576.38, 1369.14, 1234.77, 1202.91, 1557.84, 1329.85, 1203.48, 1415.17, 1392.83, 1405.60, 1427.19, 1375.85, 1442.91, 1349.33, 1454.88, 
+  1281.60, 1469.46, 1358.83, 1380.14, 1363.64, 1431.13, 1262.43, 1334.68, 1399.66, 1290.28, 1658.62, 1332.18, 1351.59, 1357.42, 1313.97, 1315.74, 1291.34, 1297.74, 1686.54, 1265.94, 
+  1589.24, 1458.80, 1414.98, 1572.02, 1366.07, 1427.09, 1438.33, 1344.23, 1277.32, 1518.03, 1472.18, 1351.37, 1392.20, 1374.39, 1377.64, 1568.39, 1282.97, 1253.27, 1246.33, 1311.90, 
+  1251.72, 1266.76, 1139.97, 1291.31, 1397.95, 1124.47, 1260.95, 1227.31, 1269.12, 1472.09, 1282.62, 1179.06, 1169.98, 1488.49, 1313.12, 1263.70, 1286.53, 1276.45, 1351.07, 1313.12, 
+  1345.65, 1366.31, 1250.39, 1330.61, 1358.94, 1406.88, 1390.62, 1382.66, 1355.59, 1434.79, 1347.25, 1215.57, 1313.64, 1212.06, 1420.40, 1374.99, 1314.28, 1419.94, 1318.03, 1268.17, 
+  1195.18, 1278.23, 1604.11, 1276.18, 1558.91, 1450.96, 1279.83, 1608.46, 1258.74, 1380.00, 1459.37, 1229.32, 1127.80, 1465.53, 1372.71, 1288.84, 1245.17, 1363.43, 1340.75, 1485.38, 
+  1282.79, 1323.81, 1342.04, 1389.78, 1172.57, 1267.06, 1203.23, 1199.95, 1461.08, 1151.50, 1148.56, 1246.64, 1194.17, 1419.16, 1151.19, 1225.54, 1172.39, 1268.26, 1279.08, 1214.26, 
+  1226.21, 1323.91, 1293.96, 1211.01, 1359.67, 1416.99, 1218.85, 1342.10, 1183.49, 1412.17, 1238.21, 1387.83, 1378.53, 1284.84, 1299.25, 1096.53, 1269.18, 1288.36, 1405.23, 1299.46, 
+  1245.22, 1327.05, 1261.93, 1215.82, 1264.44, 1239.77, 1552.56, 1296.11, 1442.32, 1384.22, 1359.94, 1383.29, 1203.91, 1374.08, 1441.88, 1189.57, 1146.06, 1315.69, 1348.47, 1322.45, 
+  1128.66, 1214.98, 1316.18, 1357.55, 1261.46, 1285.64, 1171.37, 1352.30, 1057.03, 1180.40, 1092.10, 1083.04, 1337.04, 1212.64, 1229.50, 1245.28, 1176.11, 1333.82, 1325.87, 1200.51, 
+  1102.30, 1266.74, 1114.25, 1287.98, 1317.99, 1273.57, 1255.38, 1221.25, 1239.90, 1380.25, 1289.36, 1247.62, 1260.22, 1373.04, 1228.45, 1228.69, 1353.32, 1330.31, 1104.74, 1049.00, 
+  1242.65, 1136.09, 1402.20, 1293.11, 1203.44, 1333.25, 1239.05, 1229.50, 1209.23, 1146.20, 1358.72, 1395.66, 1338.24, 1310.86, 1255.35, 1384.90, 1158.04, 1198.98, 1440.59, 1127.60, 
+  957.27, 1348.18, 1362.57, 1180.99, 1464.68, 1386.78, 1512.22, 1534.28, 1327.25, 1431.83, 1344.34, 1485.21, 1271.82, 1323.19, 1236.09, 1315.75, 1519.97, 1242.57, 1318.09, 1376.85, 
+  1278.51, 1533.16, 1460.59, 1224.81, 1236.72, 1474.99, 1366.45, 1269.97, 1357.90, 1400.97, 1495.44, 1403.39, 1435.75, 1531.07, 1341.67, 1358.59, 1247.33, 1505.51, 1388.59, 1505.12, 
+  1464.88, 1423.19, 1310.46, 1278.27, 1401.25, 1310.40, 1581.57, 1427.85, 1367.65, 1463.46, 1476.53, 1409.38, 1257.88, 1299.85, 1625.04, 1442.07, 1532.34, 1497.04, 1437.51, 1624.79, 
+  1230.74, 1367.82, 1534.68, 1330.36, 1135.18, 1501.52, 1490.87, 1358.10, 1286.56, 1358.83, 1356.88, 1512.96, 1250.52, 1272.49, 1274.92, 1305.45, 1227.33, 1135.43, 1162.45, 1230.09, 
+  1385.53, 1230.82, 1243.73, 1297.78, 1234.57, 1488.49, 1293.94, 1251.93, 1145.57, 1356.51, 1208.46, 1241.36, 1273.63, 1288.38, 1365.52, 1321.69, 1331.95, 1379.18, 1281.63, 1354.01, 
+  1224.44, 1440.92, 1317.49, 1362.65, 1403.81, 1372.31, 1383.65, 1115.44, 1327.92, 1296.24, 1512.29, 1343.31, 1283.19, 1404.62, 1263.54, 1228.75, 1174.57, 1171.94, 1559.27, 1376.76, 
+  1456.71, 1345.08, 1380.05, 1459.01, 1212.10, 1348.34, 1492.67, 1287.52, 1112.90, 1499.50, 1326.50, 1268.42, 1039.32, 1159.37, 1261.43, 1324.98, 1100.77, 1171.99, 1087.34, 1102.53, 
+  1122.55, 1021.05, 1056.53, 1142.89, 1269.32, 1112.13, 1015.51, 1135.11, 1092.82, 1237.04, 1076.18, 1128.87, 1048.15, 1195.04, 1015.79, 1190.58, 1164.24, 1212.17, 1172.98, 1075.36, 
+  1228.39, 1240.92, 1150.23, 1237.26, 1086.94, 1254.15, 1132.80, 1164.63, 1162.59, 1136.61, 1173.39, 965.03, 1177.22, 1131.64, 1254.41, 1214.57, 1089.64, 1239.24, 1106.76, 1037.27, 
+  962.49, 1034.46, 1297.65, 1254.56, 1207.93, 1216.06, 1119.13, 1312.59, 1112.75, 1097.98, 1307.74, 1192.41, 973.53, 1387.04, 1157.31, 1099.13, 1311.17, 1378.00, 1469.13, 1590.78, 
+  1333.74, 1336.15, 1297.78, 1473.36, 1289.06, 1302.42, 1201.01, 1266.29, 1503.54, 1312.87, 1262.47, 1275.63, 1395.36, 1476.57, 1312.36, 1262.03, 1233.52, 1395.29, 1228.28, 1409.59, 
+  1387.55, 1403.12, 1430.41, 1272.49, 1428.01, 1479.15, 1339.01, 1457.99, 1369.05, 1393.67, 1413.85, 1431.64, 1376.41, 1390.82, 1314.10, 1180.77, 1298.37, 1343.59, 1467.81, 1361.09, 
+  1431.13, 1478.41, 1348.23, 1394.75, 1246.04, 1296.82, 1526.66, 1458.45, 1473.05, 1495.85, 1282.82, 1599.32, 1427.10, 1350.46, 1464.37, 1271.35, 1181.11, 1559.64, 1561.56, 1389.35, 
+  1369.84, 1419.83, 1451.45, 1681.61, 1436.44, 1348.12, 1308.13, 1388.24, 1301.13, 1385.31, 1220.28, 1341.28, 1601.04, 1331.48, 1325.58, 1290.60, 1232.76, 1642.37, 1411.39, 1377.22, 
+  1156.76, 1466.42, 1375.66, 1325.09, 1408.20, 1437.40, 1412.27, 1474.78, 1429.78, 1518.94, 1426.34, 1495.92, 1366.96, 1532.46, 1439.96, 1388.39, 1398.59, 1562.84, 1378.79, 1331.36, 
+  1412.45, 1305.85, 1580.16, 1359.08, 1343.40, 1530.16, 1364.59, 1285.68, 1317.68, 1368.55, 1723.86, 1409.11, 1699.95, 1580.27, 1439.28, 1528.99, 1482.09, 1450.39, 1640.19, 1379.11, 
+  1242.22, 1607.38, 1529.27, 1414.70, 1266.13, 1260.65, 1279.51, 1502.70, 1164.50, 1270.53, 1223.93, 1280.00, 1210.34, 1181.94, 1027.15, 1218.78, 1401.17, 1092.32, 1098.36, 1086.59, 
+  1176.60, 1377.04, 1199.74, 1119.22, 1191.42, 1411.57, 1248.73, 1205.67, 1231.78, 1151.91, 1239.38, 1347.67, 1253.05, 1343.59, 1284.73, 1303.14, 1126.30, 1303.28, 1197.07, 1290.40, 
+  1222.08, 1269.38, 1281.51, 1188.44, 1311.67, 1214.92, 1432.29, 1174.58, 1265.55, 1298.27, 1154.89, 1243.58, 1042.13, 1102.71, 1476.41, 1204.74, 1360.13, 1397.41, 1231.77, 1429.69, 
+  1197.13, 1276.24, 1299.34, 1187.89, 1114.67, 1363.68, 1379.29, 1171.70, 1313.87, 1352.24, 1441.85, 1667.44, 1351.17, 1313.45, 1240.02, 1208.08, 1192.24, 1235.72, 1178.14, 1183.12, 
+  1403.52, 1250.37, 1238.65, 1235.05, 1119.69, 1466.08, 1381.23, 1271.59, 988.59, 1354.66, 1345.17, 1279.41, 1295.76, 1272.77, 1376.11, 1406.65, 1285.50, 1477.70, 1328.50, 1429.22, 
+  1224.42, 1448.28, 1261.41, 1336.04, 1378.87, 1335.38, 1327.60, 1199.76, 1155.44, 1160.00, 1452.01, 1382.43, 1341.91, 1450.36, 1302.41, 1351.84, 1158.69, 1319.26, 1543.70, 1357.04, 
+  1533.51, 1426.15, 1387.27, 1526.33, 1228.63, 1320.55, 1432.95, 1315.83, 1049.43, 1500.71, 1353.63, 1368.97, 1139.31, 1157.17, 1384.59, 1380.63, 1311.81, 1234.87, 1312.66, 1303.28, 
+  1059.96, 1117.79, 1070.43, 1129.95, 1432.29, 1153.08, 1187.14, 1287.10, 1165.82, 1348.58, 1212.90, 1204.39, 1174.20, 1272.09, 1173.52, 1162.60, 1233.63, 1305.57, 1338.09, 1172.95, 
+  1323.86, 1324.07, 1243.67, 1266.72, 1170.81, 1398.73, 1119.67, 1331.76, 1175.22, 1201.22, 1211.26, 1127.93, 1328.62, 1271.81, 1474.22, 1339.07, 1270.04, 1259.59, 1228.70, 1161.23, 
+  1210.48, 1133.59, 1493.76, 1271.63, 1328.03, 1254.34, 1389.44, 1334.65, 1232.48, 1347.65, 1322.99, 1186.21, 1086.77, 1415.26, 1294.45, 1282.19, 1531.11, 1471.22, 1581.93, 1722.80, 
+  1505.51, 1453.34, 1412.37, 1422.03, 1293.06, 1310.27, 1294.47, 1416.66, 1600.64, 1341.85, 1341.85, 1451.51, 1367.89, 1716.03, 1573.49, 1361.98, 1197.26, 1473.62, 1355.35, 1361.63, 
+  1471.37, 1457.78, 1473.47, 1400.30, 1457.48, 1598.43, 1502.65, 1578.03, 1451.60, 1657.89, 1427.07, 1526.75, 1508.23, 1608.07, 1512.20, 1345.54, 1450.02, 1373.91, 1709.84, 1510.90, 
+  1468.48, 1554.60, 1447.69, 1403.40, 1439.40, 1364.05, 1649.56, 1519.12, 1662.38, 1580.64, 1521.50, 1648.85, 1473.95, 1537.87, 1603.35, 1405.32, 1277.63, 1635.12, 1530.58, 1527.68, 
+  1376.14, 1259.62, 1404.31, 1491.97, 1331.98, 1323.84, 1261.00, 1340.33, 1212.09, 1272.78, 1149.12, 1251.68, 1474.67, 1215.21, 1209.61, 1208.81, 1223.37, 1440.41, 1299.06, 1191.88, 
+  1159.34, 1391.74, 1411.92, 1238.45, 1366.96, 1326.26, 1374.60, 1281.97, 1335.22, 1429.39, 1234.86, 1347.17, 1296.84, 1441.90, 1285.37, 1323.53, 1295.99, 1417.08, 1297.75, 1166.38, 
+  1345.28, 1205.89, 1508.88, 1352.85, 1387.88, 1397.88, 1360.48, 1318.44, 1183.16, 1290.36, 1548.41, 1268.90, 1491.98, 1406.27, 1336.20, 1491.58, 1320.34, 1336.40, 1423.83, 1315.12, 
+  1140.91, 1435.46, 1362.80, 1367.75, 1208.92, 1214.60, 1291.40, 1393.45, 1352.84, 1177.35, 1233.46, 1243.24, 1202.87, 1152.15, 1102.70, 1135.41, 1311.41, 1209.16, 1166.73, 1153.12, 
+  1082.47, 1368.74, 1272.80, 1247.51, 972.26, 1268.29, 1180.56, 1139.86, 1160.60, 1213.71, 1159.53, 1298.88, 1185.02, 1340.95, 1207.52, 1320.85, 1165.75, 1343.30, 1320.00, 1267.42, 
+  1284.86, 1303.08, 1196.86, 1109.66, 1177.52, 1129.73, 1377.07, 1293.27, 1104.89, 1318.76, 1217.58, 1159.26, 1134.64, 1227.63, 1465.98, 1179.33, 1349.20, 1310.41, 1333.38, 1341.44, 
+  1204.24, 1234.32, 1426.88, 1212.51, 1090.72, 1367.31, 1306.05, 1198.97, 1324.78, 1346.77, 1413.33, 1636.98, 1448.15, 1362.02, 1289.33, 1392.20, 1303.17, 1337.15, 1208.25, 1255.99, 
+  1570.02, 1285.29, 1254.08, 1266.47, 1371.72, 1524.30, 1318.69, 1309.52, 1280.95, 1448.40, 1241.72, 1305.67, 1428.22, 1313.74, 1429.82, 1245.78, 1457.28, 1413.81, 1374.30, 1425.78, 
+  1386.56, 1480.91, 1370.04, 1377.77, 1448.03, 1484.91, 1440.71, 1135.39, 1430.11, 1296.96, 1528.05, 1457.42, 1443.13, 1488.35, 1343.99, 1363.68, 1292.27, 1385.99, 1610.51, 1429.82, 
+  1581.36, 1555.99, 1405.08, 1588.68, 1483.02, 1433.00, 1484.10, 1337.65, 1216.33, 1530.77, 1414.60, 1352.93, 1410.85, 1404.43, 1499.88, 1654.33, 1419.27, 1381.92, 1446.47, 1313.75, 
+  1230.75, 1311.00, 1281.90, 1336.07, 1486.57, 1303.81, 1283.26, 1203.40, 1251.23, 1607.85, 1466.10, 1354.93, 1139.88, 1361.32, 1332.28, 1256.61, 1325.96, 1293.50, 1383.11, 1380.59, 
+  1410.64, 1503.91, 1421.53, 1431.41, 1325.24, 1542.63, 1332.45, 1445.11, 1361.08, 1475.89, 1355.22, 1261.77, 1358.17, 1276.94, 1568.52, 1461.70, 1382.64, 1434.41, 1416.95, 1289.51, 
+  1280.10, 1333.82, 1592.15, 1440.51, 1596.76, 1593.17, 1441.33, 1553.98, 1355.84, 1444.55, 1554.09, 1333.92, 1217.44, 1539.21, 1425.98, 1438.95, 1326.11, 1337.20, 1418.70, 1565.13, 
+  1346.15, 1290.62, 1390.47, 1296.12, 1222.93, 1208.62, 1157.11, 1232.63, 1431.54, 1168.34, 1209.56, 1266.56, 1335.13, 1510.47, 1218.02, 1308.08, 1163.80, 1395.41, 1241.01, 1233.40, 
+  1319.51, 1337.43, 1331.33, 1363.23, 1294.18, 1421.20, 1315.08, 1406.64, 1342.14, 1419.83, 1328.49, 1338.51, 1319.43, 1378.65, 1317.56, 1178.78, 1314.38, 1281.70, 1528.55, 1248.40, 
+  1287.56, 1396.60, 1304.52, 1274.46, 1270.10, 1141.44, 1508.64, 1261.97, 1498.70, 1296.16, 1294.33, 1447.11, 1317.39, 1387.30, 1419.28, 1175.32, 1093.19, 1393.37, 1432.13, 1394.91, 
+  1339.44, 1451.46, 1471.60, 1647.16, 1395.21, 1329.47, 1212.87, 1280.47, 1242.28, 1256.06, 1229.93, 1290.29, 1501.08, 1217.36, 1260.44, 1325.51, 1175.00, 1555.52, 1382.92, 1311.71, 
+  1136.58, 1354.00, 1299.64, 1349.04, 1383.59, 1351.55, 1450.07, 1263.82, 1348.83, 1480.50, 1323.08, 1472.22, 1313.66, 1503.74, 1278.77, 1374.14, 1383.02, 1426.02, 1387.34, 1283.57, 
+  1391.57, 1202.51, 1506.87, 1435.41, 1387.86, 1495.19, 1337.06, 1342.56, 1313.18, 1388.45, 1549.16, 1501.64, 1582.78, 1457.61, 1393.05, 1532.14, 1296.13, 1417.10, 1538.59, 1331.41, 
+  1146.52, 1483.76, 1364.16, 1342.58, 1339.84, 1231.51, 1392.19, 1541.26, 1379.06, 1284.47, 1333.99, 1168.79, 1240.25, 1243.38, 1225.68, 1192.46, 1478.92, 1143.23, 1194.31, 1184.91, 
+  1244.84, 1460.50, 1353.63, 1309.48, 1198.55, 1343.88, 1285.32, 1183.00, 1285.77, 1329.35, 1249.94, 1336.30, 1272.53, 1475.49, 1341.50, 1462.93, 1289.21, 1460.03, 1274.86, 1412.97, 
+  1309.66, 1320.84, 1207.50, 1154.06, 1326.60, 1294.83, 1430.91, 1303.30, 1412.77, 1334.93, 1417.29, 1186.29, 1167.63, 1136.88, 1547.47, 1292.33, 1537.90, 1413.62, 1477.22, 1370.40, 
+  1266.79, 1468.12, 1541.73, 1280.70, 1099.87, 1431.57, 1370.73, 1430.16, 1287.15, 1302.94, 1367.50, 1479.61, 1183.45, 1271.03, 1104.45, 1254.57, 1067.91, 1055.56, 1147.17, 1099.07, 
+  1412.01, 1175.60, 1122.21, 1168.64, 1217.95, 1435.20, 1244.95, 1174.28, 1037.30, 1346.03, 1126.56, 1133.71, 1207.31, 1213.28, 1396.69, 1246.52, 1310.06, 1341.45, 1199.27, 1302.28, 
+  1193.38, 1415.50, 1300.40, 1293.62, 1265.19, 1312.18, 1194.04, 1070.98, 1200.29, 1231.26, 1382.38, 1245.62, 1289.17, 1253.46, 1203.08, 1216.75, 1216.75, 1113.40, 1511.99, 1333.84, 
+  1491.33, 1364.50, 1252.77, 1389.22, 1266.92, 1262.67, 1308.35, 1139.02, 1095.95, 1250.58, 1256.60, 1207.54, 1258.37, 1222.83, 1387.63, 1565.40, 1286.28, 1378.77, 1202.50, 1226.40, 
+  1233.51, 1272.39, 1135.10, 1272.53, 1450.78, 1205.86, 1172.64, 1251.87, 1293.64, 1408.35, 1253.49, 1169.40, 1094.99, 1473.96, 1156.60, 1152.69, 1240.37, 1336.59, 1256.09, 1270.34, 
+  1379.24, 1264.01, 1305.27, 1316.17, 1293.57, 1354.00, 1248.79, 1230.31, 1220.46, 1266.96, 1321.42, 1161.22, 1321.67, 1215.86, 1477.98, 1247.61, 1280.55, 1396.92, 1217.64, 1290.41, 
+  1120.19, 1274.98, 1522.36, 1319.65, 1452.76, 1448.01, 1346.93, 1538.98, 1387.19, 1302.15, 1393.31, 1255.87, 1105.50, 1455.56, 1369.93, 1209.40, 1381.89, 1430.12, 1450.82, 1635.71, 
+  1437.24, 1390.56, 1342.80, 1428.70, 1304.14, 1425.51, 1222.89, 1303.49, 1524.84, 1368.17, 1254.39, 1262.64, 1289.81, 1553.24, 1336.51, 1305.66, 1175.94, 1402.50, 1383.16, 1314.48, 
+  1333.52, 1364.53, 1348.77, 1331.30, 1485.87, 1504.13, 1293.29, 1503.41, 1250.85, 1495.27, 1310.55, 1416.37, 1483.68, 1408.91, 1391.24, 1197.45, 1403.04, 1310.95, 1529.08, 1376.88, 
+  1411.55, 1494.99, 1419.20, 1348.40, 1245.18, 1339.69, 1672.18, 1481.88, 1471.30, 1589.93, 1510.08, 1591.33, 1434.29, 1500.06, 1437.97, 1336.17, 1210.29, 1496.89, 1431.74, 1434.55, 
+  1109.32, 1160.85, 1183.75, 1317.10, 1136.56, 1202.62, 1257.64, 1211.35, 960.97, 1102.03, 1035.43, 1094.03, 1322.79, 1109.01, 1178.40, 1103.12, 1115.55, 1351.82, 1180.03, 1116.25, 
+  1067.68, 1210.60, 1141.34, 1138.26, 1164.25, 1188.62, 1145.14, 1166.63, 1151.11, 1266.50, 1196.94, 1283.88, 1029.97, 1290.98, 1111.12, 1167.39, 1194.87, 1163.32, 1146.74, 980.08, 
+  1133.81, 1213.24, 1390.11, 1235.55, 1185.48, 1129.37, 1195.50, 1057.05, 1045.65, 1150.77, 1310.88, 1207.02, 1306.82, 1266.99, 1191.95, 1332.92, 1186.43, 1196.87, 1277.65, 1113.34, 
+  997.77, 1325.07, 1240.91, 1192.01, 1328.43, 1524.76, 1378.11, 1655.42, 1482.31, 1257.37, 1371.89, 1391.01, 1290.70, 1320.22, 1278.98, 1259.12, 1517.19, 1396.03, 1312.04, 1322.48, 
+  1342.52, 1615.32, 1338.23, 1323.15, 1259.52, 1392.80, 1297.01, 1396.00, 1374.56, 1369.10, 1377.74, 1341.32, 1343.13, 1494.14, 1353.10, 1539.29, 1394.78, 1554.40, 1437.57, 1392.17, 
+  1436.09, 1462.98, 1462.19, 1287.17, 1353.18, 1347.42, 1494.53, 1417.34, 1416.12, 1472.78, 1293.32, 1307.72, 1291.17, 1426.14, 1707.64, 1393.30, 1626.75, 1552.00, 1554.54, 1585.40, 
+  1462.09, 1566.27, 1554.21, 1355.06, 1247.11, 1530.26, 1509.97, 1483.55, 1157.37, 1224.96, 1303.57, 1373.71, 1108.41, 1151.40, 1128.28, 1104.19, 1036.39, 1078.01, 1126.44, 1077.43, 
+  1260.49, 1049.67, 1093.87, 1150.62, 1191.45, 1340.40, 1063.97, 1177.66, 1092.67, 1192.58, 1171.95, 1114.64, 1132.36, 1187.56, 1184.95, 1098.46, 1242.38, 1252.91, 1146.14, 1213.53, 
+  1151.48, 1302.51, 1210.09, 1277.25, 1212.93, 1169.25, 1232.64, 1013.59, 1131.25, 1181.94, 1195.44, 1222.64, 1227.38, 1262.32, 1169.22, 1110.55, 1056.72, 1113.43, 1372.05, 1172.92, 
+  1341.51, 1333.83, 1318.03, 1297.42, 1128.36, 1286.40, 1432.39, 1234.76, 960.27, 1262.17, 1230.64, 1289.61, 1178.74, 1322.92, 1365.09, 1560.18, 1240.06, 1298.16, 1270.39, 1380.29, 
+  1178.59, 1282.83, 1131.41, 1247.39, 1454.86, 1299.12, 1234.57, 1251.17, 1226.32, 1393.81, 1315.78, 1187.97, 1116.85, 1296.71, 1258.36, 1319.93, 1404.14, 1256.31, 1250.91, 1225.50, 
+  1318.11, 1406.80, 1374.43, 1321.74, 1271.49, 1367.09, 1280.77, 1216.35, 1378.19, 1344.02, 1280.09, 1266.72, 1361.90, 1082.34, 1467.46, 1247.23, 1225.47, 1397.46, 1170.62, 1280.63, 
+  1215.11, 1305.35, 1472.73, 1402.19, 1438.47, 1387.88, 1343.98, 1551.27, 1286.53, 1306.61, 1473.54, 1268.90, 1026.88, 1435.20, 1338.70, 1201.07, 1205.67, 1180.31, 1277.09, 1487.67, 
+  1275.37, 1205.90, 1168.27, 1151.28, 1266.29, 1223.82, 1025.42, 1126.89, 1418.77, 1258.73, 1151.18, 1185.15, 1201.54, 1305.38, 1224.83, 1195.85, 1156.78, 1236.28, 1140.40, 1218.58, 
+  1264.79, 1310.85, 1267.30, 1276.64, 1345.50, 1424.70, 1313.61, 1274.54, 1094.44, 1262.35, 1244.23, 1306.83, 1273.37, 1289.96, 1211.66, 1111.85, 1231.99, 1238.70, 1388.57, 1291.91, 
+  1313.12, 1363.81, 1206.82, 1224.65, 1157.49, 1166.88, 1407.36, 1380.27, 1427.48, 1442.76, 1246.20, 1427.56, 1280.26, 1204.75, 1406.67, 1269.74, 1098.59, 1504.81, 1333.90, 1320.63, 
+  1439.39, 1500.46, 1521.08, 1643.49, 1370.21, 1362.21, 1399.55, 1373.25, 1288.44, 1307.67, 1256.60, 1368.86, 1587.53, 1351.12, 1269.76, 1298.72, 1277.12, 1573.40, 1379.21, 1313.94, 
+  1350.92, 1346.48, 1358.60, 1362.78, 1385.25, 1415.82, 1417.94, 1276.20, 1399.87, 1503.54, 1365.93, 1488.50, 1229.29, 1605.94, 1378.20, 1407.51, 1463.04, 1487.27, 1308.27, 1295.92, 
+  1479.90, 1329.27, 1537.17, 1375.43, 1384.39, 1498.94, 1355.79, 1248.86, 1266.85, 1343.97, 1577.34, 1492.68, 1574.08, 1540.48, 1430.11, 1616.07, 1314.66, 1394.15, 1547.96, 1343.40, 
+  1238.82, 1453.75, 1400.22, 1411.65, 1266.02, 1414.66, 1393.70, 1586.89, 1439.13, 1147.83, 1388.78, 1205.49, 1210.84, 1220.89, 1086.58, 1282.55, 1383.51, 1173.76, 1187.24, 1206.61, 
+  1189.22, 1466.96, 1221.41, 1281.40, 1112.21, 1303.78, 1244.05, 1199.54, 1150.01, 1291.89, 1187.27, 1271.99, 1300.04, 1388.98, 1249.89, 1377.25, 1331.37, 1344.50, 1185.39, 1369.23, 
+  1297.42, 1346.96, 1344.56, 1085.52, 1322.79, 1161.28, 1369.76, 1327.06, 1254.11, 1295.80, 1175.43, 1147.85, 1186.42, 1235.36, 1547.78, 1293.41, 1462.35, 1358.42, 1280.40, 1305.61, 
+  1284.39, 1322.74, 1458.59, 1227.66, 1242.84, 1422.63, 1283.41, 1293.64, 1236.86, 1238.83, 1325.46, 1339.01, 1243.56, 1276.09, 1223.38, 1317.69, 1026.85, 1158.69, 1102.14, 1115.35, 
+  1243.15, 1152.42, 1207.79, 1174.65, 1257.85, 1356.79, 1174.03, 1151.82, 1116.41, 1320.78, 1188.24, 1150.60, 1187.63, 1218.89, 1267.38, 1132.95, 1250.98, 1318.38, 1122.67, 1235.94, 
+  1204.07, 1331.33, 1247.02, 1269.95, 1240.11, 1262.19, 1126.53, 1030.14, 1222.95, 1211.25, 1363.31, 1343.91, 1257.16, 1283.36, 1396.42, 1256.45, 1195.48, 1121.06, 1473.56, 1234.76, 
+  1363.67, 1305.92, 1345.16, 1403.26, 1201.26, 1268.59, 1298.15, 1035.01, 1016.79, 1252.66, 1301.61, 1217.53, 1294.85, 1272.48, 1438.89, 1559.17, 1373.48, 1459.73, 1309.49, 1395.41, 
+  1253.73, 1330.35, 1170.63, 1251.99, 1459.50, 1183.12, 1196.73, 1321.25, 1313.51, 1423.84, 1327.71, 1202.91, 1222.77, 1513.00, 1291.28, 1205.45, 1366.21, 1464.72, 1368.94, 1347.14, 
+  1408.92, 1530.45, 1289.40, 1376.09, 1313.88, 1407.88, 1279.27, 1403.69, 1335.38, 1386.07, 1362.59, 1073.05, 1270.84, 1284.84, 1526.29, 1415.24, 1394.95, 1447.69, 1398.90, 1305.83, 
+  1274.60, 1252.84, 1587.27, 1371.74, 1467.79, 1434.15, 1375.48, 1545.78, 1266.71, 1317.48, 1572.39, 1244.32, 1174.21, 1468.65, 1413.09, 1290.17, 1197.21, 1155.17, 1263.35, 1275.64, 
+  1172.47, 1166.75, 1044.69, 1269.30, 1050.90, 1086.32, 1023.80, 1087.59, 1323.49, 973.71, 1130.29, 1094.06, 1026.61, 1277.66, 1148.16, 1004.99, 1077.11, 1247.31, 1140.63, 1135.91, 
+  1193.23, 1158.95, 1238.92, 1111.04, 1119.26, 1365.83, 1098.28, 1154.73, 1024.14, 1265.05, 1204.07, 1293.20, 1264.65, 1157.76, 1059.30, 1018.65, 1143.54, 1143.00, 1259.12, 1201.64, 
+  1150.86, 1251.88, 1317.65, 1162.50, 992.08, 1126.13, 1323.76, 1158.03, 1267.61, 1293.64, 1237.19, 1384.30, 1025.94, 1139.64, 1297.74, 1216.18, 993.00, 1300.77, 1218.99, 1093.70, 
+  1311.48, 1379.92, 1391.74, 1445.09, 1292.05, 1323.08, 1298.06, 1391.88, 1159.64, 1262.33, 1149.94, 1219.13, 1434.55, 1241.38, 1228.38, 1255.36, 1287.72, 1541.03, 1349.55, 1235.28, 
+  1182.24, 1330.28, 1208.99, 1294.62, 1384.90, 1249.50, 1334.11, 1137.09, 1360.42, 1419.80, 1252.52, 1460.52, 1364.99, 1483.29, 1262.38, 1290.85, 1393.34, 1474.44, 1301.33, 1126.24, 
+  1332.38, 1186.72, 1429.03, 1304.63, 1254.23, 1479.85, 1226.02, 1171.24, 1321.09, 1285.88, 1477.04, 1426.97, 1464.75, 1483.92, 1313.67, 1615.16, 1302.34, 1412.35, 1390.38, 1185.07, 
+  1031.23, 1431.41, 1362.11, 1279.65, 1147.52, 1265.17, 1338.69, 1294.82, 1081.53, 1155.02, 1171.38, 1284.06, 996.85, 1085.68, 1079.02, 1035.53, 1365.52, 1111.12, 1050.53, 1170.60, 
+  1154.94, 1401.82, 1131.67, 1165.38, 1080.77, 1251.29, 1187.41, 1202.82, 1161.96, 1166.27, 1264.96, 1224.00, 1232.78, 1356.04, 1235.77, 1367.99, 1080.91, 1395.61, 1116.94, 1197.89, 
+  1152.28, 1282.20, 1265.43, 1105.87, 1160.68, 1185.00, 1377.18, 1160.41, 1237.22, 1369.00, 1172.74, 1143.98, 1164.60, 1059.15, 1490.22, 1281.17, 1272.72, 1306.11, 1257.99, 1435.04, 
+  1156.08, 1275.73, 1268.04, 1056.30, 962.94, 1269.43, 1272.12, 1262.24, 1212.76, 1148.18, 1322.38, 1439.61, 1326.34, 1348.20, 1146.04, 1213.72, 1202.08, 1253.69, 1144.32, 1217.91, 
+  1487.40, 1187.52, 1089.16, 1188.73, 1165.73, 1402.32, 1221.57, 1045.12, 1064.80, 1326.59, 1127.45, 1105.51, 1205.64, 1341.33, 1306.25, 1205.99, 1321.27, 1307.26, 1239.29, 1379.26, 
+  1220.08, 1373.86, 1274.71, 1285.41, 1272.40, 1249.75, 1264.54, 1089.46, 1183.74, 1163.74, 1415.27, 1413.09, 1297.57, 1262.34, 1355.14, 1284.73, 1208.88, 1302.79, 1486.06, 1227.25, 
+  1438.54, 1249.08, 1329.12, 1497.28, 1315.91, 1372.41, 1364.22, 1205.45, 1057.81, 1386.32, 1352.89, 1294.29, 1325.27, 1230.70, 1321.97, 1486.89, 1399.78, 1294.22, 1267.40, 1343.29, 
+  1235.20, 1270.54, 1121.95, 1250.46, 1478.94, 1205.37, 1219.79, 1152.37, 1161.98, 1466.89, 1362.33, 1232.15, 1071.75, 1374.74, 1195.27, 1254.65, 1194.23, 1331.21, 1282.74, 1387.72, 
+  1327.09, 1451.54, 1293.32, 1388.75, 1173.54, 1410.52, 1246.23, 1421.01, 1352.69, 1347.36, 1225.86, 1172.25, 1214.56, 1218.43, 1476.12, 1327.09, 1228.78, 1331.55, 1374.88, 1216.15, 
+  1184.61, 1275.82, 1542.57, 1276.47, 1440.43, 1462.71, 1422.04, 1461.29, 1230.16, 1392.49, 1467.53, 1279.27, 1118.19, 1440.74, 1458.13, 1403.59, 1368.83, 1301.71, 1410.11, 1550.70, 
+  1329.09, 1376.40, 1284.55, 1321.19, 1211.98, 1352.49, 1185.79, 1269.39, 1571.69, 1236.95, 1198.81, 1316.00, 1245.78, 1465.14, 1349.26, 1275.25, 1176.92, 1332.87, 1268.57, 1195.62, 
+  1258.48, 1351.58, 1365.71, 1308.49, 1346.47, 1406.09, 1215.81, 1464.78, 1268.32, 1487.75, 1278.61, 1384.99, 1346.72, 1299.86, 1301.33, 1129.20, 1267.63, 1200.91, 1519.21, 1366.10, 
+  1359.52, 1400.78, 1292.35, 1266.57, 1199.34, 1314.76, 1593.66, 1317.76, 1464.75, 1440.56, 1359.43, 1498.53, 1235.95, 1396.02, 1470.29, 1225.62, 1121.64, 1508.88, 1415.02, 1354.13, 
+  1094.40, 1256.05, 1306.23, 1484.59, 1159.38, 1184.43, 1160.58, 1239.94, 1066.13, 1120.31, 1084.26, 1107.13, 1232.42, 1185.27, 1122.73, 1218.90, 1158.50, 1390.26, 1222.39, 1203.27, 
+  1045.68, 1255.68, 1168.27, 1176.79, 1298.02, 1267.50, 1307.26, 1289.89, 1247.03, 1287.59, 1222.51, 1262.53, 1148.63, 1271.35, 1245.51, 1187.88, 1234.49, 1307.71, 1249.04, 1116.37, 
+  1219.62, 1218.57, 1349.69, 1204.77, 1223.39, 1327.52, 1178.79, 1126.71, 1144.74, 1082.20, 1503.34, 1301.65, 1392.24, 1318.44, 1260.89, 1274.02, 1282.23, 1266.53, 1428.87, 1171.14, 
+  1111.19, 1426.06, 1228.13, 1162.35, 1290.22, 1234.24, 1447.04, 1554.34, 1329.19, 1395.15, 1224.29, 1368.36, 1262.15, 1235.36, 1078.19, 1217.33, 1493.90, 1206.57, 1278.17, 1261.99, 
+  1207.40, 1527.35, 1164.25, 1225.90, 1209.26, 1448.77, 1186.13, 1225.96, 1427.34, 1285.64, 1345.22, 1242.62, 1319.73, 1382.43, 1353.37, 1346.72, 1312.13, 1358.70, 1315.08, 1232.98, 
+  1254.44, 1394.73, 1317.85, 1135.92, 1376.34, 1246.70, 1506.46, 1352.52, 1373.02, 1465.13, 1343.40, 1325.84, 1297.73, 1252.62, 1522.17, 1325.26, 1533.99, 1484.58, 1420.57, 1539.40, 
+  1309.14, 1336.26, 1459.18, 1308.33, 1187.05, 1544.99, 1431.61, 1252.38, 1297.08, 1386.36, 1534.82, 1508.74, 1322.47, 1439.91, 1396.94, 1350.46, 1277.41, 1225.67, 1333.70, 1327.48, 
+  1505.64, 1263.33, 1252.28, 1351.43, 1316.36, 1539.11, 1348.90, 1296.86, 1176.41, 1429.35, 1293.29, 1275.66, 1397.76, 1408.99, 1357.66, 1318.09, 1363.31, 1513.22, 1427.17, 1492.98, 
+  1366.35, 1582.13, 1356.30, 1444.21, 1382.33, 1365.70, 1420.20, 1217.78, 1432.58, 1228.45, 1616.54, 1409.56, 1307.97, 1475.86, 1318.09, 1367.11, 1286.74, 1257.13, 1573.40, 1372.58, 
+  1447.57, 1427.08, 1471.14, 1566.62, 1257.12, 1423.67, 1589.79, 1344.49, 1130.92, 1498.77, 1430.68, 1448.58, 1273.37, 1187.48, 1364.40, 1523.23, 1134.45, 1280.58, 1181.08, 1208.90, 
+  1122.63, 1174.70, 1126.42, 1201.24, 1346.38, 1141.12, 1131.35, 1126.39, 1096.53, 1371.79, 1273.42, 1263.91, 1027.28, 1217.60, 1233.67, 1146.90, 1230.50, 1199.41, 1100.08, 1152.27, 
+  1273.63, 1323.58, 1214.36, 1346.47, 1135.80, 1375.39, 1235.42, 1336.22, 1267.26, 1262.96, 1092.23, 1234.82, 1264.79, 1214.61, 1348.77, 1253.45, 1122.38, 1239.97, 1224.84, 1152.76, 
+  1134.34, 1142.76, 1429.84, 1189.04, 1387.07, 1278.77, 1361.50, 1392.18, 1206.86, 1334.71, 1346.73, 1242.13, 1050.60, 1341.34, 1260.75, 1238.45, 1259.03, 1452.68, 1421.62, 1570.44, 
+  1251.15, 1244.67, 1329.80, 1327.47, 1172.33, 1235.11, 1245.45, 1199.66, 1397.00, 1148.54, 1301.25, 1264.99, 1293.76, 1468.17, 1340.31, 1238.17, 1251.76, 1361.59, 1341.50, 1352.14, 
+  1323.34, 1308.28, 1426.95, 1417.59, 1269.54, 1456.13, 1317.12, 1445.25, 1312.21, 1459.87, 1347.29, 1358.24, 1396.66, 1443.73, 1350.70, 1268.52, 1365.85, 1364.99, 1421.07, 1307.91, 
+  1352.22, 1391.29, 1355.71, 1216.58, 1176.76, 1202.96, 1642.02, 1413.84, 1638.88, 1448.85, 1415.71, 1453.51, 1356.51, 1397.14, 1551.89, 1241.79, 1051.81, 1481.01, 1375.11, 1306.43, 
+  1391.90, 1448.82, 1525.69, 1650.86, 1352.60, 1398.71, 1409.39, 1522.05, 1223.15, 1417.08, 1140.56, 1282.95, 1512.92, 1306.01, 1310.24, 1293.54, 1347.89, 1517.58, 1384.35, 1324.97, 
+  1246.73, 1380.81, 1304.58, 1326.74, 1381.90, 1365.68, 1340.00, 1292.61, 1463.39, 1444.67, 1343.18, 1426.27, 1341.80, 1491.57, 1423.12, 1381.26, 1448.98, 1411.46, 1300.85, 1256.10, 
+  1367.57, 1251.11, 1535.47, 1420.20, 1447.88, 1459.55, 1441.55, 1314.46, 1233.96, 1360.85, 1603.25, 1477.07, 1444.84, 1500.80, 1486.72, 1601.72, 1338.91, 1511.31, 1509.19, 1342.63, 
+  1213.00, 1555.80, 1461.04, 1324.73, 1350.26, 1407.60, 1553.58, 1622.25, 1309.04, 1278.07, 1257.23, 1263.75, 1204.42, 1237.60, 1135.64, 1323.82, 1440.34, 1206.64, 1147.32, 1284.33, 
+  1298.69, 1563.46, 1245.16, 1371.08, 1110.77, 1353.32, 1272.94, 1376.96, 1393.38, 1327.03, 1390.54, 1231.77, 1391.41, 1334.24, 1462.92, 1495.89, 1396.69, 1501.23, 1343.75, 1252.75, 
+  1338.90, 1593.07, 1375.33, 1226.33, 1407.39, 1229.39, 1527.84, 1289.46, 1396.80, 1388.67, 1198.63, 1211.68, 1330.36, 1218.02, 1483.55, 1494.09, 1524.05, 1427.59, 1263.21, 1483.71, 
+  1281.09, 1329.57, 1457.08, 1284.94, 1185.33, 1443.42, 1330.63, 1430.03, 1214.06, 1219.89, 1347.54, 1421.58, 1180.42, 1272.71, 1211.46, 1326.81, 1037.82, 1082.19, 1161.71, 1141.40, 
+  1350.77, 1189.16, 1100.50, 1203.64, 1121.20, 1380.45, 1222.09, 1115.74, 1117.06, 1254.62, 1148.37, 1123.30, 1181.78, 1308.93, 1173.63, 1212.08, 1175.13, 1206.51, 1158.92, 1354.48, 
+  1187.28, 1432.28, 1261.04, 1279.24, 1216.02, 1300.33, 1216.19, 1091.07, 1235.87, 1242.67, 1378.27, 1250.20, 1229.67, 1274.75, 1192.17, 1186.72, 1065.46, 1210.51, 1413.41, 1192.26, 
+  1319.02, 1308.81, 1343.64, 1323.26, 1216.37, 1278.10, 1388.78, 1165.99, 1078.57, 1239.04, 1337.30, 1274.60, 1349.44, 1467.96, 1499.66, 1723.01, 1394.09, 1391.72, 1456.78, 1508.54, 
+  1285.27, 1410.21, 1227.75, 1258.55, 1568.65, 1294.37, 1346.73, 1355.97, 1291.39, 1491.92, 1433.87, 1383.22, 1234.42, 1480.98, 1431.55, 1394.94, 1451.04, 1461.42, 1480.30, 1390.20, 
+  1451.88, 1559.52, 1316.89, 1396.52, 1385.16, 1549.24, 1376.21, 1352.67, 1490.72, 1377.56, 1324.12, 1288.39, 1486.11, 1401.94, 1597.30, 1393.09, 1393.10, 1527.19, 1346.17, 1403.61, 
+  1329.84, 1428.33, 1697.28, 1486.74, 1610.30, 1524.46, 1536.59, 1601.98, 1406.43, 1537.88, 1518.79, 1379.87, 1151.81, 1615.09, 1448.84, 1386.40, 1198.14, 1206.61, 1238.94, 1358.98, 
+  1104.33, 1060.02, 1132.03, 1218.76, 1148.86, 1139.73, 1011.63, 1011.10, 1253.39, 1145.71, 1046.80, 1098.42, 1133.10, 1332.54, 1114.50, 1108.41, 1095.69, 1186.49, 1088.61, 1177.96, 
+  1179.91, 1080.40, 1232.01, 1178.43, 1295.16, 1337.88, 1089.30, 1138.30, 982.34, 1238.16, 1193.96, 1128.41, 1226.30, 1110.66, 1201.22, 1026.73, 1099.94, 1082.45, 1286.87, 1182.08, 
+  1161.86, 1229.94, 1118.10, 1169.49, 1059.97, 1106.63, 1337.81, 1198.73, 1338.76, 1140.70, 1176.55, 1411.23, 1066.54, 1225.73, 1285.37, 1105.53, 995.55, 1251.52, 1296.70, 1183.81, 
+  1336.82, 1359.41, 1531.23, 1506.89, 1277.25, 1341.98, 1207.09, 1441.27, 1245.61, 1279.99, 1171.33, 1203.39, 1552.78, 1221.36, 1278.65, 1229.00, 1212.91, 1567.53, 1327.70, 1240.24, 
+  1221.25, 1366.21, 1299.23, 1329.50, 1364.06, 1221.40, 1345.24, 1276.10, 1358.50, 1499.46, 1370.30, 1533.58, 1307.25, 1541.06, 1373.60, 1256.80, 1411.07, 1472.58, 1381.63, 1209.79, 
+  1385.44, 1228.53, 1579.26, 1332.83, 1430.57, 1425.45, 1391.60, 1288.74, 1244.24, 1275.17, 1516.60, 1474.56, 1448.48, 1489.99, 1368.60, 1592.46, 1335.75, 1411.22, 1432.70, 1267.68, 
+  1041.35, 1491.54, 1498.69, 1323.89, 1179.47, 1288.17, 1343.09, 1495.42, 1190.80, 1208.26, 1233.67, 1266.03, 1009.92, 1189.92, 1079.33, 1226.48, 1415.04, 1174.65, 1095.22, 1124.00, 
+  1118.95, 1334.79, 1243.54, 1187.79, 1081.39, 1204.17, 1153.96, 1225.61, 1165.12, 1278.03, 1207.02, 1105.44, 1266.90, 1290.10, 1156.28, 1332.57, 1130.42, 1364.51, 1124.01, 1162.57, 
+  1257.70, 1224.27, 1163.35, 1089.64, 1331.68, 1111.06, 1321.76, 1210.18, 1203.34, 1320.04, 1119.50, 1162.15, 1211.72, 1226.56, 1418.76, 1345.12, 1364.04, 1344.66, 1322.72, 1369.63, 
+  1197.77, 1342.54, 1295.97, 1116.95, 1010.17, 1336.54, 1207.94, 1273.88, 1234.22, 1145.59, 1273.48, 1352.87, 1111.27, 1229.25, 1105.41, 1236.72, 1114.96, 1128.70, 1001.74, 1106.89, 
+  1306.04, 1147.72, 1139.74, 1197.38, 1101.79, 1346.01, 1193.67, 1053.84, 997.60, 1243.23, 1132.20, 1140.96, 1188.55, 1128.00, 1141.85, 1152.23, 1186.89, 1293.55, 1165.47, 1241.90, 
+  1114.40, 1382.10, 1174.74, 1128.36, 1206.13, 1252.88, 1163.47, 1058.72, 1157.54, 1136.36, 1452.71, 1189.00, 1158.47, 1286.42, 1087.34, 1117.48, 1059.71, 1200.30, 1363.05, 1194.97, 
+  1287.62, 1371.77, 1242.62, 1381.55, 1162.41, 1153.85, 1296.64, 1183.91, 1104.32, 1302.69, 1248.47, 1127.57, 1541.65, 1449.79, 1543.72, 1669.84, 1552.41, 1442.87, 1419.15, 1516.45, 
+  1365.70, 1418.19, 1283.35, 1397.02, 1636.63, 1330.73, 1354.17, 1396.58, 1343.54, 1676.34, 1545.03, 1346.49, 1205.89, 1582.05, 1492.58, 1339.30, 1505.07, 1445.89, 1521.83, 1438.11, 
+  1514.20, 1537.87, 1457.46, 1563.90, 1380.61, 1640.16, 1372.38, 1522.58, 1470.40, 1587.96, 1514.42, 1344.65, 1492.48, 1285.49, 1721.76, 1459.99, 1440.06, 1547.91, 1372.78, 1443.99, 
+  1427.05, 1452.09, 1730.53, 1504.18, 1661.41, 1506.44, 1466.96, 1729.20, 1424.56, 1526.45, 1623.14, 1377.34, 1328.57, 1535.54, 1486.59, 1426.21, 1251.77, 1271.32, 1385.16, 1513.24, 
+  1214.50, 1329.88, 1281.79, 1400.95, 1181.91, 1193.78, 1112.89, 1162.70, 1409.60, 1309.09, 1324.74, 1200.69, 1270.76, 1404.72, 1270.69, 1247.59, 1133.68, 1276.68, 1301.66, 1287.50, 
+  1245.47, 1231.10, 1338.69, 1224.15, 1459.25, 1460.39, 1298.97, 1267.27, 1198.90, 1420.61, 1242.62, 1373.64, 1278.89, 1310.16, 1265.24, 1162.40, 1356.80, 1323.82, 1486.75, 1340.86, 
+  1272.36, 1425.28, 1252.32, 1345.57, 1290.27, 1190.63, 1562.44, 1439.95, 1476.36, 1440.54, 1413.98, 1475.85, 1274.13, 1332.14, 1366.48, 1104.44, 1112.21, 1401.95, 1403.46, 1325.29, 
+  1319.27, 1331.63, 1332.49, 1472.21, 1325.58, 1311.89, 1312.22, 1480.80, 1108.58, 1245.66, 1143.69, 1163.06, 1536.72, 1239.62, 1193.78, 1265.51, 1140.02, 1461.12, 1311.68, 1260.50, 
+  1243.53, 1288.05, 1197.69, 1253.15, 1319.70, 1266.22, 1272.58, 1219.48, 1293.98, 1487.47, 1178.02, 1344.72, 1268.21, 1537.06, 1283.91, 1289.73, 1395.59, 1376.58, 1319.33, 1045.68, 
+  1310.65, 1386.68, 1532.68, 1377.28, 1279.59, 1366.86, 1403.80, 1200.92, 1189.43, 1248.40, 1591.06, 1355.88, 1377.70, 1451.58, 1480.72, 1472.42, 1246.27, 1399.85, 1400.35, 1235.28, 
+  1124.89, 1407.01, 1319.83, 1301.32, 1415.13, 1365.13, 1452.19, 1604.11, 1500.89, 1435.12, 1385.70, 1390.88, 1370.55, 1371.05, 1134.74, 1227.42, 1515.15, 1335.13, 1326.54, 1236.30, 
+  1336.05, 1528.68, 1271.89, 1289.61, 1315.37, 1554.50, 1310.00, 1258.95, 1371.55, 1340.63, 1338.41, 1482.49, 1431.91, 1526.41, 1323.51, 1506.38, 1300.72, 1450.18, 1375.10, 1555.41, 
+  1385.68, 1408.90, 1439.56, 1172.49, 1303.00, 1284.11, 1561.57, 1510.37, 1392.96, 1444.72, 1355.37, 1344.74, 1334.03, 1237.49, 1698.61, 1301.14, 1501.12, 1497.12, 1406.61, 1668.88, 
+  1271.92, 1409.82, 1568.31, 1247.27, 1268.28, 1506.07, 1487.85, 1331.96, 1308.11, 1153.87, 1349.43, 1394.82, 1370.40, 1305.67, 1238.26, 1244.13, 1212.34, 1214.01, 1057.37, 1222.82, 
+  1462.63, 1146.31, 1176.44, 1233.37, 1219.87, 1417.39, 1256.23, 1141.71, 1104.27, 1342.60, 1107.36, 1166.71, 1269.03, 1296.78, 1394.75, 1203.71, 1303.12, 1292.80, 1349.62, 1268.20, 
+  1282.37, 1365.87, 1257.10, 1301.37, 1223.24, 1357.85, 1295.40, 1080.32, 1259.42, 1103.25, 1505.06, 1378.76, 1259.55, 1407.08, 1277.81, 1274.20, 1239.76, 1259.26, 1419.32, 1290.93, 
+  1461.62, 1392.77, 1208.72, 1487.44, 1233.27, 1167.01, 1408.25, 1166.39, 1115.86, 1476.19, 1408.85, 1255.06, 1318.64, 1417.57, 1440.11, 1502.85, 1377.80, 1417.09, 1331.16, 1321.85, 
+  1168.14, 1336.71, 1255.18, 1308.91, 1564.34, 1217.88, 1191.89, 1256.18, 1238.63, 1484.72, 1428.50, 1188.80, 1197.03, 1352.54, 1233.73, 1210.42, 1334.10, 1343.73, 1344.27, 1247.66, 
+  1422.34, 1501.63, 1308.65, 1456.09, 1333.68, 1538.77, 1309.99, 1554.85, 1368.45, 1371.48, 1286.55, 1192.83, 1372.63, 1244.44, 1486.45, 1447.41, 1312.79, 1416.11, 1354.57, 1335.71, 
+  1289.82, 1212.67, 1601.19, 1401.01, 1527.72, 1468.40, 1434.39, 1541.73, 1275.53, 1436.32, 1532.78, 1246.52, 1183.33, 1431.59, 1398.14, 1389.18
+};
+
diff --git a/benchmarks/vec-matmul/dataset_test.h b/benchmarks/vec-matmul/dataset_test.h
new file mode 100644 (file)
index 0000000..8934cc8
--- /dev/null
@@ -0,0 +1,39 @@
+
+#define ARRAY_SIZE 4 
+
+
+#define DIM_SIZE 2 
+
+#if 1
+float input1_data[ARRAY_SIZE] = 
+{
+  0.37, 7.51, 5.09, 1.69
+};
+
+float input2_data[ARRAY_SIZE] = 
+{
+  4.09, 3.02, 0.02, 8.91
+};
+
+float verify_data[ARRAY_SIZE] = 
+{
+  1.65, 68.11, 20.84, 30.44
+};
+#endif
+#if 0
+float input1_data[ARRAY_SIZE] = 
+{
+  1.0, 0.0, 0.0, 0.0
+};
+
+float input2_data[ARRAY_SIZE] = 
+{
+  1.0, 0.0, 0.0, 1.0
+};
+
+float verify_data[ARRAY_SIZE] = 
+{
+  1.0, 0.0, 0.0, 0.0
+};
+#endif
+
diff --git a/benchmarks/vec-matmul/matmul_gendata.pl b/benchmarks/vec-matmul/matmul_gendata.pl
new file mode 100755 (executable)
index 0000000..c9d0ac7
--- /dev/null
@@ -0,0 +1,200 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# matmul_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the matmul benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: matmul_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "float ".$arrayName."[ARRAY_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3.2f",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+
+
+#--------------------------------------------------------------------------
+# Matmul
+#--------------------------------------------------------------------------
+
+# http://answers.oreilly.com/topic/418-how-to-multiply-matrices-in-perl/
+
+sub mmult {
+    my ($m1,$m2) = @_;
+    my ($m1rows,$m1cols) = matdim($m1);
+    my ($m2rows,$m2cols) = matdim($m2);
+
+    my $result = [  ];
+    my ($i, $j, $k);
+
+    for $i (range($m1rows)) {
+        for $j (range($m2cols)) {
+            for $k (range($m1cols)) {
+                $result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j];
+            }
+        }
+    }
+    return $result;
+}
+
+sub range { 0 .. ($_[0] - 1) }
+
+
+sub veclen {
+    my $ary_ref = $_[0];
+    my $type = ref $ary_ref;
+    if ($type ne "ARRAY") { die "$type is bad array ref for $ary_ref" }
+    return scalar(@$ary_ref);
+}
+
+sub matdim {
+    my $matrix = $_[0];
+    my $rows = veclen($matrix);
+    my $cols = veclen($matrix->[0]);
+    return ($rows, $cols);
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  # create random input arrays
+  my $mat_values1;
+  my $mat_values2;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
+      $mat_values1->[$i][$j] = (rand(9));
+      $mat_values2->[$i][$j] = (rand(9));
+    }
+  }
+
+  # perform matmul
+  my $mat_results = mmult( $mat_values1, $mat_values2 );
+  
+  # translate 2d arrays to 1d-somethings (I don't know how to code in perl - Chris)
+  my @values1;
+  my @values2;
+  my @results;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
+    my $value1 = $mat_values1->[$i][$j];
+    my $value2 = $mat_values2->[$i][$j];
+    my $result = $mat_results->[$i][$j];
+    push( @values1, $value1 );
+    push( @values2, $value2 );
+    push( @results, $result );
+    }
+  }
+
+  print "\n\#define ARRAY_SIZE ".($opts{"size"}*$opts{"size"})." \n\n";
+  print "\n\#define DIM_SIZE ".$opts{"size"}." \n\n";
+   
+  printArray( "input1_data", \@values1 );
+  printArray( "input2_data", \@values2 );
+  printArray( "verify_data", \@results);
+}
+
+main();
+
diff --git a/benchmarks/vec-matmul/vec_matmul_asm.S b/benchmarks/vec-matmul/vec_matmul_asm.S
new file mode 100644 (file)
index 0000000..f14d186
--- /dev/null
@@ -0,0 +1,345 @@
+#*****************************************************************************
+# matmul function (assembly version)
+#-----------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------
+# Headers and Defines
+#--------------------------------------------------------------------------
+
+# Here are some defines that make writing assembly code easier.
+
+# I'm using the knowledge that rLda will be placed in register a0, rA will be
+# placed into register a1, etc., based on the calling convention for functions.
+
+#define rN      a0
+#define rLda    a0
+#define rA      a1
+#define rB      a2
+#define rC      a3
+#define rATmp2  v0
+#define rBTmp2  s0
+
+        
+# given vector-length
+#define rVlen   a7
+
+# address of VT function
+#define rVTAddr v1
+#define rTemp0  a8
+
+# desired app vector length (number of elements to vectorize)
+#define rNum    a9
+
+#define rATemp  a10
+#define rBTemp  a11
+#define rCTemp  a12
+#define rI      a13
+#define rJ      s1
+#define rK      s2
+#define rLda4   a4
+#define rK4     a5
+#define rI4     a6
+        
+# WARNING: do not write to the s0,...,s9 registers without first saving them to
+# the stack!
+
+#--------------------------------------------------------------------------
+# void scalar_matmul_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+
+        .text
+        .align 2
+        .globl scalar_matmul_asm
+        .type  scalar_matmul_asm,@function
+
+scalar_matmul_asm:
+
+        # *****   Scalar Example   *****
+
+        blez rLda, done    # exit early if lda < 0
+
+        move rJ, zero
+loopj:
+        move rI, zero
+loopi:
+        move rK, zero
+loopk:
+        mul rTemp0, rJ, rLda    # calculate indices... I'm being SUPER naive here:
+        add rATemp, rK, rTemp0  #   this could be a lot more clever!
+        slli rATemp, rATemp, 2
+        add rATemp, rA, rATemp
+
+        mul rTemp0, rK, rLda
+        add rBTemp, rI, rTemp0
+        slli rBTemp, rBTemp, 2
+        add rBTemp, rB, rBTemp
+
+        mul rTemp0, rJ, rLda
+        add rCTemp, rI, rTemp0
+        slli rCTemp, rCTemp, 2
+        add rCTemp, rC, rCTemp
+
+        flw  f2, 0(rATemp)      # again, I'm being very lazy...
+                                #   I can lift this out of the inner loop!
+        flw  f3, 0(rBTemp)
+        flw  f4, 0(rCTemp)
+        fmul.s f3, f2, f3
+        fadd.s f4, f4, f3
+        fsw  f4, 0(rCTemp)
+endk:
+        addi rK, rK, 1
+        blt rK, rLda, loopk
+endi:
+        addi rI, rI, 1
+        blt rI, rLda, loopi
+endj:
+        addi rJ, rJ, 1
+        blt rJ, rLda, loopj
+done:
+        ret
+
+
+#--------------------------------------------------------------------------
+# void vt_matmul_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+
+
+        # ***** Vector-Thread Example *****
+
+        .globl vt_matmul_asm
+        .type  vt_matmul_asm,@function
+
+vt_matmul_asm:
+        addi sp, sp, -24
+        sd s0, 0(sp)
+        sd s1, 8(sp)
+        sd s2, 16(sp)
+
+        
+        # turn on vector unit
+        mfpcr a13,cr0
+        ori a13,a13,4
+        mtpcr x0,a13,cr0
+
+        blez rLda, cpdone    # exit early if lda < 0
+
+
+        la rVTAddr, vtcode
+        slli rLda4, rLda, 2
+        
+        #for starters ask for all the registers. We shouldn't need this many
+        #but we'll trim it when we have correctness in hand
+        vvcfgivl rVlen, rNum, 1, 5
+
+        
+        move rJ, zero
+vec_loopj:
+        move rI, zero
+vec_loopi:      
+        slli rI4, rI, 2
+        
+        sub rNum, rN, rI  # book keeping 
+        vsetvl rVlen, rNum   # set the vector length
+                             # rN is the desired (application) vector length
+                             # rVlen is what vector length we were given
+
+        #####################################
+        #    LOADS FOR C                    #   
+        #####################################
+        mul rTemp0, rJ, rLda4
+        add rCTemp, rI4, rTemp0
+
+        add rCTemp, rC, rCTemp
+        vflw  vf2, rCTemp
+
+        add rCTemp, rCTemp, rLda4
+        vflw  vf4, rCTemp
+
+
+        #################################
+        # address calculation lifts     #
+        #################################
+        mul rTemp0, rJ, rLda4
+        add rATmp2, rA, rTemp0
+
+        add rBTmp2, rI4, rB
+        move rK, zero
+vec_loopk:
+        slli rK4, rK, 2
+
+        #####################################
+        #    LOADS FOR A                    #   
+        #####################################
+        
+        add rATemp, rK4, rATmp2
+        vflstw  vf0, rATemp, zero       
+
+        add rATemp, rATemp, rLda4
+        vflstw  vf3, rATemp, zero
+
+
+        #####################################
+        #    LOADS FOR B                    #   
+        #####################################
+        mul rTemp0, rK, rLda4
+        add rBTemp, rBTmp2, rTemp0
+        vflw  vf1, rBTemp
+        vf 0(rVTAddr)
+
+        #####################################
+        #    LOADS FOR A                    #   
+        #####################################
+        add rATemp, rK4, rATmp2
+        addi rATemp, rATemp, 4
+        vflstw  vf0, rATemp, zero       
+
+        add rATemp, rATemp, rLda4
+        vflstw  vf3, rATemp, zero
+
+
+        #####################################
+        #    LOADS FOR B                    #   
+        #####################################
+        add rBTemp, rBTemp, rLda4
+        vflw  vf1, rBTemp
+        vf 0(rVTAddr)
+
+        #####################################
+        #    LOADS FOR A                    #   
+        #####################################
+        add rATemp, rK4, rATmp2
+        addi rATemp, rATemp, 8
+        vflstw  vf0, rATemp, zero       
+
+        add rATemp, rATemp, rLda4
+        vflstw  vf3, rATemp, zero
+
+
+        #####################################
+        #    LOADS FOR B                    #   
+        #####################################
+        add rBTemp, rBTemp, rLda4
+        vflw  vf1, rBTemp
+        vf 0(rVTAddr)
+
+
+        #####################################
+        #    LOADS FOR A                    #   
+        #####################################
+        add rATemp, rK4, rATmp2
+        addi rATemp, rATemp, 12
+        vflstw  vf0, rATemp, zero       
+
+        add rATemp, rATemp, rLda4
+        vflstw  vf3, rATemp, zero
+
+
+        #####################################
+        #    LOADS FOR B                    #   
+        #####################################
+        add rBTemp, rBTemp, rLda4
+        vflw  vf1, rBTemp
+        vf 0(rVTAddr)
+
+vec_endk:
+        addi rK, rK, 4
+        blt rK, rLda, vec_loopk
+
+vec_endi:
+        #####################################
+        #    STORES FOR C                   #   
+        #####################################
+        vfsw  vf4, rCTemp
+        sub   rCTemp, rCTemp, rLda4
+        vfsw  vf2, rCTemp
+
+        add rI, rI, rVlen
+        blt rI, rLda, vec_loopi
+vec_endj:
+        addi rJ, rJ, 2
+#       fence.v.l
+        blt rJ, rLda, vec_loopj
+
+
+cpdone:
+        fence.v.l
+        ld s0, 0(sp)
+        ld s1, 8(sp)
+        ld s2, 16(sp)
+        addi sp, sp, 24
+
+
+        ret
+
+vtcode:
+        # ADD YOUR VECTOR-ELEMENT CODE HERE ...
+
+        #TODO: hit this with a fused multiply add.
+
+        fmadd.s f2, f0, f1, f2
+        fmadd.s f4, f3, f1, f4
+        #fmadd.s f6, f5, f1, f6
+        #fmadd.s f8, f7, f1, f8
+
+        
+        #fmul.s f1, f0, f1
+        #fadd.s f2, f2, f1
+        stop
+
+transpose:
+        # turn on vector unit
+        mfpcr a13,cr0
+        ori a13,a13,4
+        mtpcr x0,a13,cr0
+
+        
+        blez rLda, cpdone    # exit early if lda < 0
+        vvcfgivl rVlen, rNum, 1, 1
+
+        move rI, zero
+tloopi:
+        sub   rNum, rLda, rI 
+        vsetvl rVlen, rNum
+
+        move rJ, zero
+tloopj:
+
+        mul rTemp0, rJ, rLda
+        add rATemp, rI, rTemp0
+        slli rATemp, rATemp, 2
+        add rATemp, rA, rATemp
+
+        mul rTemp0, rI, rLda
+        add rBTemp, rJ, rTemp0
+        slli rBTemp, rBTemp, 2
+        add rBTemp, rB, rBTemp
+
+        #flw f0, 0(rBTemp)
+        #fsw f0, 0(rATemp)
+        vflstw vf0, rBTemp, rLda4
+        vfsw   vf0, rATemp
+        
+tendj:
+        addi rJ, rJ, 1
+        blt  rJ, rLda, tloopj
+tendi:
+        #addi rI, rI, 1
+        add rI, rI, rVlen
+        blt  rI, rLda, tloopi
+
+        ret
+        # The C code uses a jalr instruction to call this function
+        # so we can use a jr to return back to where the function
+        # was called.  Also known as "ret", for "return".
+
+        ret
+
+
+
+#####################################
+#     NOPS TO AVOID OVERPREFETCH    #
+#####################################
+#       srli rTemp0, rLda, 4 
+#nop_lp:        addi rTemp0, rTemp0, -1
+#       bgez  rTemp0, nop_lp
diff --git a/benchmarks/vec-matmul/vec_matmul_main.c b/benchmarks/vec-matmul/vec_matmul_main.c
new file mode 100644 (file)
index 0000000..5de377e
--- /dev/null
@@ -0,0 +1,260 @@
+//**************************************************************************
+// Vector-Thread Vector Matrix Multiply benchmark
+//--------------------------------------------------------------------------
+//
+// This benchmark multiplies two 2-D arrays together and writes the results to
+// a third vector. The input data (and reference data) should be generated
+// using the matmul_gendata.pl perl script and dumped to a file named
+// dataset.h. The riscv-gcc toolchain does not support system calls so printf's
+// can only be used on a host system, not on the riscv-v processor simulator
+// itself. 
+//
+// HOWEVER: printstr() and printhex() are provided, for a primitive form of
+// printing strings and hexadecimal values to stdout.
+
+
+// Choose which implementation you wish to test... but leave only one on!
+// (only the first one will be executed).
+//#define SCALAR_C
+//#define SCALAR_ASM
+#define VT_ASM
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Host Platform Includes
+
+#if HOST_DEBUG
+   #include <stdio.h>
+   #include <stdlib.h>
+#else
+void printstr(const char*);
+void exit();
+#endif
+
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+//#include "dataset_test.h"
+#include "dataset.h"
+  
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, float test[], float correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] > 1.02*correct[i] 
+       || test[i] < 0.98*correct[i]) {
+#if HOST_DEBUG
+      printf("    test[%d] : %3.2f\n", i, test[i]);
+      printf("    corr[%d] : %3.2f\n", i, correct[i]);
+#endif
+      // tell us which index fails + 2
+      // (so that if i==0,i==1 fails, we don't 
+      // think it was a 'not-finished yet' or pass)
+      return i+10; 
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, float arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %03.2f ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int correct, long long num_cycles, long long num_retired )
+{
+   int toHostValue = correct;
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  // we no longer run in -testrun mode, which means we can't use
+  // the tohost register to communicate "test is done" and "test results"
+  // so instead we will communicate through print* functions!
+  if ( correct == 1 )
+  {
+    printstr( "*** PASSED *** (num_cycles = 0x" );
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  else
+  {
+    printstr( "*** FAILED *** (num_cycles = 0x");
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  exit();
+#endif
+}
+
+
+// deprecated - cr10/stats-enable register no longer exists
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+long long getCycles()
+{
+   long long cycles = 1337;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdcycle %0" : "=r" (cycles) );
+#endif
+  return cycles;
+}
+  
+long long getInstRetired()
+{
+   long long inst_retired = 1338;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdinstret %0" : "=r" (inst_retired) );
+#endif
+  return inst_retired;
+}
+
+//--------------------------------------------------------------------------
+// matmul function
+
+// scalar C implementation 
+void matmul(const int lda,  const float A[], const float B[], float C[] )
+{
+  int i, j, k;
+  
+  for ( j = 0; j < lda; j++ )  
+    for ( i = 0; i < lda; i++ )
+    {
+      float cij = C[i + j*lda];
+      for ( k = 0; k < lda; k++ ) 
+      {
+        cij += A[j*lda + k] * B[k*lda + i];
+      }
+      C[i + j*lda] = cij;
+    }
+}
+
+
+// assembly implementations can be found in *_asm.S
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  int i,j;
+  long long start_cycles = 0;
+  long long stop_cycles = 0;
+  long long num_cycles; 
+  long long start_retired = 0;
+  long long stop_retired = 0;
+  long long num_retired;
+  
+  float results_data[ARRAY_SIZE];
+  for ( i = 0; i < DIM_SIZE; i++ )
+    for ( j = 0; j < DIM_SIZE; j++ ) 
+      results_data[i + j*DIM_SIZE] = 0.0f;
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input1", ARRAY_SIZE, input1_data );
+  printArray( "input2", ARRAY_SIZE, input2_data );
+  printArray( "verify", ARRAY_SIZE, verify_data );
+  printArray( "results", ARRAY_SIZE, results_data );
+#endif
+
+  // --------------------------------------------------
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+
+
+
+#endif
+
+  // --------------------------------------------------
+  // Do the matmul
+  start_cycles = getCycles();
+  start_retired = getInstRetired();
+  
+#ifdef SCALAR_C
+  matmul( DIM_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef SCALAR_ASM
+  #if HOST_DEBUG==0
+  scalar_matmul_asm( DIM_SIZE, input1_data, input2_data, results_data );
+  #endif
+#else
+#ifdef VT_ASM
+  #if HOST_DEBUG==0
+  vt_matmul_asm( DIM_SIZE, input1_data, input2_data, results_data );
+  #endif
+#endif
+#endif
+#endif
+  
+  stop_cycles  = getCycles();
+  stop_retired = getInstRetired();
+  num_cycles = stop_cycles - start_cycles;
+  num_retired = stop_retired - start_retired;
+     
+  
+  // --------------------------------------------------
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", ARRAY_SIZE, results_data );
+#endif
+
+
+  // --------------------------------------------------
+  // Check the results
+  int correct = verify( ARRAY_SIZE, results_data, verify_data );
+  finishTest(correct, num_cycles, num_retired);
+}
diff --git a/benchmarks/vec-vvadd/bmark.mk b/benchmarks/vec-vvadd/bmark.mk
new file mode 100644 (file)
index 0000000..78ebff2
--- /dev/null
@@ -0,0 +1,30 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+vec_vvadd_c_src = \
+       vec_vvadd_main.c \
+
+vec_vvadd_riscv_src = \
+       crt.S \
+       vec_vvadd_asm.S
+
+vec_vvadd_c_objs     = $(patsubst %.c, %.o, $(vec_vvadd_c_src))
+vec_vvadd_riscv_objs = $(patsubst %.S, %.o, $(vec_vvadd_riscv_src))
+
+vec_vvadd_host_bin = vec-vvadd.host
+$(vec_vvadd_host_bin) : $(vec_vvadd_c_src)
+       $(HOST_COMP) $^ -o $(vec_vvadd_host_bin)
+
+vec_vvadd_riscv_bin = vec-vvadd.riscv
+$(vec_vvadd_riscv_bin) : $(vec_vvadd_c_objs) $(vec_vvadd_riscv_objs)
+       $(RISCV_LINK) $(RISCV_LINK_SYSCALL) $(vec_vvadd_c_objs) $(vec_vvadd_riscv_objs) -o $(vec_vvadd_riscv_bin)
+
+junk += $(vec_vvadd_c_objs) $(vec_vvadd_riscv_objs) \
+        $(vec_vvadd_host_bin) $(vec_vvadd_riscv_bin)
diff --git a/benchmarks/vec-vvadd/dataset.h b/benchmarks/vec-vvadd/dataset.h
new file mode 100644 (file)
index 0000000..83fc6b7
--- /dev/null
@@ -0,0 +1,171 @@
+
+#define DATA_SIZE 1024 
+
+float input1_data[DATA_SIZE] = 
+{
+  41.59, 833.98, 564.92, 187.40, 749.75, 350.86, 132.42, 949.90, 584.06, 805.70, 621.44, 6.57, 931.73, 890.19, 392.50, 694.30, 961.50, 110.85, 116.64, 296.64, 
+  426.15, 314.26, 659.38, 774.03, 319.50, 678.95, 875.15, 376.99, 474.52, 938.39, 539.64, 569.21, 203.10, 280.59, 759.17, 606.49, 511.73, 657.85, 195.14, 81.76, 
+  267.13, 229.11, 337.80, 944.31, 902.33, 241.76, 913.03, 826.41, 933.10, 985.95, 195.94, 960.23, 566.85, 350.87, 649.08, 657.11, 181.07, 111.93, 859.03, 65.38, 
+  288.41, 349.32, 141.62, 905.27, 886.09, 264.13, 576.69, 979.62, 761.15, 241.01, 478.77, 499.56, 403.08, 222.09, 444.00, 721.13, 676.11, 317.98, 224.02, 937.91, 
+  288.16, 119.49, 615.12, 606.02, 389.63, 351.17, 455.08, 278.19, 367.94, 358.65, 584.29, 62.81, 985.38, 403.31, 346.66, 517.64, 559.24, 908.23, 775.53, 255.22, 
+  778.76, 598.70, 143.67, 33.87, 125.22, 941.32, 933.58, 799.68, 553.00, 431.48, 648.92, 952.26, 287.81, 19.55, 49.85, 86.34, 95.37, 441.32, 587.26, 614.94, 
+  382.15, 280.93, 808.48, 971.60, 819.34, 344.75, 450.92, 512.61, 965.23, 347.78, 808.67, 882.45, 537.55, 946.57, 701.25, 356.05, 567.96, 891.59, 22.08, 568.05, 
+  665.92, 423.06, 434.34, 158.95, 2.47, 84.01, 247.70, 49.41, 435.28, 792.95, 869.12, 486.44, 414.24, 369.14, 548.71, 518.09, 888.38, 682.27, 284.83, 264.53, 
+  499.48, 290.72, 897.15, 215.27, 731.10, 688.62, 251.21, 786.26, 555.77, 302.26, 528.37, 544.63, 322.31, 947.49, 287.49, 824.15, 304.91, 788.79, 733.63, 959.89, 
+  366.53, 722.70, 294.29, 975.54, 653.47, 748.94, 91.37, 378.81, 105.56, 102.96, 381.89, 651.77, 825.56, 840.65, 356.91, 148.28, 54.55, 140.19, 955.46, 343.09, 
+  533.74, 757.52, 521.69, 837.60, 592.30, 13.14, 173.27, 63.12, 121.08, 133.74, 758.23, 372.02, 951.71, 39.51, 129.91, 110.98, 847.87, 437.05, 255.51, 269.43, 
+  409.58, 628.32, 399.16, 549.49, 753.43, 564.11, 171.44, 19.41, 727.43, 501.57, 777.90, 43.09, 753.99, 81.39, 202.47, 853.24, 153.74, 760.34, 357.21, 943.33, 
+  922.66, 328.36, 496.72, 442.71, 516.93, 641.63, 276.71, 786.16, 113.96, 842.51, 907.08, 275.40, 237.13, 32.98, 784.54, 565.19, 357.36, 803.66, 819.14, 751.19, 
+  280.22, 85.45, 458.79, 454.92, 710.83, 459.50, 41.90, 253.04, 377.89, 508.40, 700.13, 860.38, 480.43, 741.22, 499.72, 709.19, 49.82, 371.43, 873.84, 945.74, 
+  992.29, 526.88, 721.83, 435.40, 232.94, 497.20, 697.84, 30.97, 348.62, 250.71, 350.43, 250.94, 573.58, 784.02, 749.08, 502.35, 823.63, 826.56, 170.19, 160.43, 
+  674.95, 32.57, 202.49, 143.61, 853.30, 90.19, 394.67, 107.54, 855.13, 106.95, 157.48, 6.02, 765.70, 204.09, 194.97, 574.49, 218.68, 526.07, 177.51, 239.54, 
+  698.98, 757.04, 706.64, 49.59, 84.46, 799.94, 893.26, 512.93, 373.43, 492.61, 14.70, 621.34, 83.22, 103.52, 794.61, 921.52, 643.16, 880.32, 834.18, 239.95, 
+  462.18, 114.13, 561.17, 529.93, 10.30, 997.07, 904.66, 387.08, 407.57, 105.47, 559.17, 936.96, 512.84, 409.16, 302.62, 202.29, 427.86, 613.96, 359.16, 521.47, 
+  684.36, 22.07, 185.67, 312.54, 107.15, 274.79, 387.52, 242.91, 486.42, 105.59, 698.95, 899.65, 770.03, 644.88, 80.86, 161.95, 407.27, 946.13, 30.14, 768.55, 
+  870.70, 113.84, 148.93, 62.24, 147.22, 838.37, 845.09, 432.80, 141.35, 211.37, 817.36, 821.24, 562.79, 364.45, 615.83, 495.66, 812.02, 916.81, 159.62, 430.76, 
+  803.39, 180.32, 544.52, 840.69, 458.36, 786.87, 872.83, 795.63, 806.35, 758.10, 104.71, 401.72, 254.16, 984.58, 136.35, 729.51, 584.46, 794.56, 414.82, 528.59, 
+  707.41, 554.08, 378.44, 766.91, 977.14, 236.84, 947.69, 229.98, 165.43, 505.78, 105.10, 704.89, 796.28, 140.34, 303.80, 795.40, 635.19, 560.05, 119.19, 8.94, 
+  532.12, 814.18, 37.37, 584.99, 739.88, 619.35, 767.29, 478.11, 57.63, 958.75, 784.42, 985.67, 837.44, 307.64, 67.92, 824.29, 996.62, 749.22, 171.61, 826.01, 
+  621.55, 155.29, 826.10, 43.35, 694.11, 80.98, 236.29, 747.66, 744.26, 265.92, 124.29, 731.39, 941.95, 425.61, 370.26, 320.28, 269.25, 542.98, 763.36, 752.33, 
+  915.79, 14.49, 1.02, 906.26, 995.56, 809.80, 560.98, 873.76, 972.51, 289.40, 509.58, 558.76, 970.08, 405.61, 579.55, 293.55, 251.18, 849.74, 129.09, 452.87, 
+  716.20, 86.61, 678.77, 181.77, 240.86, 335.99, 793.87, 641.72, 1.47, 320.21, 987.27, 646.93, 754.87, 958.84, 203.62, 142.11, 180.16, 299.98, 165.92, 761.46, 
+  974.39, 646.84, 559.81, 619.82, 422.99, 260.82, 565.90, 542.16, 492.49, 991.70, 745.63, 207.65, 372.46, 932.61, 664.40, 34.84, 533.95, 478.47, 908.95, 203.05, 
+  33.64, 214.19, 365.78, 892.41, 781.43, 680.21, 705.21, 688.64, 947.17, 386.39, 50.40, 101.30, 474.97, 399.09, 679.01, 330.13, 952.98, 471.66, 477.47, 725.77, 
+  713.76, 937.76, 529.17, 870.41, 77.99, 545.34, 907.70, 853.57, 143.68, 979.57, 239.21, 105.80, 365.64, 98.64, 54.56, 98.04, 440.05, 764.95, 315.62, 336.77, 
+  697.12, 774.98, 726.37, 324.62, 282.73, 536.06, 622.47, 594.54, 890.74, 75.13, 290.61, 496.26, 726.27, 449.55, 548.04, 135.51, 644.61, 838.43, 290.24, 767.27, 
+  162.90, 415.87, 491.71, 985.23, 116.70, 617.91, 859.64, 235.61, 282.59, 571.64, 913.20, 560.56, 194.94, 242.05, 782.79, 985.66, 728.32, 344.06, 430.86, 613.14, 
+  759.90, 176.81, 309.64, 333.97, 354.41, 310.11, 699.67, 46.29, 487.22, 503.74, 100.74, 393.42, 268.61, 314.32, 75.11, 345.99, 987.79, 600.60, 908.74, 384.95, 
+  92.09, 545.17, 277.13, 668.55, 351.48, 853.73, 863.11, 312.76, 100.68, 532.50, 567.78, 836.25, 370.79, 989.97, 461.42, 912.55, 182.04, 268.37, 160.27, 771.80, 
+  22.69, 854.15, 644.93, 17.22, 779.43, 911.42, 855.52, 137.54, 983.70, 717.12, 565.26, 719.22, 253.48, 785.55, 154.54, 196.92, 253.81, 447.04, 899.47, 5.34, 
+  325.97, 616.42, 309.07, 175.28, 159.88, 123.45, 838.83, 715.65, 550.54, 230.32, 82.39, 627.26, 324.56, 927.11, 103.12, 17.97, 966.92, 159.09, 177.28, 593.36, 
+  372.91, 393.86, 599.09, 745.91, 377.05, 865.47, 591.44, 553.27, 440.27, 345.91, 593.69, 290.57, 908.14, 544.77, 377.87, 456.22, 781.05, 110.18, 495.91, 896.30, 
+  806.64, 700.92, 548.12, 340.34, 29.42, 829.88, 630.52, 546.09, 613.55, 972.27, 116.31, 313.81, 904.18, 971.17, 607.11, 794.60, 169.61, 896.60, 507.27, 916.31, 
+  431.26, 339.73, 147.92, 224.85, 112.36, 580.34, 834.44, 134.00, 948.54, 201.62, 488.69, 396.03, 797.99, 478.84, 769.12, 574.12, 485.10, 339.64, 721.39, 451.01, 
+  821.46, 744.32, 0.32, 594.88, 277.92, 120.10, 680.48, 757.52, 555.46, 847.72, 517.32, 379.19, 505.76, 904.86, 246.20, 243.02, 394.14, 430.59, 214.70, 244.51, 
+  524.70, 399.78, 172.96, 304.80, 620.47, 594.89, 535.34, 698.85, 159.58, 750.18, 809.80, 454.71, 76.00, 93.16, 167.76, 16.56, 853.29, 494.86, 324.64, 78.75, 
+  52.12, 112.44, 10.83, 342.60, 730.66, 680.71, 287.57, 961.30, 92.22, 626.09, 912.54, 616.39, 860.45, 744.11, 744.54, 478.60, 615.31, 508.17, 914.51, 810.39, 
+  288.65, 974.52, 129.30, 581.07, 548.96, 868.10, 981.49, 270.03, 623.03, 653.03, 626.15, 990.32, 386.70, 323.86, 472.86, 164.65, 239.77, 189.69, 865.12, 231.99, 
+  356.20, 152.84, 825.88, 328.59, 390.54, 848.08, 38.56, 402.90, 616.86, 546.07, 206.41, 2.50, 783.35, 890.15, 815.17, 831.95, 665.61, 410.53, 94.20, 246.60, 
+  422.12, 211.55, 675.13, 9.90, 374.19, 426.82, 64.89, 53.51, 758.63, 811.88, 500.64, 437.97, 335.95, 328.20, 237.48, 415.70, 468.47, 684.52, 565.24, 305.75, 
+  449.18, 597.90, 136.86, 882.80, 383.10, 938.05, 268.60, 115.02, 908.44, 50.25, 952.61, 366.36, 397.07, 257.43, 231.61, 667.39, 35.32, 990.98, 443.25, 213.68, 
+  389.05, 13.39, 621.15, 52.84, 612.70, 934.69, 953.51, 828.93, 462.31, 621.74, 812.65, 522.67, 672.37, 57.38, 313.44, 352.52, 55.66, 972.52, 753.45, 416.32, 
+  879.66, 864.63, 572.40, 163.63, 721.06, 12.23, 643.51, 507.11, 968.33, 781.67, 840.17, 242.23, 630.38, 810.57, 795.03, 435.93, 885.97, 599.49, 696.83, 643.98, 
+  93.08, 710.36, 785.04, 112.34, 581.66, 12.82, 923.01, 615.98, 652.77, 359.69, 261.90, 233.64, 609.49, 686.46, 539.88, 118.11, 560.80, 739.29, 20.45, 317.91, 
+  976.37, 573.39, 386.70, 772.54, 663.59, 504.89, 212.06, 888.98, 907.19, 420.67, 737.06, 516.55, 25.06, 219.92, 798.00, 716.93, 452.20, 692.03, 683.97, 459.81, 
+  815.55, 323.78, 612.76, 247.55, 116.16, 352.60, 281.43, 738.83, 290.13, 909.66, 645.24, 625.86, 932.73, 220.19, 685.31, 373.01, 876.04, 646.60, 412.10, 955.61, 
+  664.07, 850.22, 783.40, 392.65, 707.73, 422.19, 523.39, 682.29, 37.63, 156.05, 43.20, 767.99, 124.71, 549.18, 814.54, 251.25, 214.66, 212.34, 572.71, 898.81, 
+  956.34, 608.88, 651.21, 434.82
+};
+
+float input2_data[DATA_SIZE] = 
+{
+  454.04, 335.65, 1.77, 989.44, 365.91, 572.77, 64.10, 153.41, 216.37, 140.33, 210.68, 572.73, 339.99, 593.28, 898.42, 228.37, 12.04, 883.21, 750.17, 646.05, 
+  500.44, 436.35, 701.84, 812.45, 981.34, 150.82, 696.06, 564.27, 272.22, 258.80, 647.13, 509.06, 88.49, 703.96, 669.95, 375.24, 551.64, 936.95, 592.64, 569.16, 
+  952.14, 800.96, 584.36, 643.10, 368.06, 489.01, 328.85, 313.03, 592.75, 388.47, 543.97, 649.72, 979.53, 997.36, 814.30, 79.21, 208.54, 998.28, 629.87, 847.38, 
+  704.44, 997.07, 253.56, 715.50, 430.09, 415.56, 538.54, 700.34, 4.53, 494.85, 100.03, 864.77, 693.83, 416.61, 296.87, 285.92, 620.97, 78.51, 351.59, 540.87, 
+  646.76, 169.92, 527.62, 289.32, 796.30, 801.60, 720.50, 758.92, 745.48, 92.20, 989.02, 271.26, 853.35, 788.60, 531.96, 222.70, 461.08, 241.60, 358.39, 332.17, 
+  684.58, 740.02, 446.29, 311.97, 743.59, 557.40, 479.07, 557.42, 925.39, 796.31, 357.74, 891.05, 666.07, 514.82, 557.92, 870.02, 853.32, 440.22, 61.13, 678.78, 
+  396.53, 9.60, 17.28, 170.59, 291.21, 380.26, 536.10, 185.83, 917.13, 539.78, 983.16, 887.64, 54.78, 612.25, 951.51, 479.91, 151.50, 7.63, 641.97, 335.43, 
+  730.12, 95.14, 728.36, 280.47, 395.18, 688.69, 911.04, 476.88, 815.06, 729.61, 265.14, 127.81, 236.25, 214.41, 180.89, 6.46, 503.57, 596.12, 173.66, 643.66, 
+  346.93, 599.78, 68.90, 849.86, 658.43, 619.45, 121.67, 131.85, 828.62, 667.11, 433.76, 487.96, 753.88, 125.79, 626.75, 14.42, 10.59, 403.62, 106.00, 703.45, 
+  818.16, 964.09, 406.41, 874.40, 856.38, 86.58, 60.48, 660.95, 667.96, 153.07, 121.32, 98.11, 412.62, 236.34, 12.41, 423.64, 965.21, 216.22, 621.17, 361.66, 
+  921.78, 715.22, 647.63, 299.72, 886.82, 682.62, 36.45, 493.97, 551.05, 537.23, 969.91, 643.13, 434.31, 415.39, 303.19, 438.67, 860.46, 203.12, 478.66, 988.42, 
+  675.20, 719.24, 990.64, 338.47, 450.81, 633.17, 155.33, 646.75, 452.99, 427.23, 509.17, 988.99, 426.10, 12.74, 483.26, 142.23, 339.79, 390.81, 50.95, 171.16, 
+  601.54, 105.47, 968.89, 121.26, 879.98, 81.89, 870.32, 600.55, 603.29, 871.73, 887.50, 610.56, 404.65, 234.16, 745.69, 526.44, 275.51, 441.57, 226.96, 752.86, 
+  943.47, 726.29, 709.63, 201.25, 54.32, 758.41, 53.13, 397.79, 41.32, 141.48, 416.24, 747.81, 219.98, 478.11, 770.83, 180.06, 482.88, 691.56, 725.10, 173.62, 
+  186.07, 914.28, 1.64, 963.17, 248.00, 464.70, 362.43, 521.93, 233.68, 120.84, 40.89, 779.34, 195.43, 161.24, 743.15, 439.32, 355.84, 403.26, 141.52, 633.14, 
+  289.43, 782.40, 320.03, 636.26, 118.73, 852.98, 70.84, 816.16, 388.16, 954.73, 36.04, 16.68, 698.34, 695.97, 677.21, 598.79, 883.95, 824.68, 746.81, 462.54, 
+  511.64, 534.37, 440.30, 428.71, 732.86, 726.51, 702.51, 547.02, 86.52, 798.67, 215.32, 21.88, 651.12, 59.56, 429.73, 657.72, 96.84, 973.02, 659.46, 966.03, 
+  524.36, 62.55, 625.28, 303.09, 714.64, 409.32, 55.49, 728.91, 305.61, 436.34, 901.67, 592.86, 691.16, 796.54, 497.10, 177.90, 940.76, 995.51, 480.97, 158.27, 
+  822.18, 611.21, 680.54, 14.69, 111.64, 797.48, 185.26, 0.42, 718.99, 96.96, 749.66, 739.06, 814.08, 435.19, 326.74, 37.87, 33.93, 605.81, 935.30, 27.08, 
+  88.64, 441.48, 339.35, 344.49, 554.29, 365.36, 954.73, 639.24, 396.74, 991.69, 249.37, 338.14, 832.96, 974.16, 393.61, 266.20, 470.51, 348.21, 336.49, 419.51, 
+  249.26, 215.93, 542.52, 903.45, 636.50, 729.85, 581.11, 820.51, 671.78, 979.39, 418.16, 670.72, 920.09, 568.34, 745.07, 662.81, 139.00, 385.86, 927.79, 173.18, 
+  457.31, 316.41, 183.92, 477.45, 196.33, 399.89, 416.39, 805.73, 996.26, 270.14, 735.50, 696.71, 825.63, 528.63, 50.72, 623.80, 537.51, 87.46, 294.50, 867.57, 
+  110.26, 398.60, 781.21, 646.64, 375.13, 943.34, 897.04, 589.48, 44.54, 288.17, 845.33, 742.83, 99.00, 522.57, 443.74, 432.33, 165.91, 930.88, 28.94, 461.66, 
+  323.98, 272.51, 376.62, 340.73, 898.14, 158.37, 168.75, 443.51, 193.73, 631.20, 935.89, 274.02, 781.65, 185.57, 619.86, 292.35, 933.33, 156.41, 827.37, 88.76, 
+  987.54, 629.48, 649.02, 32.15, 1.18, 744.89, 399.21, 915.37, 791.96, 554.59, 984.10, 530.66, 600.58, 401.77, 683.13, 540.36, 903.94, 120.85, 995.87, 521.86, 
+  622.16, 224.65, 895.32, 530.33, 820.81, 651.71, 226.16, 96.13, 262.91, 569.20, 238.65, 126.49, 610.86, 191.60, 238.92, 796.97, 884.59, 573.09, 108.00, 140.59, 
+  789.76, 852.96, 23.71, 704.58, 890.76, 480.51, 52.78, 372.43, 201.01, 546.61, 408.85, 119.89, 645.63, 464.84, 81.80, 293.26, 52.40, 880.11, 224.02, 744.84, 
+  735.53, 886.00, 167.35, 1.88, 532.19, 321.39, 169.10, 485.71, 101.72, 177.67, 42.92, 708.17, 654.57, 915.79, 625.69, 242.14, 822.84, 795.34, 641.04, 252.42, 
+  245.63, 151.34, 876.43, 333.05, 601.06, 938.92, 775.05, 397.50, 233.79, 755.78, 454.06, 424.44, 210.01, 962.37, 900.93, 923.02, 655.46, 529.87, 595.01, 90.89, 
+  464.89, 685.58, 70.44, 754.90, 32.51, 494.81, 25.80, 389.38, 488.21, 37.40, 409.08, 639.86, 27.63, 950.87, 539.51, 80.51, 303.34, 723.69, 734.88, 125.98, 
+  552.69, 248.59, 107.29, 362.31, 48.68, 869.57, 144.74, 841.18, 724.89, 335.10, 470.53, 263.38, 343.02, 809.49, 677.01, 339.36, 336.03, 410.43, 465.15, 56.81, 
+  590.66, 485.63, 406.57, 993.51, 746.33, 238.91, 525.16, 336.30, 256.11, 134.76, 546.41, 722.96, 367.62, 943.94, 106.51, 629.33, 396.50, 208.74, 429.60, 523.82, 
+  130.87, 355.83, 990.83, 673.36, 991.28, 719.97, 449.14, 84.94, 616.26, 211.40, 707.51, 737.36, 847.35, 452.81, 316.11, 974.19, 746.34, 796.57, 522.31, 618.19, 
+  115.11, 727.59, 226.00, 165.86, 200.08, 830.23, 742.47, 187.65, 705.02, 671.77, 785.22, 886.33, 962.57, 657.86, 293.97, 620.08, 144.34, 173.29, 796.21, 72.50, 
+  678.01, 80.06, 793.33, 685.03, 637.56, 967.37, 241.53, 898.52, 693.00, 372.64, 601.23, 721.30, 398.50, 553.18, 72.92, 174.85, 978.42, 325.01, 558.77, 185.25, 
+  505.93, 860.00, 651.31, 573.60, 321.32, 349.19, 400.24, 890.35, 844.52, 885.04, 933.02, 980.84, 448.61, 989.45, 50.53, 332.36, 900.28, 716.93, 747.86, 444.23, 
+  6.62, 394.55, 285.73, 703.44, 450.70, 652.55, 771.82, 485.17, 534.56, 559.01, 481.51, 507.24, 434.52, 343.63, 42.42, 784.26, 865.65, 421.89, 415.22, 871.79, 
+  539.58, 162.47, 105.09, 481.92, 595.44, 115.11, 350.01, 964.58, 287.38, 232.55, 154.11, 602.37, 539.48, 943.16, 872.17, 121.26, 652.20, 811.95, 747.88, 362.25, 
+  340.41, 910.73, 206.71, 572.95, 505.78, 973.87, 961.61, 354.74, 627.25, 849.72, 971.69, 910.80, 410.29, 770.61, 63.75, 874.84, 396.21, 482.65, 619.93, 646.52, 
+  557.70, 328.81, 67.74, 884.16, 512.52, 972.25, 6.13, 513.12, 882.90, 562.88, 764.78, 366.50, 506.01, 786.96, 831.46, 382.69, 638.33, 452.86, 72.80, 83.99, 
+  59.48, 932.56, 929.17, 924.31, 961.79, 69.09, 797.94, 985.49, 854.03, 885.08, 600.77, 389.36, 232.77, 793.58, 179.91, 773.67, 689.88, 775.80, 494.89, 139.65, 
+  234.41, 431.79, 780.34, 371.94, 22.47, 653.95, 741.81, 815.30, 429.00, 139.33, 603.92, 315.04, 344.80, 889.48, 317.27, 260.28, 861.63, 377.78, 511.76, 304.06, 
+  70.19, 35.87, 854.09, 576.98, 490.35, 326.55, 303.50, 431.21, 813.10, 708.96, 388.67, 962.18, 967.95, 442.52, 49.02, 831.49, 251.65, 321.36, 741.45, 179.51, 
+  176.27, 117.00, 523.73, 764.26, 952.82, 704.67, 531.80, 804.94, 23.61, 611.10, 846.79, 375.26, 854.69, 971.77, 24.05, 639.17, 318.66, 723.53, 662.84, 647.47, 
+  281.11, 158.85, 294.58, 885.85, 734.06, 866.60, 471.06, 296.09, 673.55, 472.93, 439.09, 5.93, 155.39, 506.79, 948.50, 600.40, 445.21, 222.05, 784.59, 349.77, 
+  943.37, 150.14, 366.16, 444.22, 604.60, 720.40, 340.70, 972.58, 911.45, 321.49, 435.22, 50.43, 78.96, 761.04, 950.33, 238.41, 27.06, 226.17, 201.43, 176.53, 
+  877.51, 450.94, 879.63, 99.89, 143.28, 31.66, 812.36, 771.31, 527.29, 488.63, 797.10, 194.25, 293.72, 966.52, 276.35, 345.26, 413.02, 197.52, 386.04, 116.36, 
+  322.72, 680.35, 538.15, 554.00, 960.31, 874.79, 48.72, 506.93, 898.24, 539.71, 495.50, 764.01, 805.12, 286.44, 432.09, 836.98, 192.15, 825.36, 778.42, 586.55, 
+  359.37, 352.70, 746.78, 11.34, 749.69, 5.98, 408.76, 643.32, 441.94, 368.15, 97.74, 169.62, 359.25, 527.49, 672.31, 69.39, 880.66, 298.11, 300.84, 327.09, 
+  923.83, 829.55, 816.51, 497.50, 243.91, 981.12, 917.21, 713.38, 653.91, 503.75, 406.65, 543.57, 108.87, 304.66, 464.10, 954.74, 86.37, 802.71, 446.02, 28.16, 
+  539.76, 655.37, 28.71, 470.59, 735.85, 941.08, 610.37, 451.33, 672.34, 237.47, 766.04, 713.35, 409.69, 869.06, 186.75, 475.83, 568.73, 44.08, 997.88, 139.85, 
+  456.29, 470.05, 566.52, 408.79
+};
+
+float verify_data[DATA_SIZE] = 
+{
+  495.63, 1169.63, 566.69, 1176.85, 1115.65, 923.63, 196.52, 1103.31, 800.44, 946.03, 832.12, 579.30, 1271.72, 1483.47, 1290.93, 922.67, 973.54, 994.06, 866.81, 942.68, 
+  926.59, 750.61, 1361.22, 1586.49, 1300.84, 829.78, 1571.21, 941.26, 746.74, 1197.19, 1186.78, 1078.26, 291.58, 984.55, 1429.12, 981.74, 1063.38, 1594.80, 787.78, 650.92, 
+  1219.28, 1030.07, 922.15, 1587.41, 1270.39, 730.77, 1241.89, 1139.44, 1525.85, 1374.42, 739.91, 1609.95, 1546.39, 1348.24, 1463.38, 736.32, 389.61, 1110.21, 1488.91, 912.76, 
+  992.84, 1346.40, 395.18, 1620.78, 1316.18, 679.69, 1115.23, 1679.96, 765.68, 735.85, 578.79, 1364.33, 1096.91, 638.70, 740.87, 1007.04, 1297.08, 396.49, 575.61, 1478.78, 
+  934.92, 289.41, 1142.74, 895.34, 1185.93, 1152.77, 1175.57, 1037.12, 1113.42, 450.84, 1573.31, 334.07, 1838.73, 1191.90, 878.61, 740.34, 1020.32, 1149.83, 1133.92, 587.39, 
+  1463.34, 1338.72, 589.95, 345.84, 868.80, 1498.73, 1412.65, 1357.10, 1478.39, 1227.79, 1006.65, 1843.31, 953.88, 534.37, 607.77, 956.35, 948.69, 881.54, 648.39, 1293.73, 
+  778.68, 290.54, 825.76, 1142.18, 1110.55, 725.01, 987.02, 698.44, 1882.36, 887.56, 1791.84, 1770.09, 592.34, 1558.82, 1652.77, 835.96, 719.46, 899.23, 664.05, 903.48, 
+  1396.04, 518.20, 1162.70, 439.42, 397.65, 772.71, 1158.74, 526.29, 1250.34, 1522.57, 1134.26, 614.25, 650.49, 583.54, 729.60, 524.55, 1391.95, 1278.39, 458.49, 908.20, 
+  846.41, 890.50, 966.06, 1065.12, 1389.53, 1308.07, 372.88, 918.11, 1384.40, 969.38, 962.13, 1032.60, 1076.19, 1073.28, 914.24, 838.56, 315.50, 1192.41, 839.63, 1663.34, 
+  1184.70, 1686.79, 700.69, 1849.94, 1509.85, 835.52, 151.84, 1039.76, 773.51, 256.03, 503.21, 749.88, 1238.18, 1076.99, 369.33, 571.92, 1019.76, 356.41, 1576.64, 704.75, 
+  1455.51, 1472.74, 1169.31, 1137.32, 1479.12, 695.76, 209.72, 557.09, 672.13, 670.97, 1728.14, 1015.15, 1386.02, 454.90, 433.10, 549.65, 1708.33, 640.17, 734.17, 1257.85, 
+  1084.79, 1347.56, 1389.80, 887.96, 1204.24, 1197.28, 326.78, 666.15, 1180.43, 928.80, 1287.07, 1032.07, 1180.09, 94.13, 685.73, 995.48, 493.52, 1151.15, 408.17, 1114.49, 
+  1524.20, 433.83, 1465.62, 563.97, 1396.91, 723.51, 1147.02, 1386.71, 717.25, 1714.24, 1794.58, 885.95, 641.78, 267.14, 1530.24, 1091.63, 632.86, 1245.24, 1046.10, 1504.05, 
+  1223.69, 811.73, 1168.43, 656.17, 765.15, 1217.91, 95.02, 650.84, 419.21, 649.88, 1116.37, 1608.19, 700.41, 1219.33, 1270.55, 889.25, 532.70, 1062.99, 1598.94, 1119.37, 
+  1178.37, 1441.16, 723.46, 1398.57, 480.94, 961.90, 1060.27, 552.90, 582.30, 371.55, 391.32, 1030.28, 769.01, 945.25, 1492.23, 941.67, 1179.47, 1229.81, 311.71, 793.56, 
+  964.38, 814.96, 522.52, 779.87, 972.03, 943.17, 465.51, 923.71, 1243.30, 1061.68, 193.53, 22.70, 1464.04, 900.06, 872.18, 1173.28, 1102.63, 1350.75, 924.32, 702.08, 
+  1210.63, 1291.41, 1146.94, 478.30, 817.32, 1526.45, 1595.77, 1059.94, 459.94, 1291.29, 230.02, 643.22, 734.35, 163.08, 1224.35, 1579.24, 739.99, 1853.34, 1493.65, 1205.98, 
+  986.54, 176.68, 1186.45, 833.02, 724.94, 1406.38, 960.15, 1115.99, 713.18, 541.81, 1460.84, 1529.83, 1204.00, 1205.70, 799.72, 380.19, 1368.62, 1609.47, 840.13, 679.74, 
+  1506.54, 633.28, 866.21, 327.23, 218.80, 1072.27, 572.78, 243.33, 1205.41, 202.56, 1448.61, 1638.72, 1584.11, 1080.07, 407.61, 199.82, 441.20, 1551.94, 965.44, 795.64, 
+  959.34, 555.31, 488.27, 406.73, 701.51, 1203.74, 1799.83, 1072.04, 538.08, 1203.05, 1066.74, 1159.37, 1395.75, 1338.61, 1009.44, 761.86, 1282.53, 1265.02, 496.10, 850.27, 
+  1052.65, 396.25, 1087.04, 1744.14, 1094.86, 1516.72, 1453.94, 1616.13, 1478.13, 1737.48, 522.87, 1072.44, 1174.25, 1552.93, 881.42, 1392.32, 723.46, 1180.41, 1342.61, 701.77, 
+  1164.72, 870.50, 562.36, 1244.36, 1173.48, 636.73, 1364.08, 1035.71, 1161.69, 775.92, 840.61, 1401.61, 1621.91, 668.97, 354.52, 1419.21, 1172.70, 647.51, 413.69, 876.51, 
+  642.38, 1212.78, 818.58, 1231.63, 1115.00, 1562.69, 1664.33, 1067.59, 102.18, 1246.92, 1629.75, 1728.50, 936.44, 830.21, 511.66, 1256.62, 1162.52, 1680.10, 200.55, 1287.67, 
+  945.54, 427.81, 1202.72, 384.08, 1592.24, 239.35, 405.04, 1191.17, 937.99, 897.12, 1060.18, 1005.41, 1723.60, 611.18, 990.11, 612.63, 1202.58, 699.39, 1590.74, 841.09, 
+  1903.33, 643.97, 650.04, 938.41, 996.74, 1554.70, 960.19, 1789.12, 1764.47, 843.99, 1493.67, 1089.42, 1570.66, 807.37, 1262.68, 833.91, 1155.12, 970.59, 1124.96, 974.72, 
+  1338.35, 311.26, 1574.08, 712.10, 1061.67, 987.70, 1020.03, 737.85, 264.38, 889.41, 1225.92, 773.42, 1365.73, 1150.43, 442.54, 939.08, 1064.75, 873.07, 273.93, 902.05, 
+  1764.15, 1499.80, 583.52, 1324.39, 1313.75, 741.33, 618.68, 914.59, 693.50, 1538.31, 1154.48, 327.54, 1018.09, 1397.45, 746.21, 328.09, 586.35, 1358.57, 1132.98, 947.89, 
+  769.17, 1100.19, 533.13, 894.29, 1313.62, 1001.59, 874.31, 1174.35, 1048.89, 564.06, 93.33, 809.48, 1129.55, 1314.88, 1304.70, 572.27, 1775.82, 1267.01, 1118.51, 978.19, 
+  959.40, 1089.10, 1405.59, 1203.46, 679.05, 1484.27, 1682.75, 1251.06, 377.47, 1735.35, 693.27, 530.23, 575.65, 1061.01, 955.49, 1021.06, 1095.51, 1294.81, 910.64, 427.66, 
+  1162.01, 1460.55, 796.81, 1079.52, 315.24, 1030.87, 648.27, 983.92, 1378.95, 112.53, 699.70, 1136.13, 753.89, 1400.42, 1087.55, 216.02, 947.95, 1562.12, 1025.12, 893.25, 
+  715.59, 664.46, 599.00, 1347.54, 165.38, 1487.48, 1004.37, 1076.79, 1007.48, 906.74, 1383.74, 823.94, 537.97, 1051.54, 1459.79, 1325.02, 1064.35, 754.49, 896.01, 669.95, 
+  1350.57, 662.43, 716.21, 1327.48, 1100.74, 549.02, 1224.82, 382.59, 743.32, 638.50, 647.15, 1116.38, 636.23, 1258.26, 181.62, 975.32, 1384.29, 809.34, 1338.34, 908.77, 
+  222.96, 901.00, 1267.96, 1341.91, 1342.76, 1573.69, 1312.25, 397.71, 716.94, 743.90, 1275.29, 1573.61, 1218.13, 1442.78, 777.53, 1886.74, 928.38, 1064.95, 682.57, 1389.99, 
+  137.80, 1581.75, 870.93, 183.08, 979.51, 1741.65, 1598.00, 325.19, 1688.71, 1388.89, 1350.48, 1605.55, 1216.06, 1443.41, 448.51, 816.99, 398.15, 620.33, 1695.69, 77.84, 
+  1003.98, 696.49, 1102.40, 860.31, 797.44, 1090.82, 1080.36, 1614.18, 1243.54, 602.96, 683.61, 1348.56, 723.06, 1480.29, 176.04, 192.82, 1945.34, 484.10, 736.05, 778.60, 
+  878.83, 1253.86, 1250.40, 1319.50, 698.36, 1214.66, 991.67, 1443.62, 1284.79, 1230.94, 1526.71, 1271.40, 1356.76, 1534.22, 428.41, 788.58, 1681.33, 827.11, 1243.77, 1340.54, 
+  813.27, 1095.47, 833.86, 1043.78, 480.13, 1482.43, 1402.35, 1031.26, 1148.11, 1531.28, 597.82, 821.05, 1338.69, 1314.80, 649.53, 1578.87, 1035.26, 1318.49, 922.49, 1788.10, 
+  970.84, 502.20, 253.02, 706.77, 707.80, 695.45, 1184.45, 1098.58, 1235.92, 434.17, 642.81, 998.40, 1337.46, 1422.00, 1641.30, 695.39, 1137.30, 1151.58, 1469.27, 813.26, 
+  1161.87, 1655.05, 207.04, 1167.83, 783.70, 1093.98, 1642.08, 1112.26, 1182.71, 1697.44, 1489.02, 1289.98, 916.05, 1675.47, 309.95, 1117.86, 790.35, 913.24, 834.63, 891.03, 
+  1082.40, 728.59, 240.69, 1188.95, 1132.99, 1567.14, 541.47, 1211.96, 1042.48, 1313.06, 1574.58, 821.21, 582.01, 880.12, 999.23, 399.25, 1491.61, 947.72, 397.45, 162.75, 
+  111.60, 1045.00, 940.01, 1266.90, 1692.45, 749.80, 1085.51, 1946.78, 946.25, 1511.17, 1513.31, 1005.75, 1093.23, 1537.69, 924.45, 1252.27, 1305.19, 1283.97, 1409.40, 950.03, 
+  523.06, 1406.31, 909.64, 953.01, 571.43, 1522.05, 1723.30, 1085.33, 1052.03, 792.36, 1230.06, 1305.36, 731.50, 1213.35, 790.13, 424.94, 1101.40, 567.48, 1376.87, 536.06, 
+  426.39, 188.71, 1679.97, 905.57, 880.88, 1174.62, 342.05, 834.11, 1429.95, 1255.03, 595.08, 964.68, 1751.30, 1332.67, 864.20, 1663.44, 917.26, 731.89, 835.65, 426.11, 
+  598.39, 328.55, 1198.86, 774.17, 1327.00, 1131.50, 596.69, 858.45, 782.24, 1422.98, 1347.43, 813.23, 1190.64, 1299.97, 261.53, 1054.87, 787.13, 1408.05, 1228.08, 953.22, 
+  730.28, 756.75, 431.44, 1768.64, 1117.16, 1804.65, 739.66, 411.11, 1581.98, 523.18, 1391.70, 372.29, 552.46, 764.22, 1180.11, 1267.78, 480.53, 1213.03, 1227.84, 563.46, 
+  1332.42, 163.53, 987.30, 497.06, 1217.30, 1655.09, 1294.21, 1801.51, 1373.76, 943.23, 1247.88, 573.11, 751.33, 818.42, 1263.77, 590.93, 82.72, 1198.69, 954.88, 592.85, 
+  1757.16, 1315.57, 1452.03, 263.52, 864.34, 43.90, 1455.87, 1278.42, 1495.61, 1270.29, 1637.27, 436.48, 924.10, 1777.09, 1071.38, 781.19, 1298.99, 797.01, 1082.87, 760.34, 
+  415.80, 1390.71, 1323.19, 666.33, 1541.97, 887.62, 971.73, 1122.91, 1551.00, 899.40, 757.40, 997.65, 1414.61, 972.90, 971.97, 955.10, 752.96, 1564.64, 798.87, 904.46, 
+  1335.73, 926.08, 1133.48, 783.88, 1413.28, 510.87, 620.83, 1532.29, 1349.13, 788.82, 834.80, 686.17, 384.31, 747.41, 1470.31, 786.32, 1332.86, 990.15, 984.81, 786.91, 
+  1739.38, 1153.33, 1429.27, 745.05, 360.07, 1333.72, 1198.64, 1452.21, 944.04, 1413.41, 1051.90, 1169.43, 1041.60, 524.85, 1149.41, 1327.75, 962.41, 1449.32, 858.12, 983.77, 
+  1203.83, 1505.59, 812.11, 863.24, 1443.57, 1363.27, 1133.76, 1133.62, 709.97, 393.53, 809.24, 1481.34, 534.41, 1418.23, 1001.29, 727.08, 783.39, 256.43, 1570.59, 1038.65, 
+  1412.63, 1078.93, 1217.72, 843.61
+};
+
diff --git a/benchmarks/vec-vvadd/dataset_test.h b/benchmarks/vec-vvadd/dataset_test.h
new file mode 100644 (file)
index 0000000..5917aea
--- /dev/null
@@ -0,0 +1,18 @@
+
+#define DATA_SIZE 4 
+
+float input1_data[DATA_SIZE] = 
+{
+  41.59, 833.98, 564.92, 187.40
+};
+
+float input2_data[DATA_SIZE] = 
+{
+  454.04, 335.65, 1.77, 989.44
+};
+
+float verify_data[DATA_SIZE] = 
+{
+  495.63, 1169.63, 566.69, 1176.85
+};
+
diff --git a/benchmarks/vec-vvadd/vec_vvadd_asm.S b/benchmarks/vec-vvadd/vec_vvadd_asm.S
new file mode 100644 (file)
index 0000000..2e74436
--- /dev/null
@@ -0,0 +1,108 @@
+#*****************************************************************************
+# vvadd function (assembly version)
+#-----------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------
+# Headers and Defines
+#--------------------------------------------------------------------------
+
+# Here are some defines that make writing assembly code easier.
+
+# I'm using the knowledge that rN will be placed in register a0, rA will be
+# placed into register a1, etc., based on the calling convention for functions.
+
+#define rN      a0
+#define rA      a1
+#define rB      a2
+#define rC      a3
+
+#define rVLen   a4
+
+# WARNING: do not write to the s0,...,s9 registers without first saving them to
+# the stack.  
+
+#--------------------------------------------------------------------------
+# void scalar_vvadd_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+
+        .text
+        .align 2
+        .globl scalar_vvadd_asm
+        .type  scalar_vvadd_asm,@function
+
+scalar_vvadd_asm:
+
+        # *****   Scalar Example   *****
+
+        beq rN, zero, done    # exit early if n == 0 
+
+loop:
+        flw  f2, 0(rA)  
+        flw  f3, 0(rB)  
+        fadd.s f2, f2, f3
+        fsw  f2, 0(rC)  
+        addi rN, rN, -1
+        addi rA, rA, 4 
+        addi rB, rB, 4 
+        addi rC, rC, 4 
+        bne  rN, zero, loop
+done:
+        ret
+
+              
+#--------------------------------------------------------------------------
+# void vt_vvadd_asm( int n, float a[], float b[], float c[] )
+#--------------------------------------------------------------------------
+              
+
+        # ***** Vector-Thread Example *****
+
+        .globl vt_vvadd_asm
+        .type  vt_vvadd_asm,@function
+
+vt_vvadd_asm:
+
+        beq rN, zero, cpdone  
+        la a5, vtcode
+
+        # First, configure the vector unit.
+        # rd (given vlen), desired vlen, num of x-regs, num of f-regs
+        # For vvadd, we do not need to use any x-registers, and only two
+        # floating point registers. By using fewer registers, hwacha can give us a longer vector length!
+        # But make sure to use registers starting from x0, f0!
+        # WARNING: there is a BUG if you tell it you want 0 registers of any type!
+        # So here I'm asking for 1 x-register, even though I don't use any of them.
+        vvcfgivl rVLen, rN, 1, 2  
+                                  
+
+stripmineloop:
+        vsetvl rVLen, rN   # set the vector length 
+                           # rN is the desired (application) vector length
+                           # rVLen is what vector length we were given
+
+        vflw vf0, rA       # vector loads
+        vflw vf1, rB  
+        vf 0(a5)           # jump to vector-fetch code
+        vfsw vf0, rC       # vector store
+        
+        sub rN, rN, rVLen  # book keeping 
+        slli a6, rVLen, 2  # turn num_elements into num_bytes
+        add rA, rA, a6 
+        add rB, rB, a6 
+        add rC, rC, a6 
+        bne rN, zero, stripmineloop
+
+cpdone:    
+        fence.v.l          # make stores visible to the control processor
+        ret
+
+vtcode:
+        fadd.s f0, f0, f1   
+        stop
+        
+        # The C code uses a jalr instruction to call this function
+        # so we can use a jr to return back to where the function
+        # was called.  Also known as "ret", for "return".
+
+        ret
diff --git a/benchmarks/vec-vvadd/vec_vvadd_main.c b/benchmarks/vec-vvadd/vec_vvadd_main.c
new file mode 100644 (file)
index 0000000..c08e41a
--- /dev/null
@@ -0,0 +1,255 @@
+//**************************************************************************
+// Vector-Thread Vector-vector add benchmark
+//--------------------------------------------------------------------------
+//
+// This benchmark uses adds to vectors and writes the results to a third
+// vector. The input data (and reference data) should be generated using the
+// vvadd_gendata.pl perl script and dumped to a file named dataset.h. The
+// riscv-gcc toolchain does not support system calls so printf's can only be
+// used on a host system, not on the riscv-v processor simulator itself. 
+//
+// HOWEVER: printstr() and printhex() are provided, for a primitive form of
+// printing strings and hexadecimal values to stdout.
+
+
+// Choose which implementation you wish to test... but leave only one on!
+// (only the first one will be executed).
+//#define SCALAR_C
+//#define SCALAR_ASM
+#define VT_ASM
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Platform Specific Includes
+
+#if HOST_DEBUG
+   #include <stdio.h>
+   #include <stdlib.h>
+#else
+void printstr(const char*);
+void exit();
+#endif
+
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+//#include "dataset_test.h"
+#include "dataset.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, float test[], float correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+//    if ( test[i] != correct[i] ) {
+    if ( test[i] > 1.02*correct[i] 
+       || test[i] < 0.98*correct[i]) {
+#if HOST_DEBUG
+      printf("    test[%d] : %3.2f\n", i, test[i]);
+      printf("    corr[%d] : %3.2f\n", i, correct[i]);
+#endif
+      // tell us which index fails + 2
+      // (so that if i==0,i==1 fails, we don't 
+      // think it was a 'not-finished yet' or pass)
+//      return i+10; 
+      return 2; 
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, float arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %03.2f ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int correct, long long num_cycles, long long num_retired )
+{
+   int toHostValue = correct;
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  // we no longer run in -testrun mode, which means we can't use
+  // the tohost register to communicate "test is done" and "test results"
+  // so instead we will communicate through print* functions!
+  if ( correct == 1 )
+  {
+    printstr( "*** PASSED *** (num_cycles = 0x" );
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  else
+  {
+    printstr( "*** FAILED *** (num_cycles = 0x");
+    printhex(num_cycles);
+    printstr( ", num_inst_retired = 0x");
+    printhex(num_retired);
+    printstr( ")\n" );
+  }
+  exit();
+#endif
+}
+
+// deprecated - cr10/stats-enable register no longer exists
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+long long getCycles()
+{
+   long long cycles = 1337;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdcycle %0" : "=r" (cycles) );
+#endif
+  return cycles;
+}
+          
+long long getInstRetired()
+{
+   long long inst_retired = 1338;
+#if ( !HOST_DEBUG && SET_STATS )
+  __asm__ __volatile__( "rdinstret %0" : "=r" (inst_retired) );
+#endif
+  return inst_retired;
+}
+          
+//--------------------------------------------------------------------------
+// vvadd function
+
+// scalar C implementation 
+void vvadd( int n, float a[], float b[], float c[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ )
+    c[i] = a[i] + b[i];
+}
+
+// assembly implementations can be found in *_asm.S
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  float results_data[DATA_SIZE];
+  long long start_cycles = 0;
+  long long stop_cycles = 0;
+  long long num_cycles; 
+  long long start_retired = 0;
+  long long stop_retired = 0;
+  long long num_retired;
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input1", DATA_SIZE, input1_data );
+  printArray( "input2", DATA_SIZE, input2_data );
+  printArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+  // --------------------------------------------------
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+  
+#ifdef SCALAR_C
+  vvadd( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef SCALAR_ASM
+  scalar_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef VT_ASM
+  vt_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
+#endif
+#endif
+#endif
+
+#endif
+
+  // --------------------------------------------------
+  // Do the vvadd
+  start_cycles = getCycles();
+  start_retired = getInstRetired();
+
+#ifdef SCALAR_C
+  vvadd( DATA_SIZE, input1_data, input2_data, results_data );
+#else
+#ifdef SCALAR_ASM
+  #if HOST_DEBUG==0
+  scalar_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
+  #endif
+#else
+#ifdef VT_ASM
+  #if HOST_DEBUG==0
+  vt_vvadd_asm( DATA_SIZE, input1_data, input2_data, results_data );
+  #endif
+#endif
+#endif
+#endif
+  
+  stop_cycles  = getCycles();
+  stop_retired = getInstRetired();
+  num_cycles = stop_cycles - start_cycles;
+  num_retired = stop_retired - start_retired;
+
+//  printstr("stop_cycles: "); printhex(stop_cycles); printstr("\n");
+//  printstr("star_cycles: "); printhex(start_cycles); printstr("\n");
+
+  // --------------------------------------------------
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", DATA_SIZE, results_data );
+#endif
+
+  // --------------------------------------------------
+  // Check the results
+  int correct = verify( DATA_SIZE, results_data, verify_data );
+  finishTest(correct, num_cycles, num_retired);
+}
diff --git a/benchmarks/vec-vvadd/vvadd_gendata.pl b/benchmarks/vec-vvadd/vvadd_gendata.pl
new file mode 100755 (executable)
index 0000000..10fc4e9
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# vvadd_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the vvadd benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: vvadd_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "float ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3.2f",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3.2f",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values1;
+  my @values2;
+  my @sum;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    my $value1 = (rand(999));
+    my $value2 = (rand(999));
+    push( @values1, $value1 );
+    push( @values2, $value2 );
+    push( @sum, $value1 + $value2 );
+  }
+
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input1_data", \@values1 );
+  printArray( "input2_data", \@values2 );
+  printArray( "verify_data", \@sum );
+
+}
+
+main();
+
diff --git a/benchmarks/vvadd/bmark.mk b/benchmarks/vvadd/bmark.mk
new file mode 100644 (file)
index 0000000..d03cb96
--- /dev/null
@@ -0,0 +1,29 @@
+#=======================================================================
+# UCB CS250 Makefile fragment for benchmarks
+#-----------------------------------------------------------------------
+#
+# Each benchmark directory should have its own fragment which
+# essentially lists what the source files are and how to link them
+# into an riscv and/or host executable. All variables should include
+# the benchmark name as a prefix so that they are unique.
+#
+
+vvadd_c_src = \
+       vvadd_main.c \
+
+vvadd_riscv_src = \
+       crt.S \
+
+vvadd_c_objs     = $(patsubst %.c, %.o, $(vvadd_c_src))
+vvadd_riscv_objs = $(patsubst %.S, %.o, $(vvadd_riscv_src))
+
+vvadd_host_bin = vvadd.host
+$(vvadd_host_bin) : $(vvadd_c_src)
+       $(HOST_COMP) $^ -o $(vvadd_host_bin)
+
+vvadd_riscv_bin = vvadd.riscv
+$(vvadd_riscv_bin) : $(vvadd_c_objs) $(vvadd_riscv_objs)
+       $(RISCV_LINK) $(vvadd_c_objs) $(vvadd_riscv_objs) -o $(vvadd_riscv_bin)
+
+junk += $(vvadd_c_objs) $(vvadd_riscv_objs) \
+        $(vvadd_host_bin) $(vvadd_riscv_bin)
diff --git a/benchmarks/vvadd/dataset1-large.h b/benchmarks/vvadd/dataset1-large.h
new file mode 100644 (file)
index 0000000..911e8de
--- /dev/null
@@ -0,0 +1,165 @@
+
+#define DATA_SIZE 1000
+
+int input1_data[DATA_SIZE] =
+{
+   41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621,   6, 931, 890, 392, 694, 961, 110, 116, 296,
+  426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195,  81,
+  267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859,  65,
+  288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,
+  288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584,  62, 985, 403, 346, 517, 559, 908, 775, 255,
+  778, 598, 143,  33, 125, 941, 933, 799, 553, 431, 648, 952, 287,  19,  49,  86,  95, 441, 587, 614,
+  382, 280, 808, 971, 819, 344, 450, 512, 965, 347, 808, 882, 537, 946, 701, 356, 567, 891,  22, 568,
+  665, 423, 434, 158,   2,  84, 247,  49, 435, 792, 869, 486, 414, 369, 548, 518, 888, 682, 284, 264,
+  499, 290, 897, 215, 731, 688, 251, 786, 555, 302, 528, 544, 322, 947, 287, 824, 304, 788, 733, 959,
+  366, 722, 294, 975, 653, 748,  91, 378, 105, 102, 381, 651, 825, 840, 356, 148,  54, 140, 955, 343,
+  533, 757, 521, 837, 592,  13, 173,  63, 121, 133, 758, 372, 951,  39, 129, 110, 847, 437, 255, 269,
+  409, 628, 399, 549, 753, 564, 171,  19, 727, 501, 777,  43, 753,  81, 202, 853, 153, 760, 357, 943,
+  922, 328, 496, 442, 516, 641, 276, 786, 113, 842, 907, 275, 237,  32, 784, 565, 357, 803, 819, 751,
+  280,  85, 458, 454, 710, 459,  41, 253, 377, 508, 700, 860, 480, 741, 499, 709,  49, 371, 873, 945,
+  992, 526, 721, 435, 232, 497, 697,  30, 348, 250, 350, 250, 573, 784, 749, 502, 823, 826, 170, 160,
+  674,  32, 202, 143, 853,  90, 394, 107, 855, 106, 157,   6, 765, 204, 194, 574, 218, 526, 177, 239,
+  698, 757, 706,  49,  84, 799, 893, 512, 373, 492,  14, 621,  83, 103, 794, 921, 643, 880, 834, 239,
+  462, 114, 561, 529,  10, 997, 904, 387, 407, 105, 559, 936, 512, 409, 302, 202, 427, 613, 359, 521,
+  684,  22, 185, 312, 107, 274, 387, 242, 486, 105, 698, 899, 770, 644,  80, 161, 407, 946,  30, 768,
+  870, 113, 148,  62, 147, 838, 845, 432, 141, 211, 817, 821, 562, 364, 615, 495, 812, 916, 159, 430,
+  803, 180, 544, 840, 458, 786, 872, 795, 806, 758, 104, 401, 254, 984, 136, 729, 584, 794, 414, 528,
+  707, 554, 378, 766, 977, 236, 947, 229, 165, 505, 105, 704, 796, 140, 303, 795, 635, 560, 119,   8,
+  532, 814,  37, 584, 739, 619, 767, 478,  57, 958, 784, 985, 837, 307,  67, 824, 996, 749, 171, 826,
+  621, 155, 826,  43, 694,  80, 236, 747, 744, 265, 124, 731, 941, 425, 370, 320, 269, 542, 763, 752,
+  915,  14,   1, 906, 995, 809, 560, 873, 972, 289, 509, 558, 970, 405, 579, 293, 251, 849, 129, 452,
+  716,  86, 678, 181, 240, 335, 793, 641,   1, 320, 987, 646, 754, 958, 203, 142, 180, 299, 165, 761,
+  974, 646, 559, 619, 422, 260, 565, 542, 492, 991, 745, 207, 372, 932, 664,  34, 533, 478, 908, 203,
+   33, 214, 365, 892, 781, 680, 705, 688, 947, 386,  50, 101, 474, 399, 679, 330, 952, 471, 477, 725,
+  713, 937, 529, 870,  77, 545, 907, 853, 143, 979, 239, 105, 365,  98,  54,  98, 440, 764, 315, 336,
+  697, 774, 726, 324, 282, 536, 622, 594, 890,  75, 290, 496, 726, 449, 548, 135, 644, 838, 290, 767,
+  162, 415, 491, 985, 116, 617, 859, 235, 282, 571, 913, 560, 194, 242, 782, 985, 728, 344, 430, 613,
+  759, 176, 309, 333, 354, 310, 699,  46, 487, 503, 100, 393, 268, 314,  75, 345, 987, 600, 908, 384,
+   92, 545, 277, 668, 351, 853, 863, 312, 100, 532, 567, 836, 370, 989, 461, 912, 182, 268, 160, 771,
+   22, 854, 644,  17, 779, 911, 855, 137, 983, 717, 565, 719, 253, 785, 154, 196, 253, 447, 899,   5,
+  325, 616, 309, 175, 159, 123, 838, 715, 550, 230,  82, 627, 324, 927, 103,  17, 966, 159, 177, 593,
+  372, 393, 599, 745, 377, 865, 591, 553, 440, 345, 593, 290, 908, 544, 377, 456, 781, 110, 495, 896,
+  806, 700, 548, 340,  29, 829, 630, 546, 613, 972, 116, 313, 904, 971, 607, 794, 169, 896, 507, 916,
+  431, 339, 147, 224, 112, 580, 834, 134, 948, 201, 488, 396, 797, 478, 769, 574, 485, 339, 721, 451,
+  821, 744,   0, 594, 277, 120, 680, 757, 555, 847, 517, 379, 505, 904, 246, 243, 394, 430, 214, 244,
+  524, 399, 172, 304, 620, 594, 535, 698, 159, 750, 809, 454,  75,  93, 167,  16, 853, 494, 324,  78,
+   52, 112,  10, 342, 730, 680, 287, 961,  92, 626, 912, 616, 860, 744, 744, 478, 615, 508, 914, 810,
+  288, 974, 129, 581, 548, 868, 981, 270, 623, 653, 626, 990, 386, 323, 472, 164, 239, 189, 865, 231,
+  356, 152, 825, 328, 390, 848,  38, 402, 616, 546, 206,   2, 783, 890, 815, 831, 665, 410,  94, 246,
+  422, 211, 675,   9, 374, 426,  64,  53, 758, 811, 500, 437, 335, 328, 237, 415, 468, 684, 565, 305,
+  449, 597, 136, 882, 383, 938, 268, 115, 908,  50, 952, 366, 397, 257, 231, 667,  35, 990, 443, 213,
+  389,  13, 621,  52, 612, 934, 953, 828, 462, 621, 812, 522, 672,  57, 313, 352,  55, 972, 753, 416,
+  879, 864, 572, 163, 721,  12, 643, 507, 968, 781, 840, 242, 630, 810, 795, 435, 885, 599, 696, 643,
+   93, 710, 785, 112, 581,  12, 923, 615, 652, 359, 261, 233, 609, 686, 539, 118, 560, 739,  20, 317,
+  976, 573, 386, 772, 663, 504, 212, 888, 907, 420, 737, 516,  25, 219, 797, 716, 452, 692, 683, 459,
+  815, 323, 612, 247, 116, 352, 281, 738, 290, 909, 645, 625, 932, 220, 685, 373, 876, 646, 412, 955
+};
+
+int input2_data[DATA_SIZE] =
+{
+  454, 335,   1, 989, 365, 572,  64, 153, 216, 140, 210, 572, 339, 593, 898, 228,  12, 883, 750, 646,
+  500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509,  88, 703, 669, 375, 551, 936, 592, 569,
+  952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814,  79, 208, 998, 629, 847,
+  704, 997, 253, 715, 430, 415, 538, 700,   4, 494, 100, 864, 693, 416, 296, 285, 620,  78, 351, 540,
+  646, 169, 527, 289, 796, 801, 720, 758, 745,  92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332,
+  684, 740, 446, 311, 743, 557, 479, 557, 925, 796, 357, 891, 666, 514, 557, 870, 853, 440,  61, 678,
+  396,   9,  17, 170, 291, 380, 536, 185, 917, 539, 983, 887,  54, 612, 951, 479, 151,   7, 641, 335,
+  730,  95, 728, 280, 395, 688, 911, 476, 815, 729, 265, 127, 236, 214, 180,   6, 503, 596, 173, 643,
+  346, 599,  68, 849, 658, 619, 121, 131, 828, 667, 433, 487, 753, 125, 626,  14,  10, 403, 106, 703,
+  818, 964, 406, 874, 856,  86,  60, 660, 667, 153, 121,  98, 412, 236,  12, 423, 965, 216, 621, 361,
+  921, 715, 647, 299, 886, 682,  36, 493, 551, 537, 969, 643, 434, 415, 303, 438, 860, 203, 478, 988,
+  675, 719, 990, 338, 450, 633, 155, 646, 452, 427, 509, 988, 426,  12, 483, 142, 339, 390,  50, 171,
+  601, 105, 968, 121, 879,  81, 870, 600, 603, 871, 887, 610, 404, 234, 745, 526, 275, 441, 226, 752,
+  943, 726, 709, 201,  54, 758,  53, 397,  41, 141, 416, 747, 219, 478, 770, 180, 482, 691, 725, 173,
+  186, 914,   1, 963, 247, 464, 362, 521, 233, 120,  40, 779, 195, 161, 743, 439, 355, 403, 141, 633,
+  289, 782, 320, 636, 118, 852,  70, 816, 388, 954,  36,  16, 698, 695, 677, 598, 883, 824, 746, 462,
+  511, 534, 440, 428, 732, 726, 702, 547,  86, 798, 215,  21, 651,  59, 429, 657,  96, 973, 659, 966,
+  524,  62, 625, 303, 714, 409,  55, 728, 305, 436, 901, 592, 691, 796, 497, 177, 940, 995, 480, 158,
+  822, 611, 680,  14, 111, 797, 185,   0, 718,  96, 749, 739, 814, 435, 326,  37,  33, 605, 935,  27,
+   88, 441, 339, 344, 554, 365, 954, 639, 396, 991, 249, 338, 832, 974, 393, 266, 470, 348, 336, 419,
+  249, 215, 542, 903, 636, 729, 581, 820, 671, 979, 418, 670, 920, 568, 745, 662, 139, 385, 927, 173,
+  457, 316, 183, 477, 196, 399, 416, 805, 996, 270, 735, 696, 825, 528,  50, 623, 537,  87, 294, 867,
+  110, 398, 781, 646, 375, 943, 897, 589,  44, 288, 845, 742,  99, 522, 443, 432, 165, 930,  28, 461,
+  323, 272, 376, 340, 898, 158, 168, 443, 193, 631, 935, 274, 781, 185, 619, 292, 933, 156, 827,  88,
+  987, 629, 649,  32,   1, 744, 399, 915, 791, 554, 984, 530, 600, 401, 683, 540, 903, 120, 995, 521,
+  622, 224, 895, 530, 820, 651, 226,  96, 262, 569, 238, 126, 610, 191, 238, 796, 884, 573, 108, 140,
+  789, 852,  23, 704, 890, 480,  52, 372, 201, 546, 408, 119, 645, 464,  81, 293,  52, 880, 224, 744,
+  735, 886, 167,   1, 532, 321, 169, 485, 101, 177,  42, 708, 654, 915, 625, 242, 822, 795, 641, 252,
+  245, 151, 876, 333, 601, 938, 775, 397, 233, 755, 454, 424, 210, 962, 900, 923, 655, 529, 595,  90,
+  464, 685,  70, 754,  32, 494,  25, 389, 488,  37, 409, 639,  27, 950, 539,  80, 303, 723, 734, 125,
+  552, 248, 107, 362,  48, 869, 144, 841, 724, 335, 470, 263, 343, 809, 677, 339, 336, 410, 465,  56,
+  590, 485, 406, 993, 746, 238, 525, 336, 256, 134, 546, 722, 367, 943, 106, 629, 396, 208, 429, 523,
+  130, 355, 990, 673, 991, 719, 449,  84, 616, 211, 707, 737, 847, 452, 316, 974, 746, 796, 522, 618,
+  115, 727, 226, 165, 200, 830, 742, 187, 705, 671, 785, 886, 962, 657, 293, 620, 144, 173, 796,  72,
+  678,  80, 793, 685, 637, 967, 241, 898, 693, 372, 601, 721, 398, 553,  72, 174, 978, 325, 558, 185,
+  505, 859, 651, 573, 321, 349, 400, 890, 844, 885, 933, 980, 448, 989,  50, 332, 900, 716, 747, 444,
+    6, 394, 285, 703, 450, 652, 771, 485, 534, 559, 481, 507, 434, 343,  42, 784, 865, 421, 415, 871,
+  539, 162, 105, 481, 595, 115, 350, 964, 287, 232, 154, 602, 539, 943, 872, 121, 652, 811, 747, 362,
+  340, 910, 206, 572, 505, 973, 961, 354, 627, 849, 971, 910, 410, 770,  63, 874, 396, 482, 619, 646,
+  557, 328,  67, 884, 512, 972,   6, 513, 882, 562, 764, 366, 506, 786, 831, 382, 638, 452,  72,  83,
+   59, 932, 929, 924, 961,  69, 797, 985, 854, 885, 600, 389, 232, 793, 179, 773, 689, 775, 494, 139,
+  234, 431, 780, 371,  22, 653, 741, 815, 428, 139, 603, 315, 344, 889, 317, 260, 861, 377, 511, 304,
+   70,  35, 854, 576, 490, 326, 303, 431, 813, 708, 388, 962, 967, 442,  49, 831, 251, 321, 741, 179,
+  176, 117, 523, 764, 952, 704, 531, 804,  23, 611, 846, 375, 854, 971,  24, 639, 318, 723, 662, 647,
+  281, 158, 294, 885, 734, 866, 471, 296, 673, 472, 439,   5, 155, 506, 948, 600, 445, 222, 784, 349,
+  943, 150, 366, 444, 604, 720, 340, 972, 911, 321, 435,  50,  78, 761, 950, 238,  27, 226, 201, 176,
+  877, 450, 879,  99, 143,  31, 812, 771, 527, 488, 797, 194, 293, 966, 276, 345, 413, 197, 386, 116,
+  322, 680, 538, 553, 960, 874,  48, 506, 898, 539, 495, 764, 805, 286, 432, 836, 192, 825, 778, 586,
+  359, 352, 746,  11, 749,   5, 408, 643, 441, 368,  97, 169, 359, 527, 672,  69, 880, 298, 300, 327,
+  923, 829, 816, 497, 243, 981, 917, 713, 653, 503, 406, 543, 108, 304, 464, 954,  86, 802, 446,  28
+};
+
+int verify_data[DATA_SIZE] =
+{
+  495, 1168, 565, 1176, 1114, 922, 196, 1102, 800, 945, 831, 578, 1270, 1483, 1290, 922, 973, 993, 866, 942,
+  926, 750, 1360, 1586, 1300, 828, 1571, 940, 746, 1196, 1186, 1078, 291, 983, 1428, 981, 1062, 1593, 787, 650,
+  1219, 1029, 921, 1587, 1270, 730, 1241, 1139, 1525, 1373, 738, 1609, 1545, 1347, 1463, 736, 389, 1109, 1488, 912,
+  992, 1346, 394, 1620, 1316, 679, 1114, 1679, 765, 735, 578, 1363, 1096, 638, 740, 1006, 1296, 395, 575, 1477,
+  934, 288, 1142, 895, 1185, 1152, 1175, 1036, 1112, 450, 1573, 333, 1838, 1191, 877, 739, 1020, 1149, 1133, 587,
+  1462, 1338, 589, 344, 868, 1498, 1412, 1356, 1478, 1227, 1005, 1843, 953, 533, 606, 956, 948, 881, 648, 1292,
+  778, 289, 825, 1141, 1110, 724, 986, 697, 1882, 886, 1791, 1769, 591, 1558, 1652, 835, 718, 898, 663, 903,
+  1395, 518, 1162, 438, 397, 772, 1158, 525, 1250, 1521, 1134, 613, 650, 583, 728, 524, 1391, 1278, 457, 907,
+  845, 889, 965, 1064, 1389, 1307, 372, 917, 1383, 969, 961, 1031, 1075, 1072, 913, 838, 314, 1191, 839, 1662,
+  1184, 1686, 700, 1849, 1509, 834, 151, 1038, 772, 255, 502, 749, 1237, 1076, 368, 571, 1019, 356, 1576, 704,
+  1454, 1472, 1168, 1136, 1478, 695, 209, 556, 672, 670, 1727, 1015, 1385, 454, 432, 548, 1707, 640, 733, 1257,
+  1084, 1347, 1389, 887, 1203, 1197, 326, 665, 1179, 928, 1286, 1031, 1179,  93, 685, 995, 492, 1150, 407, 1114,
+  1523, 433, 1464, 563, 1395, 722, 1146, 1386, 716, 1713, 1794, 885, 641, 266, 1529, 1091, 632, 1244, 1045, 1503,
+  1223, 811, 1167, 655, 764, 1217,  94, 650, 418, 649, 1116, 1607, 699, 1219, 1269, 889, 531, 1062, 1598, 1118,
+  1178, 1440, 722, 1398, 479, 961, 1059, 551, 581, 370, 390, 1029, 768, 945, 1492, 941, 1178, 1229, 311, 793,
+  963, 814, 522, 779, 971, 942, 464, 923, 1243, 1060, 193,  22, 1463, 899, 871, 1172, 1101, 1350, 923, 701,
+  1209, 1291, 1146, 477, 816, 1525, 1595, 1059, 459, 1290, 229, 642, 734, 162, 1223, 1578, 739, 1853, 1493, 1205,
+  986, 176, 1186, 832, 724, 1406, 959, 1115, 712, 541, 1460, 1528, 1203, 1205, 799, 379, 1367, 1608, 839, 679,
+  1506, 633, 865, 326, 218, 1071, 572, 242, 1204, 201, 1447, 1638, 1584, 1079, 406, 198, 440, 1551, 965, 795,
+  958, 554, 487, 406, 701, 1203, 1799, 1071, 537, 1202, 1066, 1159, 1394, 1338, 1008, 761, 1282, 1264, 495, 849,
+  1052, 395, 1086, 1743, 1094, 1515, 1453, 1615, 1477, 1737, 522, 1071, 1174, 1552, 881, 1391, 723, 1179, 1341, 701,
+  1164, 870, 561, 1243, 1173, 635, 1363, 1034, 1161, 775, 840, 1400, 1621, 668, 353, 1418, 1172, 647, 413, 875,
+  642, 1212, 818, 1230, 1114, 1562, 1664, 1067, 101, 1246, 1629, 1727, 936, 829, 510, 1256, 1161, 1679, 199, 1287,
+  944, 427, 1202, 383, 1592, 238, 404, 1190, 937, 896, 1059, 1005, 1722, 610, 989, 612, 1202, 698, 1590, 840,
+  1902, 643, 650, 938, 996, 1553, 959, 1788, 1763, 843, 1493, 1088, 1570, 806, 1262, 833, 1154, 969, 1124, 973,
+  1338, 310, 1573, 711, 1060, 986, 1019, 737, 263, 889, 1225, 772, 1364, 1149, 441, 938, 1064, 872, 273, 901,
+  1763, 1498, 582, 1323, 1312, 740, 617, 914, 693, 1537, 1153, 326, 1017, 1396, 745, 327, 585, 1358, 1132, 947,
+  768, 1100, 532, 893, 1313, 1001, 874, 1173, 1048, 563,  92, 809, 1128, 1314, 1304, 572, 1774, 1266, 1118, 977,
+  958, 1088, 1405, 1203, 678, 1483, 1682, 1250, 376, 1734, 693, 529, 575, 1060, 954, 1021, 1095, 1293, 910, 426,
+  1161, 1459, 796, 1078, 314, 1030, 647, 983, 1378, 112, 699, 1135, 753, 1399, 1087, 215, 947, 1561, 1024, 892,
+  714, 663, 598, 1347, 164, 1486, 1003, 1076, 1006, 906, 1383, 823, 537, 1051, 1459, 1324, 1064, 754, 895, 669,
+  1349, 661, 715, 1326, 1100, 548, 1224, 382, 743, 637, 646, 1115, 635, 1257, 181, 974, 1383, 808, 1337, 907,
+  222, 900, 1267, 1341, 1342, 1572, 1312, 396, 716, 743, 1274, 1573, 1217, 1441, 777, 1886, 928, 1064, 682, 1389,
+  137, 1581, 870, 182, 979, 1741, 1597, 324, 1688, 1388, 1350, 1605, 1215, 1442, 447, 816, 397, 620, 1695,  77,
+  1003, 696, 1102, 860, 796, 1090, 1079, 1613, 1243, 602, 683, 1348, 722, 1480, 175, 191, 1944, 484, 735, 778,
+  877, 1252, 1250, 1318, 698, 1214, 991, 1443, 1284, 1230, 1526, 1270, 1356, 1533, 427, 788, 1681, 826, 1242, 1340,
+  812, 1094, 833, 1043, 479, 1481, 1401, 1031, 1147, 1531, 597, 820, 1338, 1314, 649, 1578, 1034, 1317, 922, 1787,
+  970, 501, 252, 705, 707, 695, 1184, 1098, 1235, 433, 642, 998, 1336, 1421, 1641, 695, 1137, 1150, 1468, 813,
+  1161, 1654, 206, 1166, 782, 1093, 1641, 1111, 1182, 1696, 1488, 1289, 915, 1674, 309, 1117, 790, 912, 833, 890,
+  1081, 727, 239, 1188, 1132, 1566, 541, 1211, 1041, 1312, 1573, 820, 581, 879, 998, 398, 1491, 946, 396, 161,
+  111, 1044, 939, 1266, 1691, 749, 1084, 1946, 946, 1511, 1512, 1005, 1092, 1537, 923, 1251, 1304, 1283, 1408, 949,
+  522, 1405, 909, 952, 570, 1521, 1722, 1085, 1051, 792, 1229, 1305, 730, 1212, 789, 424, 1100, 566, 1376, 535,
+  426, 187, 1679, 904, 880, 1174, 341, 833, 1429, 1254, 594, 964, 1750, 1332, 864, 1662, 916, 731, 835, 425,
+  598, 328, 1198, 773, 1326, 1130, 595, 857, 781, 1422, 1346, 812, 1189, 1299, 261, 1054, 786, 1407, 1227, 952,
+  730, 755, 430, 1767, 1117, 1804, 739, 411, 1581, 522, 1391, 371, 552, 763, 1179, 1267, 480, 1212, 1227, 562,
+  1332, 163, 987, 496, 1216, 1654, 1293, 1800, 1373, 942, 1247, 572, 750, 818, 1263, 590,  82, 1198, 954, 592,
+  1756, 1314, 1451, 262, 864,  43, 1455, 1278, 1495, 1269, 1637, 436, 923, 1776, 1071, 780, 1298, 796, 1082, 759,
+  415, 1390, 1323, 665, 1541, 886, 971, 1121, 1550, 898, 756, 997, 1414, 972, 971, 954, 752, 1564, 798, 903,
+  1335, 925, 1132, 783, 1412, 509, 620, 1531, 1348, 788, 834, 685, 384, 746, 1469, 785, 1332, 990, 983, 786,
+  1738, 1152, 1428, 744, 359, 1333, 1198, 1451, 943, 1412, 1051, 1168, 1040, 524, 1149, 1327, 962, 1448, 858, 983
+};
+
diff --git a/benchmarks/vvadd/dataset1.h b/benchmarks/vvadd/dataset1.h
new file mode 100644 (file)
index 0000000..44f32f2
--- /dev/null
@@ -0,0 +1,60 @@
+
+#define DATA_SIZE 300
+
+int input1_data[DATA_SIZE] =
+{
+   41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621,   6, 931, 890, 392, 694, 961, 110, 116, 296,
+  426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195,  81,
+  267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859,  65,
+  288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,
+  288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584,  62, 985, 403, 346, 517, 559, 908, 775, 255,
+  778, 598, 143,  33, 125, 941, 933, 799, 553, 431, 648, 952, 287,  19,  49,  86,  95, 441, 587, 614,
+  382, 280, 808, 971, 819, 344, 450, 512, 965, 347, 808, 882, 537, 946, 701, 356, 567, 891,  22, 568,
+  665, 423, 434, 158,   2,  84, 247,  49, 435, 792, 869, 486, 414, 369, 548, 518, 888, 682, 284, 264,
+  499, 290, 897, 215, 731, 688, 251, 786, 555, 302, 528, 544, 322, 947, 287, 824, 304, 788, 733, 959,
+  366, 722, 294, 975, 653, 748,  91, 378, 105, 102, 381, 651, 825, 840, 356, 148,  54, 140, 955, 343,
+  533, 757, 521, 837, 592,  13, 173,  63, 121, 133, 758, 372, 951,  39, 129, 110, 847, 437, 255, 269,
+  409, 628, 399, 549, 753, 564, 171,  19, 727, 501, 777,  43, 753,  81, 202, 853, 153, 760, 357, 943,
+  922, 328, 496, 442, 516, 641, 276, 786, 113, 842, 907, 275, 237,  32, 784, 565, 357, 803, 819, 751,
+  280,  85, 458, 454, 710, 459,  41, 253, 377, 508, 700, 860, 480, 741, 499, 709,  49, 371, 873, 945,
+  992, 526, 721, 435, 232, 497, 697,  30, 348, 250, 350, 250, 573, 784, 749, 502, 823, 826, 170, 160
+};
+
+int input2_data[DATA_SIZE] =
+{
+  454, 335,   1, 989, 365, 572,  64, 153, 216, 140, 210, 572, 339, 593, 898, 228,  12, 883, 750, 646,
+  500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509,  88, 703, 669, 375, 551, 936, 592, 569,
+  952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814,  79, 208, 998, 629, 847,
+  704, 997, 253, 715, 430, 415, 538, 700,   4, 494, 100, 864, 693, 416, 296, 285, 620,  78, 351, 540,
+  646, 169, 527, 289, 796, 801, 720, 758, 745,  92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332,
+  684, 740, 446, 311, 743, 557, 479, 557, 925, 796, 357, 891, 666, 514, 557, 870, 853, 440,  61, 678,
+  396,   9,  17, 170, 291, 380, 536, 185, 917, 539, 983, 887,  54, 612, 951, 479, 151,   7, 641, 335,
+  730,  95, 728, 280, 395, 688, 911, 476, 815, 729, 265, 127, 236, 214, 180,   6, 503, 596, 173, 643,
+  346, 599,  68, 849, 658, 619, 121, 131, 828, 667, 433, 487, 753, 125, 626,  14,  10, 403, 106, 703,
+  818, 964, 406, 874, 856,  86,  60, 660, 667, 153, 121,  98, 412, 236,  12, 423, 965, 216, 621, 361,
+  921, 715, 647, 299, 886, 682,  36, 493, 551, 537, 969, 643, 434, 415, 303, 438, 860, 203, 478, 988,
+  675, 719, 990, 338, 450, 633, 155, 646, 452, 427, 509, 988, 426,  12, 483, 142, 339, 390,  50, 171,
+  601, 105, 968, 121, 879,  81, 870, 600, 603, 871, 887, 610, 404, 234, 745, 526, 275, 441, 226, 752,
+  943, 726, 709, 201,  54, 758,  53, 397,  41, 141, 416, 747, 219, 478, 770, 180, 482, 691, 725, 173,
+  186, 914,   1, 963, 247, 464, 362, 521, 233, 120,  40, 779, 195, 161, 743, 439, 355, 403, 141, 633
+};
+
+int verify_data[DATA_SIZE] =
+{
+  495, 1168, 565, 1176, 1114, 922, 196, 1102, 800, 945, 831, 578, 1270, 1483, 1290, 922, 973, 993, 866, 942,
+  926, 750, 1360, 1586, 1300, 828, 1571, 940, 746, 1196, 1186, 1078, 291, 983, 1428, 981, 1062, 1593, 787, 650,
+  1219, 1029, 921, 1587, 1270, 730, 1241, 1139, 1525, 1373, 738, 1609, 1545, 1347, 1463, 736, 389, 1109, 1488, 912,
+  992, 1346, 394, 1620, 1316, 679, 1114, 1679, 765, 735, 578, 1363, 1096, 638, 740, 1006, 1296, 395, 575, 1477,
+  934, 288, 1142, 895, 1185, 1152, 1175, 1036, 1112, 450, 1573, 333, 1838, 1191, 877, 739, 1020, 1149, 1133, 587,
+  1462, 1338, 589, 344, 868, 1498, 1412, 1356, 1478, 1227, 1005, 1843, 953, 533, 606, 956, 948, 881, 648, 1292,
+  778, 289, 825, 1141, 1110, 724, 986, 697, 1882, 886, 1791, 1769, 591, 1558, 1652, 835, 718, 898, 663, 903,
+  1395, 518, 1162, 438, 397, 772, 1158, 525, 1250, 1521, 1134, 613, 650, 583, 728, 524, 1391, 1278, 457, 907,
+  845, 889, 965, 1064, 1389, 1307, 372, 917, 1383, 969, 961, 1031, 1075, 1072, 913, 838, 314, 1191, 839, 1662,
+  1184, 1686, 700, 1849, 1509, 834, 151, 1038, 772, 255, 502, 749, 1237, 1076, 368, 571, 1019, 356, 1576, 704,
+  1454, 1472, 1168, 1136, 1478, 695, 209, 556, 672, 670, 1727, 1015, 1385, 454, 432, 548, 1707, 640, 733, 1257,
+  1084, 1347, 1389, 887, 1203, 1197, 326, 665, 1179, 928, 1286, 1031, 1179,  93, 685, 995, 492, 1150, 407, 1114,
+  1523, 433, 1464, 563, 1395, 722, 1146, 1386, 716, 1713, 1794, 885, 641, 266, 1529, 1091, 632, 1244, 1045, 1503,
+  1223, 811, 1167, 655, 764, 1217,  94, 650, 418, 649, 1116, 1607, 699, 1219, 1269, 889, 531, 1062, 1598, 1118,
+  1178, 1440, 722, 1398, 479, 961, 1059, 551, 581, 370, 390, 1029, 768, 945, 1492, 941, 1178, 1229, 311, 793
+};
+
diff --git a/benchmarks/vvadd/vvadd_gendata.pl b/benchmarks/vvadd/vvadd_gendata.pl
new file mode 100755 (executable)
index 0000000..f23cdf4
--- /dev/null
@@ -0,0 +1,139 @@
+#!/usr/bin/perl -w
+#==========================================================================
+# vvadd_gendata.pl
+#
+# Author : Christopher Batten (cbatten@mit.edu)
+# Date   : April 29, 2005
+#
+(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
+#
+# Simple script which creates an input data set and the reference data
+# for the vvadd benchmark.
+#
+ENDMSG
+
+use strict "vars";
+use warnings;
+no  warnings("once");
+use Getopt::Long;
+
+#--------------------------------------------------------------------------
+# Command line processing
+#--------------------------------------------------------------------------
+
+our %opts;
+
+sub usage()
+{
+
+  print "\n";
+  print " Usage: vvadd_gendata.pl [options] \n";
+  print "\n";
+  print " Options:\n";
+  print "  --help  print this message\n";
+  print "  --size  size of input data [1000]\n";
+  print "  --seed  random seed [1]\n";
+  print "$usageMsg";
+
+  exit();
+}
+
+sub processCommandLine()
+{
+
+  $opts{"help"} = 0;
+  $opts{"size"} = 1000;
+  $opts{"seed"} = 1;
+  Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
+  $opts{"help"} and usage();
+
+}
+
+#--------------------------------------------------------------------------
+# Helper Functions
+#--------------------------------------------------------------------------
+
+sub printArray
+{
+  my $arrayName = $_[0];
+  my $arrayRef  = $_[1];
+
+  my $numCols = 20;
+  my $arrayLen = scalar(@{$arrayRef});
+
+  print "int ".$arrayName."[DATA_SIZE] = \n";
+  print "{\n";
+
+  if ( $arrayLen <= $numCols ) {
+    print "  ";
+    for ( my $i = 0; $i < $arrayLen; $i++ ) {
+      print sprintf("%3d",$arrayRef->[$i]);
+      if ( $i != $arrayLen-1 ) {
+        print ", ";
+      }
+    }
+    print "\n";
+  }
+
+  else {
+    my $numRows = int($arrayLen/$numCols);
+    for ( my $j = 0; $j < $numRows; $j++ ) {
+      print "  ";
+      for ( my $i = 0; $i < $numCols; $i++ ) {
+        my $index = $j*$numCols + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+    if ( $arrayLen > ($numRows*$numCols) ) {
+      print "  ";
+      for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
+        my $index = $numCols*$numRows + $i;
+        print sprintf("%3d",$arrayRef->[$index]);
+        if ( $index != $arrayLen-1 ) {
+          print ", ";
+        }
+      }
+      print "\n";
+    }
+
+  }
+
+  print  "};\n\n";
+}
+
+#--------------------------------------------------------------------------
+# Main
+#--------------------------------------------------------------------------
+
+sub main()
+{
+
+  processCommandLine();
+  srand($opts{"seed"});
+
+  my @values1;
+  my @values2;
+  my @sum;
+  for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
+    my $value1 = int(rand(999));
+    my $value2 = int(rand(999));
+    push( @values1, $value1 );
+    push( @values2, $value2 );
+    push( @sum, $value1 + $value2 );
+  }
+
+
+  print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
+  printArray( "input1_data", \@values1 );
+  printArray( "input2_data", \@values2 );
+  printArray( "verify_data", \@sum );
+
+}
+
+main();
+
diff --git a/benchmarks/vvadd/vvadd_main.c b/benchmarks/vvadd/vvadd_main.c
new file mode 100644 (file)
index 0000000..9738118
--- /dev/null
@@ -0,0 +1,139 @@
+//**************************************************************************
+// Vector-vector add benchmark
+//--------------------------------------------------------------------------
+//
+// This benchmark uses adds to vectors and writes the results to a
+// third vector. The input data (and reference data) should be
+// generated using the vvadd_gendata.pl perl script and dumped
+// to a file named dataset1.h The smips-gcc toolchain does not
+// support system calls so printf's can only be used on a host system,
+// not on the smips processor simulator itself. You should not change
+// anything except the HOST_DEBUG and PREALLOCATE macros for your timing
+// runs.
+
+//--------------------------------------------------------------------------
+// Macros
+
+// Set HOST_DEBUG to 1 if you are going to compile this for a host
+// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
+// to 0 if you are compiling with the smips-gcc toolchain.
+
+#ifndef HOST_DEBUG
+#define HOST_DEBUG 0
+#endif
+
+// Set PREALLOCATE to 1 if you want to preallocate the benchmark
+// function before starting stats. If you have instruction/data
+// caches and you don't want to count the overhead of misses, then
+// you will need to use preallocation.
+
+#ifndef PREALLOCATE
+#define PREALLOCATE 0
+#endif
+
+// Set SET_STATS to 1 if you want to carve out the piece that actually
+// does the computation.
+
+#ifndef SET_STATS
+#define SET_STATS 0
+#endif
+
+//--------------------------------------------------------------------------
+// Input/Reference Data
+
+#include "dataset1.h"
+
+//--------------------------------------------------------------------------
+// Helper functions
+
+int verify( int n, int test[], int correct[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ ) {
+    if ( test[i] != correct[i] ) {
+      return 2;
+    }
+  }
+  return 1;
+}
+
+#if HOST_DEBUG
+void printArray( char name[], int n, int arr[] )
+{
+  int i;
+  printf( " %10s :", name );
+  for ( i = 0; i < n; i++ )
+    printf( " %3d ", arr[i] );
+  printf( "\n" );
+}
+#endif
+
+void finishTest( int toHostValue )
+{
+#if HOST_DEBUG
+  if ( toHostValue == 1 )
+    printf( "*** PASSED ***\n" );
+  else
+    printf( "*** FAILED *** (tohost = %d)\n", toHostValue );
+  exit(0);
+#else
+  asm( "mtpcr %0, cr30" : : "r" (toHostValue) );
+  while ( 1 ) { }
+#endif
+}
+
+void setStats( int enable )
+{
+#if ( !HOST_DEBUG && SET_STATS )
+  asm( "mtpcr %0, cr10" : : "r" (enable) );
+#endif
+}
+
+//--------------------------------------------------------------------------
+// vvadd function
+
+void vvadd( int n, int a[], int b[], int c[] )
+{
+  int i;
+  for ( i = 0; i < n; i++ )
+    c[i] = a[i] + b[i];
+}
+
+//--------------------------------------------------------------------------
+// Main
+
+int main( int argc, char* argv[] )
+{
+  int results_data[DATA_SIZE];
+
+  // Output the input array
+
+#if HOST_DEBUG
+  printArray( "input1", DATA_SIZE, input1_data );
+  printArray( "input2", DATA_SIZE, input2_data );
+  printArray( "verify", DATA_SIZE, verify_data );
+#endif
+
+  // If needed we preallocate everything in the caches
+
+#if PREALLOCATE
+  vvadd( DATA_SIZE, input1_data, input2_data, results_data );
+#endif
+
+  // Do the vvadd
+
+  setStats(1);
+  vvadd( DATA_SIZE, input1_data, input2_data, results_data );
+  setStats(0);
+
+  // Print out the results
+
+#if HOST_DEBUG
+  printArray( "results", DATA_SIZE, results_data );
+#endif
+
+  // Check the results
+
+  finishTest(verify( DATA_SIZE, results_data, verify_data ));
+
+}