FPBench Logo

Examples 1.2

Examples of FPCore 1.2 expressions

FPBench is a standard benchmark suite for the floating-point community. The benchmark suite contains a common format for floating-point computation and metadata and a common set of accuracy measures:

  1. The FPCore input format
  2. FPCore example inputs
  3. Metadata for FPCore benchmarks
  4. Standard measures of error

Rounding with cast

The cast operation is necessary for explicitly rounding values without performing other numerical operations. Precision annotations specified with ! never cause any numerical operations to occur; they only change the rounding context.

For example, the expression

(! :precision binary64 (! :precision binary32 x))

will not round the value of the variable x. This expression is the same as simply specifying

x

regardless of the rounding context. To round x, it is necessary to cast it in a context with the desired precision. The expression

(! :precision binary64 (! :precision binary32 (cast x)))

will round x to binary32 precision (here the outer annotation for binary64 precision is redundant, as it will be overwritten by the inner one), while the expression

(! :precision binary64 (cast (! :precision binary32 (cast x))))

will round x twice, first to binary32 precision, and then from binary32 to binary64 precision.

Because numerical operations already round their outputs, it should not be necessary to cast in most cases, unless double rounding is specifically intended. For example, in an expression such as

(! :precision binary64
   ([ x (+ y 1)])
  )

the value stored in x will already be rounded to binary64 precision, as the addition is done in a context with that precision. Inserting an explicit cast around either the addition or the use of x would cause double rounding, and while in the case of binary64 precision this is a no-op, for other rounding contexts it could lead to undesirable behavior.

Inheriting properties in rounding contexts

All properties not explicitly specified in a ! precision annotation are inherited from the parent context. For the top level expression in an FPCore benchmark, the parent context includes all the overall properties of the benchmark.

For example, in the following benchmark

(FPCore ()
 :name "foo"
 :math-library gnu-libm-2.34
 :spec 0
  (! :precision binary64 (sin PI)))

the sin operation will take place in a context with name "foo", math-library gnu-libm-2.34, spec 0, and binary64 precision. Even properties that are seemingly unrelated to rounding, such as the name of the benchmark, are inherited. The FPCore standard does not prohibit tools from implementing rounding functions that depend on these properties, or other tool-specific properties, although having a rounding function that depends on name is not advised.

Properties in the rounding context might come from multiple different annotations. For example, in the expression

(! :math-library gnu-libm-2.34 (! :round toZero (! :precision binary32 (+ x 1))))

the addition will take place as expected in a context with binary32 precision, toZero rounding direction, and the gnu-libm-2.34 math library. This can be useful if some, but not all, of the properties are shared by multiple subexpressions. For example, in the expression

(! :precision binary64 (- (! :round toPositive (+ x y)) (! :round toNegative (+ x y))))

all of the operations will take place in a context with binary64 precision, but the additions will use different rounding directions.