2

This code should generate the same output. But the c output seems to be rounded up while c++ is not. I don't understand what is going on here. Please explain.

Upto the point where I show the code, same values are passed to both c and c++ code.

c code:

unsigned int sz1=sz+1; 
double* bMat = (double*)calloc(bMatSize,bMatSize * sizeof(double));

for (unsigned int ii = 0; ii<sz; ii++)
    for (unsigned int jj = 0; jj <= ii; jj++)
    {
       bMat[jj*sz1 + ii] = simgms_math_ddot(numBFunc, queueTest[ii], queueTest[jj] );
       bMat[ii*sz1 + jj] = bMat[jj*sz1 + ii];
    }

c++ code:

std::vector<double> bMat;
unsigned int sz1=sz+1;
bMat.resize(sz1*sz1);
for(unsigned int ii=0; ii<sz; ii++)
    for(unsigned int jj=0; jj<=ii; jj++)
    {
        bMat.at(jj*sz1+ii)=simgms_math_ddot(numBFunc, queueTest.at(ii).data(), queueTest.at(jj).data());
        bMat.at(ii*sz1+jj)=bMat.at(jj*sz1+ii);
    }

for (int i = 0; i < bMat.size(); ++i) {
   std::cout << bMat[i] << ' ';
}
std::cout << std::endl;

common function

double simgms_math_ddot(unsigned int numElements, double aMat[], double bMat[])

{
    const MKL_INT n=numElements;

    double res = cblas_ddot(n, aMat, 1, bMat, 1);

    return res;
}

c coutput (bMat)

0 0 -1 0 0 -1 -1 -1 0  

c++ coutput (bMat)

 1.05e-05 0.00134 -1 0.00134 1.11 -1 -1 -1 0 

And the error matrix contains values:

1.78e-15 0.387 1.3 -0.48 -17.5 2.28 -0.387 -1.78e-15 1.48 -0.33 -17.3 2.4 -1.3 -1.48 -1.11e-16 1.08 -0.926 2.41 0.48 0.33 -1.08 0 0.551 0.74 17.5 17.3 0.926 -0.551 0 -0.384 -2.28 -2.4 -2.41 -0.74 0.384 0

std::deque< double* > queueTest;

....Its filled with errorMatrix elements, which are 2d arrays,

 e.g: queueTest.push_front(errorMatrix);
MadHatter
  • 321
  • 7
  • 17

1 Answers1

1

The problem is probably because of the way you're storing queueTest in a deque.

queueTest.at(ii).data()

reaches the iith element without problem (but with O(n) complexity, and can make you think that it's indexed access whereas it's not), but if you pass the address of the first element of the std::deque to your C program, adding an offset won't work because, unlike std::vector memory, std::deque memory isn't contiguous (it's a linked list) so you're getting random data for your coefficients.

From http://www.cplusplus.com/reference/deque/deque/:

unlike vectors, deques are not guaranteed to store all its elements in contiguous storage locations: accessing elements in a deque by offsetting a pointer to another element causes undefined behavior.

The quickfix to be able to use it from the C side is to convert your deque to a vector.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219