Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
TensorJoseph
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Camille Coti
TensorJoseph
Commits
a1412956
Commit
a1412956
authored
5 years ago
by
Camille Coti
Browse files
Options
Downloads
Patches
Plain Diff
Missing files
parent
3d2ae59b
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/masterworker3.cpp
+222
-0
222 additions, 0 deletions
src/masterworker3.cpp
src/mw_addslave3.cpp
+237
-0
237 additions, 0 deletions
src/mw_addslave3.cpp
with
459 additions
and
0 deletions
src/masterworker3.cpp
0 → 100644
+
222
−
0
View file @
a1412956
#include
<iostream>
#include
<mpi.h>
#include
<ginac/ginac.h>
#include
"products.h"
#include
"utils_parall.h"
#include
"parall_constants.h"
#include
"parall_internal.h"
#include
"utils.h"
namespace
gi
=
GiNaC
;
/*******************************************************************************
* Parallel 1-level decomposition *
*******************************************************************************/
gi
::
ex
multiply_1level_master3
(
tensor3D_t
&
T
,
unsigned
int
size
,
MPI_Comm
comm
=
MPI_COMM_WORLD
)
{
gi
::
ex
Tens
=
0
;
unsigned
int
a2
,
a4
;
gi
::
lst
symbols
;
MPI_Status
status
;
char
*
expr_c
;
size_t
expr_c_size
=
0
;
int
src
,
np
,
running
=
0
;
unsigned
int
len
;
parameters_2_1_t
pzero
(
0
,
0
);
MPI_Comm_size
(
comm
,
&
np
);
expr_c
=
NULL
;
expr_c
=
(
char
*
)
malloc
(
3279
);
// TMP
int
i
,
j
;
i
=
0
;
j
=
0
;
int
receivedresults
=
0
;
unsigned
int
N
=
size
/
2
;
std
::
vector
<
parameters_2_1_t
>
input
;
std
::
vector
<
std
::
string
>
results_s
;
std
::
vector
<
gi
::
ex
>
results
;
/* Build a list of argument sets */
for
(
a4
=
0
;
a4
<
N
;
a4
++
){
for
(
a2
=
0
;
a2
<
N
;
a2
++
){
parameters_2_1_t
p
(
a4
,
a2
);
input
.
push_back
(
p
);
}
}
/* Compute the set of symbols */
/* Could be done while the first slave is working */
symbols
=
all_symbols_3D
(
size
);
/* Distribute the work */
while
(
input
.
size
()
>
0
)
{
MPI_Recv
(
&
len
,
1
,
MPI_UNSIGNED
,
MPI_ANY_SOURCE
,
MPI_ANY_TAG
,
comm
,
&
status
);
src
=
status
.
MPI_SOURCE
;
if
(
status
.
MPI_TAG
==
TAG_PULL
)
{
/* Nothing else will come: just send wome work */
send_work
(
input
,
src
,
comm
);
}
else
{
if
(
status
.
MPI_TAG
==
TAG_RES
){
src
=
status
.
MPI_SOURCE
;
/* The first message contains the length of what is coming next */
if
(
len
!=
0
)
{
if
(
len
>
expr_c_size
)
{
expr_c_size
=
len
;
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
expr_c
=
(
char
*
)
malloc
(
expr_c_size
);
// The \0 was added by the slave
}
/* Receive the result */
MPI_Recv
(
expr_c
,
len
,
MPI_CHAR
,
src
,
TAG_EXPR
,
comm
,
&
status
);
/* put it in the result queue */
std
::
string
s
(
expr_c
);
send_work
(
input
,
src
,
comm
);
/* Process what I have just received */
/* Could be given to a slave... */
gi
::
ex
received
=
de_linearize_expression
(
s
,
symbols
);
Tens
+=
received
;
#if DEBUG
results
.
push_back
(
received
);
results_s
.
push_back
(
s
);
receivedresults
++
;
#endif
}
else
{
/* Send more work */
send_work
(
input
,
src
,
comm
);
}
}
else
{
std
::
cerr
<<
"Wrong tag received "
<<
status
.
MPI_TAG
<<
std
::
endl
;
}
}
}
/* Wait until everyone is done */
running
=
np
-
1
;
// all the slaves are running
while
(
running
>
0
)
{
MPI_Recv
(
&
len
,
1
,
MPI_UNSIGNED
,
MPI_ANY_SOURCE
,
MPI_ANY_TAG
,
comm
,
&
status
);
src
=
status
.
MPI_SOURCE
;
if
(
len
!=
0
)
{
if
(
len
>
expr_c_size
)
{
expr_c_size
=
len
;
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
expr_c
=
(
char
*
)
malloc
(
expr_c_size
);
// The \0 was added by the slave
}
/* Receive the result */
MPI_Recv
(
expr_c
,
len
,
MPI_CHAR
,
src
,
TAG_EXPR
,
comm
,
&
status
);
/* And send the END signal */
send_end
(
src
,
pzero
,
comm
);
running
--
;
/* Process what I have just received */
/* Could be given to a slave... */
/* put it in the result queue */
std
::
string
s
(
expr_c
);
gi
::
ex
received
=
de_linearize_expression
(
s
,
symbols
);
Tens
+=
received
;
#if DEBUG
results
.
push_back
(
received
);
results_s
.
push_back
(
s
);
receivedresults
++
;
#endif
}
else
{
send_end
(
src
,
pzero
,
comm
);
running
--
;
}
}
#if DEBUG
std
::
cout
<<
"Received "
<<
receivedresults
<<
" results"
<<
std
::
endl
;
std
::
cout
<<
"Tpara="
<<
Tens
<<
";"
<<
std
::
endl
;
#endif
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
return
Tens
;
}
void
multiply_1level_slave3
(
tensor3D_t
&
T
,
int
size
,
MPI_Comm
comm
=
MPI_COMM_WORLD
)
{
gi
::
ex
Tens
;
unsigned
int
a2
,
a4
;
unsigned
int
len
=
0
;
parameters_t
params
;
MPI_Status
status
;
char
*
expr_c
;
int
rank
;
MPI_Comm_rank
(
comm
,
&
rank
);
/* Ask for some work */
MPI_Send
(
&
len
,
1
,
MPI_UNSIGNED
,
ROOT
,
TAG_PULL
,
comm
);
while
(
true
){
/* Receive a set of parameters */
MPI_Recv
(
&
params
,
1
,
DT_PARAMETERS_2_1
,
ROOT
,
MPI_ANY_TAG
,
comm
,
&
status
);
if
(
status
.
MPI_TAG
==
TAG_WORK
){
a4
=
params
.
a4
;
a2
=
params
.
a2
;
Tens
=
one_level1_product
(
&
T
,
size
,
a4
,
a2
);
send_result
(
Tens
);
}
else
{
if
(
status
.
MPI_TAG
==
TAG_END
){
return
;
}
else
{
std
::
cerr
<<
"Wrong tag received on slave "
<<
status
.
MPI_TAG
<<
std
::
endl
;
}
}
}
}
/* Communication protocol:
M -> W: always the same size, therefore unique communication
W -> M: send an unsigned int (size of the expression), then the expression (table of chars)
*/
gi
::
ex
multiply_1level_mw3
(
tensor3D_t
&
T
,
int
size
)
{
// simpler: same dimension everywhere
int
rank
;
gi
::
ex
Tens
=
0
;
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
rank
);
/* Create a new datatype for the parameters */
create_parameters_datatype_2_1
();
/* Here we go */
if
(
0
==
rank
)
{
Tens
=
multiply_1level_master3
(
T
,
size
);
}
else
{
multiply_1level_slave3
(
T
,
size
);
}
/* Finalize */
free_parameters_2_1_dt
();
return
Tens
;
}
This diff is collapsed.
Click to expand it.
src/mw_addslave3.cpp
0 → 100644
+
237
−
0
View file @
a1412956
#include
<iostream>
#include
<mpi.h>
#include
<ginac/ginac.h>
#include
"products.h"
#include
"utils_parall.h"
#include
"parall_constants.h"
#include
"parall_internal.h"
#include
"utils.h"
#include
"profiling.h"
namespace
gi
=
GiNaC
;
/*******************************************************************************
* Parallel 1-level decomposition with addition on a slave *
*******************************************************************************/
gi
::
ex
multiply_1level_master_addslave3
(
tensor3D_t
&
T
,
unsigned
int
size
,
MPI_Comm
comm
=
MPI_COMM_WORLD
)
{
gi
::
ex
Tens
=
0
;
unsigned
int
a2
,
a4
;
gi
::
ex
A
;
gi
::
lst
symbols
;
MPI_Status
status
;
char
*
expr_c
;
size_t
expr_c_size
=
0
;
int
src
,
np
,
running
=
0
;
unsigned
int
len
;
parameters_2_1_t
pzero
(
0
,
0
);
MPI_Comm_size
(
comm
,
&
np
);
expr_c
=
NULL
;
expr_c
=
(
char
*
)
malloc
(
3279
);
int
i
,
j
;
i
=
0
;
j
=
0
;
int
receivedresults
=
0
;
unsigned
int
N
=
size
/
2
;
std
::
vector
<
parameters_2_1_t
>
input
;
std
::
vector
<
std
::
string
>
results
;
/* length and char* */
/* Build a list of argument sets */
for
(
a4
=
0
;
a4
<
N
;
a4
++
){
for
(
a2
=
0
;
a2
<
N
;
a2
++
){
parameters_2_1_t
p
(
a4
,
a2
);
input
.
push_back
(
p
);
}
}
/* Compute the set of symbols */
/* Could be done while the first slave is working */
symbols
=
all_symbols_3D
(
size
);
/* Distribute the work */
while
(
input
.
size
()
>
0
)
{
MPI_Recv
(
&
len
,
1
,
MPI_UNSIGNED
,
MPI_ANY_SOURCE
,
MPI_ANY_TAG
,
comm
,
&
status
);
if
(
status
.
MPI_TAG
==
TAG_PULL
)
{
/* Nothing else will come: just send wome work */
src
=
status
.
MPI_SOURCE
;
send_work
(
input
,
src
);
}
else
{
if
(
status
.
MPI_TAG
==
TAG_RES
){
src
=
status
.
MPI_SOURCE
;
/* The first message contains the length of what is coming next */
if
(
len
!=
0
)
{
if
(
len
>
expr_c_size
)
{
expr_c_size
=
len
;
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
expr_c
=
(
char
*
)
malloc
(
expr_c_size
);
// The \0 was added by the slave
}
/* Receive the result */
MPI_Recv
(
expr_c
,
len
,
MPI_CHAR
,
src
,
TAG_EXPR
,
comm
,
&
status
);
/* Put it in the result queue */
results
.
push_back
(
std
::
string
(
expr_c
)
);
}
/* Send more work */
send_work_addslave
(
input
,
results
,
src
);
}
else
{
std
::
cerr
<<
"Wrong tag received "
<<
status
.
MPI_TAG
<<
std
::
endl
;
}
}
}
/* Wait until everyone is done */
running
=
np
-
1
;
// all the slaves are running
while
(
running
>
0
)
{
/* TODO: here all we should receive is either TAG_EXPR or TAG_PULL if the input is too small */
MPI_Recv
(
&
len
,
1
,
MPI_UNSIGNED
,
MPI_ANY_SOURCE
,
MPI_ANY_TAG
,
comm
,
&
status
);
src
=
status
.
MPI_SOURCE
;
if
(
len
!=
0
)
{
if
(
len
>
expr_c_size
)
{
expr_c_size
=
len
;
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
expr_c
=
(
char
*
)
malloc
(
expr_c_size
);
// The \0 was added by the slave
}
/* Receive the result */
MPI_Recv
(
expr_c
,
len
,
MPI_CHAR
,
src
,
TAG_EXPR
,
comm
,
&
status
);
/* Put it in the result queue */
results
.
push_back
(
std
::
string
(
expr_c
)
);
}
send_add_or_end_addslave
(
results
,
src
,
&
running
,
pzero
);
}
/* Add whatever I have left */
Tens
=
add_expressions
(
results
,
symbols
);
#if DEBUG
std
::
cout
<<
"Received "
<<
receivedresults
<<
" results"
<<
std
::
endl
;
std
::
cout
<<
"Tpara="
<<
Tens
<<
";"
<<
std
::
endl
;
#endif
if
(
NULL
!=
expr_c
)
free
(
expr_c
);
return
Tens
;
}
void
multiply_1level_slave_addslave3
(
tensor3D_t
&
T
,
unsigned
int
size
,
MPI_Comm
comm
=
MPI_COMM_WORLD
)
{
gi
::
ex
Tens
;
int
a2
,
a4
;
unsigned
int
len
=
0
;
parameters_t
params
;
MPI_Status
status
;
char
*
expr_c
;
int
rank
;
MPI_Comm_rank
(
comm
,
&
rank
);
/* Ask for some work */
MPI_Send
(
&
len
,
1
,
MPI_UNSIGNED
,
ROOT
,
TAG_PULL
,
comm
);
/* Compute the set of symbols */
gi
::
lst
symbols
=
all_symbols_3D
(
size
);
while
(
true
){
/* Receive a set of parameters */
MPI_Recv
(
&
params
,
1
,
DT_PARAMETERS_2_1
,
ROOT
,
MPI_ANY_TAG
,
comm
,
&
status
);
if
(
status
.
MPI_TAG
==
TAG_WORK
){
a4
=
params
.
a4
;
a2
=
params
.
a2
;
Tens
=
one_level1_product
(
&
T
,
size
,
a4
,
a2
);
send_result
(
Tens
);
}
else
{
if
(
status
.
MPI_TAG
==
TAG_ADD
)
{
/* Receive a set of expressions to add */
/* Number of expressions received */
int
nb
=
params
.
a4
;
/* Length of each string */
unsigned
int
*
lengths
=
(
unsigned
int
*
)
malloc
(
nb
*
sizeof
(
unsigned
int
)
);
MPI_Recv
(
lengths
,
nb
,
MPI_INT
,
ROOT
,
TAG_ADD
,
comm
,
&
status
);
std
::
vector
<
std
::
string
>
results_s
;
char
*
c_str
;
int
i
;
int
len
;
for
(
i
=
0
;
i
<
nb
;
i
++
)
{
len
=
lengths
[
i
]
+
1
;
c_str
=
(
char
*
)
malloc
(
len
);
MPI_Recv
(
c_str
,
len
,
MPI_CHAR
,
ROOT
,
TAG_ADD
,
comm
,
&
status
);
c_str
[
len
-
1
]
=
'\0'
;
// The master sends C++ strings, which do not contain the final '\0'
results_s
.
push_back
(
std
::
string
(
c_str
)
);
free
(
c_str
);
}
/* Delinearize all the expressions and add them */
Tens
=
add_expressions
(
results_s
,
symbols
);
/* Send the result */
send_result
(
Tens
);
}
else
{
if
(
status
.
MPI_TAG
==
TAG_END
){
return
;
}
else
{
std
::
cerr
<<
"Wrong tag received on slave "
<<
status
.
MPI_TAG
<<
std
::
endl
;
}
}
}
}
}
/* Communication protocol:
M -> W: always the same size, therefore unique communication
W -> M: send an unsigned int (size of the expression), then the expression (table of chars)
*/
gi
::
ex
multiply_1level_mw_addslave3
(
tensor3D_t
&
T
,
int
size
)
{
// simpler: same dimension everywhere
int
rank
;
gi
::
ex
Tens
=
0
;
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
rank
);
/* Create a new datatype for the parameters */
create_parameters_datatype_2_1
();
/* Here we go */
if
(
0
==
rank
)
{
Tens
=
multiply_1level_master_addslave3
(
T
,
size
);
}
else
{
multiply_1level_slave_addslave3
(
T
,
size
);
}
/* Finalize */
free_parameters_2_1_dt
();
return
Tens
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment