Отправить массив mpz_t через mpi

Я использую libgmp (GMP) для работы с очень длинными целыми числами, хранящимися как mpz_t: http://gmplib.org/manual/Integer-Internals.html#Integer-Internals

mpz_t переменные представляют целые числа с использованием знака и величины в пространстве, динамически распределяемом и перераспределяемом.

Поэтому я думаю, что mpz_t похож на указатель.

Как я могу отправить массив mpz_t переменных с данными через MPI?


person osgx    schedule 12.03.2011    source источник


Ответы (2)


Используйте mpz_import() и mpz_export() для преобразования между mpz_t и например. char массивы, которые затем можно отправлять/получать по MPI. Будьте осторожны с правильными параметрами, связанными с порядком байтов и т. д.

person Aasmund Eldhuset    schedule 12.03.2011
comment
Как я могу экспортировать массив mpz_ts? - person osgx; 12.03.2011
comment
Я не знаю, есть ли для этого встроенная поддержка, поэтому вам может понадобиться выделить массив, достаточно большой для хранения всех чисел, а затем несколько раз вызывать mpz_export() и постепенно заполнять массив. Вы также можете использовать mpz_out_raw() и mpz_inp_raw(). если есть способ создавать потоки памяти в C. - person Aasmund Eldhuset; 12.03.2011
comment
я только что обнаружил, что должен передать два массива: первый - это вывод экспорта, а второй - массив count, возвращаемый экспортом! - person osgx; 12.03.2011
comment
@osgx: я забыл об этом подумать. Альтернативным решением может быть чередование счетчиков с экспортируемыми данными: первые четыре байта содержат int, представляющий первый счетчик, затем следуют столько же байтов, представляющих первое число, затем еще четыре байта, представляющих второй счетчик, и так далее. на. - person Aasmund Eldhuset; 12.03.2011

Вот код:

unsigned long *buf, *t; // pointers for ulong array for storing gmp data
unsigned long count, countc; // sizes of data and element sizes array 
unsigned long size = array_size; // size of array
size_t *bc,*tc; // pointers for size_t array to store element sizes;

buf=(unsigned long*)malloc(sizeof(unsigned long)*(size*limb_per_element));
bc=(size_t*)malloc(sizeof(size_t)*(size));

if(rank==SENDER_RANK) {
    t=buf;
    tc=bc;
    for(int i;i<size;i++) {
        mpz_export(t,tc,1,sizeof(unsigned long),0,0, ARRAY(i));
        t+=*tc;
    tc++;
    }
    count=t-buf;
    countc=tc-bc;
    MPI_Send(&count, 1, MPI_UNSIGNED_LONG, 0, 0, MPI_COMM_WORLD);
    MPI_Send(&countc, 1, MPI_UNSIGNED_LONG, 0, 0, MPI_COMM_WORLD);
    MPI_Send(bc, countc*(sizeof(size_t)), MPI_CHAR, 0, 0, MPI_COMM_WORLD);
    MPI_Send(buf, count, MPI_UNSIGNED_LONG, 0, 0, MPI_COMM_WORLD);
} else {
    status=MPI_Recv(&count, 1, MPI_UNSIGNED_LONG, SENDER_RANK, 0, MPI_COMM_WORLD, NULL); 
    status=MPI_Recv(&countc, 1, MPI_UNSIGNED_LONG, SENDER_RANK, 0, MPI_COMM_WORLD, NULL); 
    t=buf;
    tc=bc;
    status=MPI_Recv(bc, countc*(sizeof(size_t)), MPI_CHAR, SENDER_RANK, 0, MPI_COMM_WORLD, NULL); 
    status=MPI_Recv(buf, count, MPI_UNSIGNED_LONG, SENDER_RANK, 0, MPI_COMM_WORLD, NULL); 
    for(int i; i<size; i++) {
        mpz_import(ARRAY(i),*tc,1,sizeof(unsigned long),0,0, t);
        t+=*tc;
        tc++;
    }
}
free(buf);
free(bc);
person Community    schedule 16.03.2011