tensormatrix_mpi.cpp 6.81 KB
Newer Older
Camille Coti's avatar
Camille Coti committed
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <cstdlib>
#include <ginac/ginac.h>
#include <fstream> // debug?
#include <signal.h> // necessaire ?
#include <sys/wait.h> // necessaire ?
#include <mpi.h>

#include <unistd.h> // debug

Camille Coti's avatar
Camille Coti committed
11
12
#include "tensormatrix.h"
#include "utils.h"
Camille Coti's avatar
Camille Coti committed
13

14
15
16
17
#ifdef TAUPROF
#include <TAU.h>
#endif

Camille Coti's avatar
Camille Coti committed
18
#define DEBUG 0
Camille Coti's avatar
Camille Coti committed
19
20
21
22
23
24
25

namespace gi = GiNaC;

/*
  libginac-dev ginac-tools
  mpic++ -O3 -g -Wall -o tensormatrix_mpi tensormatrix_mpi.cpp -lginac  -Wno-unused-variable
*/
26
27
28
29
30

/* Arguments:
   tensormatrix_mpi [N] [Function name] [Nb of foremen]
   Function names being: 
   - M/m: Master-Worker -> multiply_1level_mw
Camille Coti's avatar
Camille Coti committed
31
32
   - n/N: Master-Worker, coarser grain -> multiply_1level_mw2
   - o/O: Master-Worker, middle grain -> multiply_1level_mw3
33
   - A/a: Master-Worker, addition on a slave -> multiply_1level_mw_addslave
34
   - B/b: Master-Worker, coarser grain, addition on a slave -> multiply_1level_mw_addslave2
Camille Coti's avatar
Camille Coti committed
35
36
   - D/d: Master-Worker, middle grain, addition on a slave -> multiply_1level_mw_addslave3
   - E/e: Master-Worker, middle grain, addition on a slave, parallel final addition -> multiply_1level_mw_addslave4
37
   - H/h: Hierarchical master-worker -> multiply_1level_mw_hierarch
Camille Coti's avatar
Camille Coti committed
38
   - i/I: Hierarchical master-worker, coarser grain -> multiply_1level_mw_hierarch
39
   - C/c: Combined -> multiply_combined
40
41
*/

Camille Coti's avatar
Camille Coti committed
42
43
44
45
/* Sequentiel sur Minimum
real	3m31,034s
*/

46
47
48
49
/*******************************************************************************
 *                          Global variables                                   *
 *******************************************************************************/

Camille Coti's avatar
Camille Coti committed
50
MPI_Datatype DT_PARAMETERS;
Camille Coti's avatar
Camille Coti committed
51
52
MPI_Datatype DT_PARAMETERS_2_1;
MPI_Datatype DT_PARAMETERS_2_2;
53
MPI_Datatype DT_PARAMETERS_S;
Camille Coti's avatar
Camille Coti committed
54

Camille Coti's avatar
Camille Coti committed
55
56
unsigned int nbforemen = NBFOREMEN;     /* Number of foremen to use with the hierarchical M/W */
unsigned int maxresult = MAXRESULT;     /* Maximum results in the result queue, addslave version */
57

Camille Coti's avatar
Camille Coti committed
58
59
60
61
62
63
64
65
/*******************************************************************************
 *                               Main function                                 *
 *******************************************************************************/

int main( int argc, char** argv ){

    tensor3D_t T;
    matrix_int_t J;
66
67
    int N = DEFAULTN;
    char tostart = DEFAULTFUNCTION;
Camille Coti's avatar
Camille Coti committed
68
69
70
71
72
    
    gi::ex Tpara = 0;
    gi::ex Tseq = 0;

    double tv_start, tv_para, tv_seq;
Camille Coti's avatar
Output    
Camille Coti committed
73
    int rank, size;
74
75
76
77
78
79
    
#ifdef TAUPROF
    TAU_INIT(&argc, &argv);
    TAU_PROFILE_SET_NODE(0);
#endif
    
Camille Coti's avatar
Camille Coti committed
80
81
82
83
    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
    //    std::cout << "Process " << rank << " has pid " << getpid() << std::endl;

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    /* Parse the command line */

    if( argc >= 2 ) {
        if( argv[1][0] == 'h' ) {
            if( 0 == rank ) help();
            MPI_Finalize();
            return EXIT_SUCCESS;
        }
        N = atoi( argv[1] );
        if( argc >= 3 ) {
            switch( argv[2][0] ) {
            case 'M':
            case 'm':
                tostart = 'm';
                break;
99
100
101
102
            case 'N':
            case 'n':
                tostart = 'n';
                break;
Camille Coti's avatar
Camille Coti committed
103
104
105
106
            case 'O':
            case 'o':
                tostart = 'o';
                break;
107
108
109
110
            case 'A':
            case 'a':
                tostart = 'a';
                break;
111
112
113
114
            case 'B':
            case 'b':
                tostart = 'b';
                break;
Camille Coti's avatar
Camille Coti committed
115
116
117
118
            case 'D':
            case 'd':
                tostart = 'd';
                break;
Camille Coti's avatar
Camille Coti committed
119
120
121
122
            case 'E':
            case 'e':
                tostart = 'e';
                break;
123
124
125
126
            case 'H':
            case 'h':
                tostart = 'h';
                break;
Camille Coti's avatar
Camille Coti committed
127
128
129
130
            case 'I':
            case 'i':
                tostart = 'i';
                break;
131
132
133
134
            case 'C':
            case 'c':
                tostart = 'c';
                break;
Camille Coti's avatar
Camille Coti committed
135
136
137
138
139
140
141
142
            case 'S':
            case 's':
                tostart = 's';
                break;
            case '1':
            case '2':
                tostart = argv[2][0];
                break;
143
144
145
146
147
            default:
                std::cout << "Wrong function name. Using " << tostart << std::endl;
                break;
            }
            if( argc >= 4 ) {
Camille Coti's avatar
Camille Coti committed
148
                nbforemen = atoi( argv[3] );  /* these two variables are obtained from the same CLI parameter but since they are */
149
                maxresult = atoi( argv[3] );  /* used in two functions for two purposes, use two different names                */
150
151
152
153
            }
        }
    }

Camille Coti's avatar
Camille Coti committed
154
155
156
157
158
159
160
161
162
163
164
    /* Initialize the tensor with symbolic values */
    
    create_tensor_3D( T, N, N, N );

    /* Initialize the simplectic matrix */

    init_simplectic( J, N, N );

    /* Compute it in parallel */
    
    tv_start = getTime();
Camille Coti's avatar
Camille Coti committed
165
166
    switch( tostart ){
    case 'm':
167
        Tpara = multiply_1level_mw( T, N );
Camille Coti's avatar
Camille Coti committed
168
        break;
169
170
171
    case 'n':
        Tpara = multiply_1level_mw2( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
172
173
174
    case 'o':
        Tpara = multiply_1level_mw3( T, N );
        break;
175
176
    case 'a':
        Tpara = multiply_1level_mw_addslave( T, N );
Camille Coti's avatar
Camille Coti committed
177
        break;
178
179
180
    case 'b':
        Tpara = multiply_1level_mw_addslave2( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
181
182
183
    case 'd':
        Tpara = multiply_1level_mw_addslave3( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
184
185
186
    case 'e':
        Tpara = multiply_1level_mw_addslave4( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
187
188
189
    case 'h':
        Tpara = multiply_2levels_mw_hierarch( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
190
191
192
    case 'i':
        Tpara = multiply_2levels_mw_hierarch2( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
193
194
195
    case 'c':
        Tpara = multiply_combined( T, N );
        break;
Camille Coti's avatar
Camille Coti committed
196
    case 's':
Camille Coti's avatar
Camille Coti committed
197
        Tpara = multiply_seq( T, N );
Camille Coti's avatar
Camille Coti committed
198
199
        break;
    case '1':
Camille Coti's avatar
Camille Coti committed
200
201
202
203
        Tpara = multiply_1level( T, N );
        break;
    case '2':
        Tpara = multiply_2levels( T, N );
Camille Coti's avatar
Camille Coti committed
204
205
206
207
        break;
    default:
        std::cerr << "Wrong function called" << std::endl;
    }
Camille Coti's avatar
Camille Coti committed
208
209
210
211
212
213
214
215
216
217
218
219
    tv_para = getTime();

    /* Local verification */
    
    if( 0 == rank ) {
#if DEBUG
        Tseq = multiply_1level( T, J, N );
        tv_seq = getTime();
        
        std::cout << "Tpara3=" << Tpara << ";" << std::endl;
        std::cout << "Tseq=" << Tseq << ";" << std::endl;
#endif
220
        std::cout.precision( 4 );
Camille Coti's avatar
Output    
Camille Coti committed
221
222
223
        MPI_Comm_size( MPI_COMM_WORLD, &size );
        //        std::cout << "Time: ";
        //std::cout << "parallel    " << ( tv_para - tv_start ) / 1e6 << "   ";
Camille Coti's avatar
Output    
Camille Coti committed
224
        std::cout << size << "\t" << tostart << "\t" << N << "\t" << ( tv_para - tv_start ) / 1e6 << "   ";
Camille Coti's avatar
Camille Coti committed
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#if DEBUG
        std::cout << "sequential  " << ( tv_seq - tv_para ) / 1e6 << "   ";
        /* this verification does not work, the manual one (copy-paste in ginsh) works */
        std::cout << "Equal? " << ( Tseq.is_equal( Tpara )  ? "yes" : "no" ) << std::endl;
#endif
        std::cout << std::endl;

        //        std::cout << "Difference? " << ( Tseq -= Tpara  ) << std::endl;
    }

    MPI_Finalize();
    return EXIT_SUCCESS;
}

239

Camille Coti's avatar
Camille Coti committed
240