--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+ .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:
--- /dev/null
+ .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:
--- /dev/null
+#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
--- /dev/null
+ .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"
--- /dev/null
+#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?
+}
--- /dev/null
+/*======================================================================*/
+/* 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 = .;
+}
+
--- /dev/null
+/*======================================================================*/
+/* 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 = .;
+}
+
--- /dev/null
+// 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
+
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+#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
+};
--- /dev/null
+#!/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)
--- /dev/null
+//**************************************************************************
+// 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 ));
+
+}
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+#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 */
--- /dev/null
+#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
--- /dev/null
+//**************************************************************************
+// 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 */
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+
+#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
+};
+
--- /dev/null
+//**************************************************************************
+// 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;
+ }
+
+ }
+
+}
--- /dev/null
+//**************************************************************************
+// 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[] );
--- /dev/null
+#!/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();
+
--- /dev/null
+//**************************************************************************
+// 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 ));
+
+}
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+
+#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
+};
+
--- /dev/null
+#!/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();
+
--- /dev/null
+//**************************************************************************
+// 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);
+}
+
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+
+#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
+};
+
--- /dev/null
+//**************************************************************************
+// 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);
+}
+
--- /dev/null
+#!/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();
+
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+
+#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
+};
+
--- /dev/null
+// *************************************************************************
+// 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;
+
+}
+
--- /dev/null
+//**************************************************************************
+// Software multiply function
+//--------------------------------------------------------------------------
+
+// Simple C version
+int multiply(int x, int y);
+
+// Simple assembly version
+int multiply_asm(int x, int y);
--- /dev/null
+#!/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();
+
--- /dev/null
+// *************************************************************************
+// 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 ));
+
+}
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+
+#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
+};
+
--- /dev/null
+#!/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();
+
--- /dev/null
+//**************************************************************************
+// 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 ));
+
+}
--- /dev/null
+*************************************************************************
+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.
--- /dev/null
+#=======================================================================
+# 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)
--- /dev/null
+#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,