Search code examples
cdivide-by-zero

Near identical functions, yet only some give divide by 0 errors


Was given a function to do simple matrix-matrix element-wise division. However, running the int8 & int16 versions return Integer divide by 0 errors from valgrind, & seg faults from command line. The int32, spfp and dpfp functions, which I ensured were the same text besides type declaration, do not have this problem. The values in the matrix are randomly genrated with the rand() function. Why would only some of these return divide by 0 errors?

First Function

double matrix_matrix_div_elementwise_int8(int size,int threads)
{
//initialize index variables, random number generator, and timer
int i;
int size2D=size*size;
srand(SEED);
struct TIME_STRUCT start,end;

//allocate memory for matrices
INT8_TYPE *A=malloc(sizeof(INT8_TYPE)*(size*size));
INT8_TYPE *B=malloc(sizeof(INT8_TYPE)*(size*size));
INT8_TYPE *C=malloc(sizeof(INT8_TYPE)*(size*size));

//initialize input matrices to random numbers
//initialize output matrix to zeros
for(i=0;i<(size*size);i++)
{
    A[i]=rand();
    B[i]=rand();
    C[i]=0;
}

//serial operation
if(threads==1)
{
    //start timer
    TIME_GET(&start);
    //computation
    for(i=0;i<size2D;i++)
    {
        C[i]=A[i]/B[i];
    }
    //end timer
    TIME_GET(&end);
}
//parallel operation
else
{
    //start timer
    TIME_GET(&start);
    //parallelize with OpenMP
    #pragma omp parallel for num_threads(threads) private(i)
    //computation
    for(i=0;i<size2D;i++)
    {
        C[i]=A[i]/B[i];
    }
    //end timer
    TIME_GET(&end);
}

//free memory
free(C);
free(B);
free(A);

return TIME_RUNTIME(start,end);
} 

Second Function

double matrix_matrix_div_elementwise_int32(int size,int threads)
{
//initialize index variables, random number generator, and timer
int i;
int size2D=size*size;
srand(SEED);
struct TIME_STRUCT start,end;

//allocate memory for matrices
INT32_TYPE *A=malloc(sizeof(INT32_TYPE)*(size*size));
INT32_TYPE *B=malloc(sizeof(INT32_TYPE)*(size*size));
INT32_TYPE *C=malloc(sizeof(INT32_TYPE)*(size*size));

//initialize input matrices to random numbers
//initialize output matrix to zeros
for(i=0;i<(size*size);i++)
{
    A[i]=rand();
    B[i]=rand();
    C[i]=0;
}

//serial operation
if(threads==1)
{
    //start timer
    TIME_GET(&start);
    //computation
    for(i=0;i<size2D;i++)
    {
        C[i]=A[i]/B[i];
    }
    //end timer
    TIME_GET(&end);
}
//parallel operation
else
{
    //start timer
    TIME_GET(&start);
    //parallelize with OpenMP
    #pragma omp parallel for num_threads(threads) private(i)
    //computation
    for(i=0;i<size2D;i++)
    {
        C[i]=A[i]/B[i];
    }
    //end timer
    TIME_GET(&end);
}

//free memory
free(C);
free(B);
free(A);

return TIME_RUNTIME(start,end);

}


Solution

  • If B[i] is ever 0, you'll get a divide by zero problem. rand() can return 0.

    So sometimes B[i]=rand(); will assign 0 to B[i].

    As stated in the comment, this will be more common with fewer bits as 0 is a more likely outcome of the rand() operation.