程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MPI 帶狀劃分矩陣轉置

MPI 帶狀劃分矩陣轉置

編輯:C++入門知識

MPI矩陣操作分兩部分:

1.讀文件

2.操作

讀文件的時候可以使用MPI_File_read來直接分配數據。

矩陣存儲的格式:連續內存空間,頭兩個int表示行列數,後續位置使用double表示數據,行優先存儲。

文件使用二進制方式直接存儲矩陣內存塊。

轉置非方陣,使用新申請的內存。如果使用O(1)的內存,並沒有規則的交換的過程,所以不大現實,邏輯太復雜,太慢。


[cpp]
#include <stdio.h>  
#include <stdlib.h>  
#include "mpi.h"  
 
/*
matrix transpostion using mpi 
linear division
author GT
2013.4.18
*/ 
int rank,size; 
/*
file is in binary form
initial two int are size
afterwards is double data
all matrix is in the same form
*/ 
/*
read the size of @fileName
return in @sizes 
*/ 
void readSize(char *fileName, int* sizes) 

    FILE *in; 
    in = fopen(fileName, "rb"); 
    if(in == NULL) 
    { 
        return ; 
    } 
    fread(sizes, sizeof(int), 2, in); 
    fclose(in); 

/*
divide the matrix columns averagely among all threads
while reading the @fileName
the matrix is @row*@col
return in @dest 
*/ 
void readMatrixByColumn (char *fileName, int row, int col, double *dest) 

    //amazingly simple function to averagely divide array  
    //[colStart,colEnd)  
    int colStart = rank * col / size; 
    int colEnd = (rank + 1) * col / size;  
    int myCol = colEnd - colStart; 
    //columns for a thread   
    MPI_Datatype columns;  
    MPI_Type_vector (row, myCol, col, MPI_DOUBLE, &columns); 
    MPI_Type_commit(&columns); 
    //file operation  
    MPI_File file; 
    MPI_Status status; 
    MPI_File_open (MPI_COMM_WORLD, fileName, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file); 
    //current start position  
    MPI_Offset offset = colStart * sizeof(double) + 2 * sizeof(int); 
    //read  
    MPI_File_set_view (file, offset, MPI_DOUBLE, columns, "native", MPI_INFO_NULL); 
    MPI_File_seek (file, 0, MPI_SEEK_SET); 
    double *data = (double*)((int*)dest + 2); 
    MPI_File_read (file, data, myCol * row, MPI_DOUBLE, &status); 
    //set coordinate  
    *((int*) dest) = row; 
    *((int*) dest + 1) = myCol; 
    //clean up  
    MPI_File_close (&file); 
    MPI_Type_free (&columns); 

     
 
/*
convert 1d index @one into 2d coordinate @xy 
the matrix is row*@col
*/ 
extern inline void one2two (int one, int col,int *xy) 

    xy[0] = one / col; 
    xy[1] = one % col; 

/*
convert using two ints
*/ 
extern inline int two2one3 (int x, int y, int col) 

    return x * col + y; 

 
/*
convert 2d @xy into 1d @return 
matrix is row * @col
*/ 
extern inline int two2one2 (int *xy, int col) 

    return two2one3 (xy[0], xy[1], col); 

/*
transposition 2d @xy to 1d @return
*/ 
extern inline int transpositionTwo2one (int *xy, int row) 

    return two2one3 (xy[1], xy[0], row); 

/*
transposite @matrix and store in @tran
*/ 
 
void transposite (double *matrix, double *tran) 

    int row = *((int*) matrix); 
    int col = *((int*) matrix + 1); 
    *((int*) tran) = col; 
    *((int*) tran + 1) = row; 
    int xy[2]; 
    double *matrixData = (double*) ((int*) matrix + 2); 
    double *tranData = (double*) ((int*) tran + 2); 
    for ( int i = 0; i < row * col; ++ i ) 
    { 
        one2two ( i, col, xy ); 
        *(tranData + transpositionTwo2one (xy, row)) = *(matrixData + i);    
    } 

 
void show (double *matrix) 

    double *data =(double*) ((int*) matrix + 2); 
    int row = *((int*) matrix); 
    int col = *((int*) matrix + 1); 
    printf ("%d %d matrix \n", row, col); 
    for (int i = 0; i < row; ++i) 
    { 
        for (int j = 0; j < col; ++j) 
        { 
            printf("%lf ",*(data + i * col + j)); 
        } 
        printf("\n"); 
    } 

void testRead (char *fileName, int *sizes) 

    int err; 
    MPI_File file; 
    MPI_Status status; 
    MPI_File_open (MPI_COMM_WORLD, fileName, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file); 
    MPI_File_set_view (file, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL); 
    if(0 == rank) 
        printf("e %d %d %d \n", err, sizes[0], sizes[1] ); 
    err = MPI_File_read (file, sizes, 2, MPI_INT, &status); 
    if(0 == rank) 
        printf("ee %d %d %d \n", err, sizes[0], sizes[1] ); 
    MPI_File_close (&file); 

int main (int argc, char* argv[]) 

    MPI_Init (&argc, &argv); 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); 
    MPI_Comm_size (MPI_COMM_WORLD, &size); 
 
    int sizes[2]; 
    readSize (argv[1], sizes); 
    double *matrix = (double*) malloc(sizes[0] * sizes[1] * sizeof(double) + 2 *sizeof(int)); 
    double *transp = (double*) malloc(sizes[0] * sizes[1] * sizeof(double) + 2 *sizeof(int)); 
    readMatrixByColumn (argv[1], sizes[0], sizes[1], matrix); 
    transposite(matrix ,transp); 
    if (2 == rank) 
    { 
        printf ("matrix\n"); 
        show (matrix); 
        printf ("transposition \n"); 
        show (transp); 
    } 
    MPI_Finalize (); 
    free (matrix); 
    return 0; 

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"

/*
matrix transpostion using mpi
linear division
author GT
2013.4.18
*/
int rank,size;
/*
file is in binary form
initial two int are size
afterwards is double data
all matrix is in the same form
*/
/*
read the size of @fileName
return in @sizes
*/
void readSize(char *fileName, int* sizes)
{
 FILE *in;
 in = fopen(fileName, "rb");
 if(in == NULL)
 {
  return ;
 }
 fread(sizes, sizeof(int), 2, in);
 fclose(in);
}
/*
divide the matrix columns averagely among all threads
while reading the @fileName
the matrix is @row*@col
return in @dest
*/
void readMatrixByColumn (char *fileName, int row, int col, double *dest)
{
 //amazingly simple function to averagely divide array
 //[colStart,colEnd)
 int colStart = rank * col / size;
 int colEnd = (rank + 1) * col / size;
 int myCol = colEnd - colStart;
 //columns for a thread
 MPI_Datatype columns;
 MPI_Type_vector (row, myCol, col, MPI_DOUBLE, &columns);
 MPI_Type_commit(&columns);
 //file operation
 MPI_File file;
 MPI_Status status;
 MPI_File_open (MPI_COMM_WORLD, fileName, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file);
 //current start position
 MPI_Offset offset = colStart * sizeof(double) + 2 * sizeof(int);
 //read
 MPI_File_set_view (file, offset, MPI_DOUBLE, columns, "native", MPI_INFO_NULL);
 MPI_File_seek (file, 0, MPI_SEEK_SET);
 double *data = (double*)((int*)dest + 2);
 MPI_File_read (file, data, myCol * row, MPI_DOUBLE, &status);
 //set coordinate
 *((int*) dest) = row;
 *((int*) dest + 1) = myCol;
 //clean up
 MPI_File_close (&file);
 MPI_Type_free (&columns);
}
 

/*
convert 1d index @one into 2d coordinate @xy
the matrix is row*@col
*/
extern inline void one2two (int one, int col,int *xy)
{
 xy[0] = one / col;
 xy[1] = one % col;
}
/*
convert using two ints
*/
extern inline int two2one3 (int x, int y, int col)
{
 return x * col + y;
}

/*
convert 2d @xy into 1d @return
matrix is row * @col
*/
extern inline int two2one2 (int *xy, int col)
{
 return two2one3 (xy[0], xy[1], col);
}
/*
transposition 2d @xy to 1d @return
*/
extern inline int transpositionTwo2one (int *xy, int row)
{
 return two2one3 (xy[1], xy[0], row);
}
/*
transposite @matrix and store in @tran
*/

void transposite (double *matrix, double *tran)
{
 int row = *((int*) matrix);
 int col = *((int*) matrix + 1);
 *((int*) tran) = col;
 *((int*) tran + 1) = row;
 int xy[2];
 double *matrixData = (double*) ((int*) matrix + 2);
 double *tranData = (double*) ((int*) tran + 2);
 for ( int i = 0; i < row * col; ++ i )
 {
  one2two ( i, col, xy );
  *(tranData + transpositionTwo2one (xy, row)) = *(matrixData + i); 
 }
}

void show (double *matrix)
{
 double *data =(double*) ((int*) matrix + 2);
 int row = *((int*) matrix);
 int col = *((int*) matrix + 1);
 printf ("%d %d matrix \n", row, col);
 for (int i = 0; i < row; ++i)
 {
  for (int j = 0; j < col; ++j)
  {
   printf("%lf ",*(data + i * col + j));
  }
  printf("\n");
 }
}
void testRead (char *fileName, int *sizes)
{
 int err;
 MPI_File file;
 MPI_Status status;
 MPI_File_open (MPI_COMM_WORLD, fileName, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file);
 MPI_File_set_view (file, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL);
 if(0 == rank)
  printf("e %d %d %d \n", err, sizes[0], sizes[1] );
 err = MPI_File_read (file, sizes, 2, MPI_INT, &status);
 if(0 == rank)
  printf("ee %d %d %d \n", err, sizes[0], sizes[1] );
 MPI_File_close (&file);
}
int main (int argc, char* argv[])
{
 MPI_Init (&argc, &argv);
 MPI_Comm_rank (MPI_COMM_WORLD, &rank);
 MPI_Comm_size (MPI_COMM_WORLD, &size);

 int sizes[2];
 readSize (argv[1], sizes);
 double *matrix = (double*) malloc(sizes[0] * sizes[1] * sizeof(double) + 2 *sizeof(int));
 double *transp = (double*) malloc(sizes[0] * sizes[1] * sizeof(double) + 2 *sizeof(int));
 readMatrixByColumn (argv[1], sizes[0], sizes[1], matrix);
 transposite(matrix ,transp);
 if (2 == rank)
 {
  printf ("matrix\n");
  show (matrix);
  printf ("transposition \n");
  show (transp);
 }
 MPI_Finalize ();
 free (matrix);
 return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved