I have this code for matrix multiplication, using pthreads, but I get the error "cast to pointer from integer of different size"
I don't know what is wrong.I am new to pthread, and this is what I have made so far:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#define NTHREADS 4
int dim ;
pthread_mutex_t m;       /* Mutex protecting the sum value */
pthread_t thread_id[NTHREADS];  /* Thread ids */
float **A, **B, **C;
void *prod (void *s){
    int *id=(int *)s;
    int idd=*id;
    /* Define local variables */
    int i,j,k, start, end, len ;
    float **Aa, **Bb, **Cc;
    start = dim*idd;       /* Start of this threads slice of the vectors */
    end   = start + dim;      /* End of the slice */
    for (i = 0 ; i < dim; i++)
    {
        for (j = 0;  j < dim; j++)
        {
            Cc[i][j] = 0;
            for (i=start; i<end ; i++) {
                Cc[i][j] += Aa[i][k] * Bb[k][j];
            }
        }
    }
    pthread_mutex_lock (&m);     /* Lock the mutex */
    C[i][j] += Cc[i][j];                /* Update the shared variable */
    pthread_mutex_unlock (&m);   /* Unlock the mutex */
    pthread_exit(NULL);            /* Done! */
}
int main ( int argc, char *argv[] )
{
    void *status;
    float **A, **B, **C;
    int i,j,k;
    if ( argc == 2)
        dim = atoi(argv[1]); // get the dimension of the matrix
    // from the command prompt
    else
        dim = 128;
    A = (float **)malloc(sizeof(float*)*dim);
    B = (float **)malloc(sizeof(float*)*dim);
    C = (float **)malloc(sizeof(float*)*dim);
    for (i = 0 ; i < dim; i++)
    {
        A[i] = (float *)malloc(sizeof(float)*dim);
        B[i] = (float *)malloc(sizeof(float)*dim);
        C[i] = (float *)malloc(sizeof(float)*dim);
    }
    for (i=0; i<dim; i++)
    {
        for (j = 0 ; j < dim; j++)
        {
            A[i][j]=rand();
            B[i][j]=rand();
        }
    }
    struct timeval t1, t2;
    gettimeofday(&t1, NULL);
    // you need to parallelize this
    // perform the multiplication
    for(i=0;i<NTHREADS;i++) {
        pthread_create(&thread_id[i], NULL, prod, (void *)i);
    }
    /* Wait on the other threads */
    for(i=0;i<NTHREADS;i++) {
        pthread_join(thread_id[i], &status);
    }
    gettimeofday(&t2, NULL);
    double t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec ) / 1000000.0;
    // take the difference and report it in seconds
    printf("execution time %f seconds\n",t);
}
the error at this line:
pthread_create(&thread_id[i], NULL, prod, (void *)i); 
                You are wrongly using an hack to pass an integer to a thread. The idea behind what you are doing is an integer is 4 bytes and a pointer is 4 bytes in x86_32 (8 bytes in x86_64) so I can convert an integer type to a pointer type and then convert it back to an int type without losing any data. This works in the majority of the scenarios, but there is not guarantee that a pointer and an integer have the same size. The C standard does not specify this.
The compiler returns a warning because you are converting an int to void * which may have different size, ( but in fact in your machine they have the same size). 
There is a error in you code, when you convert the int to a void* calling the pthead_create function, you should convert it back to an integer type. So, this line is wrong :
int *id=(int *)s;
it should be :
int id = (int)s; 
Consider this example where the argument for the thread function is zero.
s=0; therefore  ---> *id=(int*)0; // Null pointer 
This is a pointer to the address zero. When you try to deference it, you will likely get an segmentation fault.
The best way to do this is by using the intptr_t type. This type has the same size of a pointer (not int) in every architecture. It is defined as follows :
Integer type capable of holding a value converted from a void pointer and then be converted back to that type with a value that compares equal to the original pointer.
So you can do something like this:
#include <stdint.h>
void *threadfunc(void *param)
{
    int id = (intptr_t) param;
    ...
}
int i, r;
r = pthread_create(&thread, NULL, threadfunc, (void *) (intptr_t) i);
(This example code has been taken from : How to cast an integer to void pointer?)
However, there is not guarantee that the size of int is the same of the size of intptr_t, but it's really unlikely that some data is lost in the conversion process. 
EDIT
Additional errors :
float **Aa, **Bb, **Cc; are not initialised. start and end exceeds the limit of the array. The matrix rows are not allocated in consecutive memory areas. I would consider to rewrite the code for the matrix multiplication because the algorithm is wrong.
You want to cast integer, short, or char and set a pointer to that value use the reinterpret_cast() call. We used to just (void*) the value and the older compilers were happy, but the new versions, for example g++ 4.8.5, know the value is not the right size for a pointer. reinterpret_cast is just like a cast but it resized it so the compile doesn't complain.
For example:
int i = 3;
pointer void * ptr;
ptr = (void*)i;                    // will generate the warning
ptr = reinterpret_cast<void*>(i);  // No warning is generated
X11 example getting a character out of addr and then setting XTPOINTER to it.
val = (XTPOINTER)(*(char*)toVal.addr);                   //  warning
val = reinterpret_cast<XTPOINTER>(*(short*)toVal.addr);  // No warning
                        Correct way to achieve this is by referencing the variable "i" (check http://man7.org/linux/man-pages/man3/pthread_create.3.html):
pthread_create(&thread_id[i], NULL, prod, (void *)&i);
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With