package em.coremark
import BenchAlgI
import Crc
import Utils
# patterned after core_matrix.c
module MatrixBench: BenchAlgI
private:
type matdat_t: int16
type matres_t: int32
config dimN: uint8
var matA: matdat_t[]
var matB: matdat_t[]
var matC: matres_t[]
function addVal(val: matdat_t)
function mulVal(val: matdat_t)
function mulMat()
function mulMatBix()
function mulVec()
function sumDat(clipval: matdat_t): matdat_t
function bix(res: matres_t, lower: uint8, upper: uint8): matres_t
function clip(d: matdat_t, b: bool): matdat_t
function enlarge(val: matdat_t): matdat_t
function prDat(lab: string, mat: matdat_t[])
function prRes(lab: string)
end
def em$construct()
auto i = 0
auto j = 0
while j < memSize
i += 1
j = i * i * 2 * 4
end
dimN = i - 1
matA.length = matB.length = matC.length = dimN * dimN
end
def addVal(val)
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
matA[i * dimN + j] += val
end
end
end
def bix(res, lower, upper)
auto r = <uint32>res
auto l = <uint32>lower
auto u = <uint32>upper
return <matres_t>((r >> l) & (~(0xffffffff << u)))
end
def clip(d, b)
auto x = <uint16>d
return <matdat_t>(x & (b ? 0x0ff : 0x0ffff))
end
def dump()
## TODO -- implement
end
def enlarge(val)
auto v = <uint16>val
return <matdat_t>(0xf000 | v)
end
def kind()
return Utils.Kind.MATRIX
end
def mulVal(val)
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
matC[i * dimN + j] = <matres_t>matA[i * dimN + j] * <matres_t>val
end
end
end
def mulMat()
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
matC[i * dimN + j] = 0
for auto k = 0; k < dimN; k++
matC[i * dimN + j] += <matres_t>matA[i * dimN + k] * <matres_t>matB[k * dimN + j]
end
end
end
end
def mulMatBix()
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
matC[i * dimN + j] = 0
for auto k = 0; k < dimN; k++
auto tmp = <matres_t>matA[i * dimN + k] * <matres_t>matB[k * dimN + j]
matC[i * dimN + j] += bix(tmp, 2, 4) * bix(tmp, 5, 7)
end
end
end
end
def mulVec()
for auto i = 0; i < dimN; i++
matC[i] = 0
for auto j = 0; j < dimN; j++
matC[i] += <matres_t>matA[i * dimN + j] * <matres_t>matB[j]
end
end
end
def print()
prDat("A", matA)
prDat("B", matB)
end
def prDat(lab, mat)
printf "\n%s:\n ", lab
for auto i = 0; i < dimN; i++
auto sep = ""
for auto j = 0; j < dimN; j++
printf "%s%d", sep, mat[i * dimN + j]
sep = ","
end
printf "\n "
end
end
def prRes(lab)
printf "\n%s:\n ", lab
for auto i = 0; i < dimN; i++
auto sep = ""
for auto j = 0; j < dimN; j++
printf "%s%d", sep, matC[i * dimN + j]
sep = ","
end
printf "\n "
end
end
def run(arg)
auto crc = <Crc.sum_t>0
auto val = <matdat_t>arg
auto clipval = enlarge(val)
#
addVal(val)
mulVal(val)
crc = Crc.add16(sumDat(clipval), crc)
#
mulVec()
crc = Crc.add16(sumDat(clipval), crc)
#
mulMat()
crc = Crc.add16(sumDat(clipval), crc)
#
mulMatBix()
crc = Crc.add16(sumDat(clipval), crc)
#
addVal(-val)
return Crc.add16(<int16>crc, Utils.getCrc(Utils.Kind.FINAL))
end
def setup()
auto s32 = <uint32>Utils.getSeed(1) | (<uint32>Utils.getSeed(2) << 16)
auto sd = <matdat_t>s32
sd = 1 if sd == 0
auto order = <matdat_t>1
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
sd = <int16>((order * sd) % 65536)
auto val = <matdat_t>(sd + order)
val = clip(val, false)
matB[i * dimN + j] = val
val += order
val = clip(val, true)
matA[i * dimN + j] = val
order += 1
end
end
end
def sumDat(clipval)
auto cur = <matres_t>0
auto prev = <matres_t>0
auto tmp = <matres_t>0
auto ret = <matdat_t>0
for auto i = 0; i < dimN; i++
for auto j = 0; j < dimN; j++
cur = matC[i * dimN + j]
tmp += cur
if tmp > clipval
ret += 10
tmp = 0
else
ret += (cur > prev) ? 1 : 0
end
prev = cur
end
end
return ret
end