Quantcast
Viewing all articles
Browse latest Browse all 77

Why does Cilk Plus __sec_reduce_add differ from a sequential addition?

I'm finding a significant error for certain input values when I use a particular offset to add values. Due to the nature of the algorithm I'm considering (not relevant to the question), I need to start a sum value with the first element of an array. I was able to extract a minimal working example, which is appended below.

Even though there are less than 50 floating point additions involved, I'm seeing error far beyond that order of magnitude of ulps, and I don't understand what I am doing wrong. See the following code snippet, along with the invocation and what my results are:

// icc -std=c++11 -O3 commutative.cpp -o commutative -lm -lcilkrts -fp-model precise -fp-model source
// echo 0x1.2a30cp+36 -0x1.04b3b6p+35 0x1.92204p+32 -0x1.b9319p+34 0x1.1a88f4p+33 -0x1.39b0f2p+35 0x1.744a68p+31 -0x1.73385p+34 0x1.6ad72ep+34 -0x1.8a076cp+34 0x1.dc6578p+34 0x1.8f075ep+35 0x1.d1bd22p+34 0x1.ff211p+30 0x1.43b8cap+36 -0x1.1efd2p+32 0x1.1e646cp+35 0x1.c91e16p+34 -0x1.b1e3eap+35 -0x1.52ce1p+32 -0x1.cf6f2cp+34 -0x1.c7007ep+35 -0x1.efe1fp+35 0x1.90143cp+34 | ./commutative

#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>

#include <cilk/cilk.h>

int main(int argc, char**) {
    if (argc != 1) {
        printf("Usage: echo 1 2 3 | commutative\n");
        return 1;
    }

    std::vector<float> vec;
    while(!feof(stdin)) {
        float f;
        if (scanf("%a", &f) > 0) {
            vec.push_back(f);
        }
    }

    auto sz = vec.size();
    printf("size %d\n", sz);

    float* arr = &vec.front();
    float sum1 = arr[0];
    sum1 += __sec_reduce_add(arr[1:sz-1] + arr[1:sz-1]);

    float sum2 = arr[0];
    for (int i = 1; i < sz; ++i) sum2 += arr[i] + arr[i];

    if (sum1 != sum2) printf("ERROR! unequal sums (%f vs %f), rel. err %f\n",
                             sum1, sum2, (float) std::abs((sum1 - sum2) / sum2));
    printf("sum1 %a\n", sum1);
    printf("sum2 %a\n", sum2);
    return sum1 != sum2;
}
size 24
ERROR! unequal sums (-13099008.000000 vs -13139968.000000), rel. err 0.003117
sum1 -0x1.8fcp+23
sum2 -0x1.91p+23
$ icc --version
icc (ICC) 15.0.2 20150121
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

 


Viewing all articles
Browse latest Browse all 77

Trending Articles