Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Iker Martín Álvarez
Proteo
Commits
af1175a5
Commit
af1175a5
authored
Dec 15, 2021
by
iker_martin
Browse files
WIP. Terminando de anyadir Merge method. Sigue habiendo un error de memoria
parent
0a5e948b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Codes/Main/Main.c
View file @
af1175a5
...
@@ -91,7 +91,6 @@ int main(int argc, char *argv[]) {
...
@@ -91,7 +91,6 @@ int main(int argc, char *argv[]) {
get_benchmark_configuration
(
&
config_file
);
//No se obtiene bien el archivo
get_benchmark_configuration
(
&
config_file
);
//No se obtiene bien el archivo
get_benchmark_results
(
&
results
);
//No se obtiene bien el archivo
get_benchmark_results
(
&
results
);
//No se obtiene bien el archivo
set_results_post_reconfig
(
results
,
group
->
grp
,
config_file
->
sdr
,
config_file
->
adr
);
set_results_post_reconfig
(
results
,
group
->
grp
,
config_file
->
sdr
,
config_file
->
adr
);
printf
(
"HIJOS 2
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
comm
);
if
(
config_file
->
comm_tam
)
{
if
(
config_file
->
comm_tam
)
{
group
->
compute_comm_array
=
malloc
(
config_file
->
comm_tam
*
sizeof
(
char
));
group
->
compute_comm_array
=
malloc
(
config_file
->
comm_tam
*
sizeof
(
char
));
...
@@ -115,14 +114,20 @@ int main(int argc, char *argv[]) {
...
@@ -115,14 +114,20 @@ int main(int argc, char *argv[]) {
int
spawn_type
=
COMM_SPAWN_MERGE
;
// TODO Pasar a CONFIG
int
spawn_type
=
COMM_SPAWN_MERGE
;
// TODO Pasar a CONFIG
int
spawn_is_single
=
COMM_SPAWN_MULTIPLE
;
// TODO Pasar a CONFIG
int
spawn_is_single
=
COMM_SPAWN_MULTIPLE
;
// TODO Pasar a CONFIG
group
->
grp
=
group
->
grp
-
1
;
// TODO REFACTOR???
group
->
grp
=
group
->
grp
-
1
;
// TODO REFACTOR???
printf
(
"TEST 3
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
do
{
do
{
group
->
grp
=
group
->
grp
+
1
;
group
->
grp
=
group
->
grp
+
1
;
set_benchmark_grp
(
group
->
grp
);
set_benchmark_grp
(
group
->
grp
);
get_malleability_user_comm
(
&
comm
);
get_malleability_user_comm
(
&
comm
);
printf
(
"TEST 4
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
if
(
comm
==
MPI_COMM_NULL
)
{
printf
(
"Mi comunicador es nulo?
\n
"
);
}
MPI_Comm_size
(
comm
,
&
(
group
->
numP
));
MPI_Comm_size
(
comm
,
&
(
group
->
numP
));
MPI_Comm_rank
(
comm
,
&
(
group
->
myId
));
MPI_Comm_rank
(
comm
,
&
(
group
->
myId
));
printf
(
"MAIN 2
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
comm
);
printf
(
"TEST 5
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
//printf("MAIN 2\n"); fflush(stdout); MPI_Barrier(comm);
if
(
config_file
->
resizes
!=
group
->
grp
+
1
)
{
if
(
config_file
->
resizes
!=
group
->
grp
+
1
)
{
set_malleability_configuration
(
spawn_type
,
spawn_is_single
,
config_file
->
phy_dist
[
group
->
grp
+
1
],
-
1
,
config_file
->
aib
,
-
1
);
set_malleability_configuration
(
spawn_type
,
spawn_is_single
,
config_file
->
phy_dist
[
group
->
grp
+
1
],
-
1
,
config_file
->
aib
,
-
1
);
...
@@ -133,9 +138,10 @@ int main(int argc, char *argv[]) {
...
@@ -133,9 +138,10 @@ int main(int argc, char *argv[]) {
malleability_add_data
(
&
run_id
,
1
,
MAL_INT
,
1
,
1
);
malleability_add_data
(
&
run_id
,
1
,
MAL_INT
,
1
,
1
);
}
}
}
}
printf
(
"
MAIN 3
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
comm
);
printf
(
"
TEST 7
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
res
=
work
();
res
=
work
();
printf
(
"TEST 8
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
print_local_results
();
print_local_results
();
}
while
((
config_file
->
resizes
>
group
->
grp
+
1
)
&&
(
spawn_type
==
COMM_SPAWN_MERGE
||
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
));
}
while
((
config_file
->
resizes
>
group
->
grp
+
1
)
&&
(
spawn_type
==
COMM_SPAWN_MERGE
||
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
));
...
@@ -148,7 +154,7 @@ int main(int argc, char *argv[]) {
...
@@ -148,7 +154,7 @@ int main(int argc, char *argv[]) {
print_final_results
();
// Pasado este punto ya no pueden escribir los procesos
print_final_results
();
// Pasado este punto ya no pueden escribir los procesos
MPI_Finalize
();
MPI_Finalize
();
free_application_data
();
//
free_application_data();
return
0
;
return
0
;
}
}
...
...
Codes/malleability/ProcessDist.c
View file @
af1175a5
...
@@ -74,7 +74,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
...
@@ -74,7 +74,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
slurm_data
->
type_creation
=
type_creation
;
slurm_data
->
type_creation
=
type_creation
;
slurm_data
->
spawn_is_single
=
spawn_is_single
;
slurm_data
->
spawn_is_single
=
spawn_is_single
;
if
(
type_creation
==
COMM_SPAWN_SERIAL
)
{
if
(
type_creation
==
COMM_SPAWN_SERIAL
||
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE
)
{
if
(
myId
==
root
)
{
if
(
myId
==
root
)
{
processes_dist
(
argv
,
numP
,
type_dist
);
processes_dist
(
argv
,
numP
,
type_dist
);
...
@@ -85,7 +85,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
...
@@ -85,7 +85,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
// WORK
// WORK
generic_spawn
(
myId
,
root
,
slurm_data
->
spawn_is_single
,
child
,
comm
);
generic_spawn
(
myId
,
root
,
slurm_data
->
spawn_is_single
,
child
,
comm
);
if
(
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE
_PTHREAD
&&
0
)
{
if
(
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE
)
{
int
numParents
;
int
numParents
;
MPI_Comm_size
(
comm
,
&
numParents
);
MPI_Comm_size
(
comm
,
&
numParents
);
if
(
numParents
<
numP
)
{
//Expand
if
(
numParents
<
numP
)
{
//Expand
...
@@ -102,7 +102,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
...
@@ -102,7 +102,7 @@ int init_slurm_comm(char *argv, int myId, int numP, int root, int type_dist, int
commSlurm
=
MAL_SPAWN_COMPLETED
;
commSlurm
=
MAL_SPAWN_COMPLETED
;
}
else
if
(
type_creation
==
COMM_SPAWN_PTHREAD
)
{
}
else
if
(
type_creation
==
COMM_SPAWN_PTHREAD
||
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE_PTHREAD
)
{
commSlurm
=
MAL_SPAWN_PENDING
;
commSlurm
=
MAL_SPAWN_PENDING
;
if
((
spawn_is_single
&&
myId
==
root
)
||
!
spawn_is_single
)
{
if
((
spawn_is_single
&&
myId
==
root
)
||
!
spawn_is_single
)
{
...
@@ -229,7 +229,7 @@ void proc_adapt_expand(int *numP, int numC, MPI_Comm intercomm, MPI_Comm *comm,
...
@@ -229,7 +229,7 @@ void proc_adapt_expand(int *numP, int numC, MPI_Comm intercomm, MPI_Comm *comm,
*
numP
=
numC
;
*
numP
=
numC
;
if
(
*
comm
!=
MPI_COMM_WORLD
&&
*
comm
!=
MPI_COMM_NULL
)
{
if
(
*
comm
!=
MPI_COMM_WORLD
&&
*
comm
!=
MPI_COMM_NULL
)
{
//
MPI_Comm_free(comm);
FIXME
MPI_Comm_free
(
comm
);
}
}
*
comm
=
new_comm
;
*
comm
=
new_comm
;
}
}
...
@@ -281,8 +281,7 @@ void* thread_work(void* creation_data_arg) {
...
@@ -281,8 +281,7 @@ void* thread_work(void* creation_data_arg) {
generic_spawn
(
creation_data
->
myId
,
creation_data
->
root
,
slurm_data
->
spawn_is_single
,
returned_comm
,
creation_data
->
comm
);
generic_spawn
(
creation_data
->
myId
,
creation_data
->
root
,
slurm_data
->
spawn_is_single
,
returned_comm
,
creation_data
->
comm
);
//TODO Eliminar el && 0
if
(
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE_PTHREAD
)
{
if
(
slurm_data
->
type_creation
==
COMM_SPAWN_MERGE_PTHREAD
&&
0
)
{
//MPI_Comm_size(creation_data->comm, &numP);
//MPI_Comm_size(creation_data->comm, &numP);
numP
=
1
;
//FIXME BORRAR
numP
=
1
;
//FIXME BORRAR
if
(
numP
<
creation_data
->
numP_childs
)
{
//Expand
if
(
numP
<
creation_data
->
numP_childs
)
{
//Expand
...
@@ -360,8 +359,10 @@ void generic_spawn(int myId, int root, int spawn_is_single, MPI_Comm *child, MPI
...
@@ -360,8 +359,10 @@ void generic_spawn(int myId, int root, int spawn_is_single, MPI_Comm *child, MPI
if
(
spawn_is_single
)
{
if
(
spawn_is_single
)
{
single_spawn_connection
(
myId
,
root
,
comm
,
child
);
single_spawn_connection
(
myId
,
root
,
comm
,
child
);
}
else
{
}
else
{
int
rootBcast
=
MPI_PROC_NULL
;
if
(
myId
==
root
)
rootBcast
=
MPI_ROOT
;
create_processes
(
myId
,
root
,
child
,
comm
);
create_processes
(
myId
,
root
,
child
,
comm
);
MPI_Bcast
(
&
spawn_is_single
,
1
,
MPI_INT
,
MPI_ROOT
,
*
child
);
MPI_Bcast
(
&
spawn_is_single
,
1
,
MPI_INT
,
rootBcast
,
*
child
);
}
}
}
}
...
...
Codes/malleability/malleabilityManager.c
View file @
af1175a5
...
@@ -88,10 +88,8 @@ int init_malleability(int myId, int numP, int root, MPI_Comm comm, char *name_ex
...
@@ -88,10 +88,8 @@ int init_malleability(int myId, int numP, int root, MPI_Comm comm, char *name_ex
state
=
MAL_NOT_STARTED
;
state
=
MAL_NOT_STARTED
;
// Si son el primer grupo de procesos, obtienen los datos de los padres
// Si son el primer grupo de procesos, obtienen los datos de los padres
printf
(
"TESTHHH 1
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
MPI_Comm_get_parent
(
&
(
mall
->
intercomm
));
MPI_Comm_get_parent
(
&
(
mall
->
intercomm
));
if
(
mall
->
intercomm
!=
MPI_COMM_NULL
)
{
if
(
mall
->
intercomm
!=
MPI_COMM_NULL
)
{
printf
(
"TESTHHH 2
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
Children_init
();
Children_init
();
return
MALLEABILITY_CHILDREN
;
return
MALLEABILITY_CHILDREN
;
}
}
...
@@ -383,6 +381,7 @@ void Children_init() {
...
@@ -383,6 +381,7 @@ void Children_init() {
if
(
spawn_is_single
)
{
if
(
spawn_is_single
)
{
malleability_establish_connection
(
mall
->
myId
,
MALLEABILITY_ROOT
,
&
(
mall
->
intercomm
));
malleability_establish_connection
(
mall
->
myId
,
MALLEABILITY_ROOT
,
&
(
mall
->
intercomm
));
}
}
MPI_Bcast
(
&
(
mall_conf
->
spawn_type
),
1
,
MPI_INT
,
MALLEABILITY_ROOT
,
mall
->
intercomm
);
MPI_Bcast
(
&
root_parents
,
1
,
MPI_INT
,
MALLEABILITY_ROOT
,
mall
->
intercomm
);
MPI_Bcast
(
&
root_parents
,
1
,
MPI_INT
,
MALLEABILITY_ROOT
,
mall
->
intercomm
);
MPI_Bcast
(
&
numP_parents
,
1
,
MPI_INT
,
root_parents
,
mall
->
intercomm
);
MPI_Bcast
(
&
numP_parents
,
1
,
MPI_INT
,
root_parents
,
mall
->
intercomm
);
...
@@ -419,17 +418,20 @@ void Children_init() {
...
@@ -419,17 +418,20 @@ void Children_init() {
// Guardar los resultados de esta transmision
// Guardar los resultados de esta transmision
recv_results
(
mall_conf
->
results
,
mall
->
root
,
mall_conf
->
config_file
->
resizes
,
mall
->
intercomm
);
recv_results
(
mall_conf
->
results
,
mall
->
root
,
mall_conf
->
config_file
->
resizes
,
mall
->
intercomm
);
printf
(
"HIJOS 1
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
printf
(
"HIJOS 1
%d
\n
"
,
mall
->
numP
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
)
{
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
)
{
proc_adapt_expand
(
&
(
mall
->
numP
),
mall
->
numC
,
mall
->
intercomm
,
&
(
mall
->
comm
),
MALLEABILITY_CHILDREN
);
proc_adapt_expand
(
&
(
mall
->
numP
),
mall
->
numP
+
numP_parents
,
mall
->
intercomm
,
&
(
mall
->
comm
),
MALLEABILITY_CHILDREN
);
//TODO Que valor se pasa?
//
if(mall->thread_comm != MPI_COMM_WORLD) MPI_Comm_free(&(mall->thread_comm));
if
(
mall
->
thread_comm
!=
MPI_COMM_WORLD
)
MPI_Comm_free
(
&
(
mall
->
thread_comm
));
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
mall
->
thread_comm
=
aux
;
mall
->
thread_comm
=
aux
;
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
mall
->
user_comm
=
aux
;
mall
->
user_comm
=
aux
;
}
}
printf
(
"HIJOS 2
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
MPI_Comm_disconnect
(
&
(
mall
->
intercomm
));
MPI_Comm_disconnect
(
&
(
mall
->
intercomm
));
}
}
...
@@ -447,7 +449,6 @@ void Children_init() {
...
@@ -447,7 +449,6 @@ void Children_init() {
int
spawn_step
(){
int
spawn_step
(){
mall_conf
->
results
->
spawn_start
=
MPI_Wtime
();
mall_conf
->
results
->
spawn_start
=
MPI_Wtime
();
state
=
init_slurm_comm
(
mall
->
name_exec
,
mall
->
myId
,
mall
->
numC_spawned
,
mall
->
root
,
mall_conf
->
spawn_dist
,
mall_conf
->
spawn_type
,
mall_conf
->
spawn_is_single
,
mall
->
thread_comm
,
&
(
mall
->
intercomm
));
state
=
init_slurm_comm
(
mall
->
name_exec
,
mall
->
myId
,
mall
->
numC_spawned
,
mall
->
root
,
mall_conf
->
spawn_dist
,
mall_conf
->
spawn_type
,
mall_conf
->
spawn_is_single
,
mall
->
thread_comm
,
&
(
mall
->
intercomm
));
printf
(
"TEST 2 un total de %d
\n
"
,
mall
->
numC_spawned
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_SERIAL
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
)
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_SERIAL
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
)
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
=
MPI_Wtime
()
-
mall_conf
->
results
->
spawn_start
;
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
=
MPI_Wtime
()
-
mall_conf
->
results
->
spawn_start
;
...
@@ -515,6 +516,7 @@ int start_redistribution() {
...
@@ -515,6 +516,7 @@ int start_redistribution() {
int
rootBcast
=
MPI_PROC_NULL
;
int
rootBcast
=
MPI_PROC_NULL
;
if
(
mall
->
myId
==
mall
->
root
)
rootBcast
=
MPI_ROOT
;
if
(
mall
->
myId
==
mall
->
root
)
rootBcast
=
MPI_ROOT
;
MPI_Bcast
(
&
(
mall_conf
->
spawn_type
),
1
,
MPI_INT
,
rootBcast
,
mall
->
intercomm
);
MPI_Bcast
(
&
(
mall
->
root
),
1
,
MPI_INT
,
rootBcast
,
mall
->
intercomm
);
MPI_Bcast
(
&
(
mall
->
root
),
1
,
MPI_INT
,
rootBcast
,
mall
->
intercomm
);
MPI_Bcast
(
&
(
mall
->
numP
),
1
,
MPI_INT
,
rootBcast
,
mall
->
intercomm
);
MPI_Bcast
(
&
(
mall
->
numP
),
1
,
MPI_INT
,
rootBcast
,
mall
->
intercomm
);
send_config_file
(
mall_conf
->
config_file
,
rootBcast
,
mall
->
intercomm
);
send_config_file
(
mall_conf
->
config_file
,
rootBcast
,
mall
->
intercomm
);
...
@@ -609,6 +611,8 @@ int end_redistribution() {
...
@@ -609,6 +611,8 @@ int end_redistribution() {
send_results
(
mall_conf
->
results
,
rootBcast
,
mall_conf
->
config_file
->
resizes
,
mall
->
intercomm
);
send_results
(
mall_conf
->
results
,
rootBcast
,
mall_conf
->
config_file
->
resizes
,
mall
->
intercomm
);
printf
(
"PADRES 7
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
)
{
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE_PTHREAD
)
{
double
time_adapt
=
MPI_Wtime
();
double
time_adapt
=
MPI_Wtime
();
if
(
mall
->
numP
>
mall
->
numC
)
{
//Shrink
if
(
mall
->
numP
>
mall
->
numC
)
{
//Shrink
...
@@ -618,9 +622,11 @@ int end_redistribution() {
...
@@ -618,9 +622,11 @@ int end_redistribution() {
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
=
MPI_Wtime
()
-
time_adapt
;
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
=
MPI_Wtime
()
-
time_adapt
;
}
else
{
}
else
{
printf
(
"PADRES 8
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
proc_adapt_expand
(
&
(
mall
->
numP
),
mall
->
numC
,
mall
->
intercomm
,
&
(
mall
->
comm
),
MALLEABILITY_NOT_CHILDREN
);
proc_adapt_expand
(
&
(
mall
->
numP
),
mall
->
numC
,
mall
->
intercomm
,
&
(
mall
->
comm
),
MALLEABILITY_NOT_CHILDREN
);
//
if(mall->thread_comm != MPI_COMM_WORLD) MPI_Comm_free(&(mall->thread_comm));
FIXME
if
(
mall
->
thread_comm
!=
MPI_COMM_WORLD
)
MPI_Comm_free
(
&
(
mall
->
thread_comm
));
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
MPI_Comm_dup
(
mall
->
comm
,
&
aux
);
mall
->
thread_comm
=
aux
;
mall
->
thread_comm
=
aux
;
...
@@ -628,11 +634,13 @@ int end_redistribution() {
...
@@ -628,11 +634,13 @@ int end_redistribution() {
mall
->
user_comm
=
aux
;
mall
->
user_comm
=
aux
;
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_SERIAL
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
)
if
(
mall_conf
->
spawn_type
==
COMM_SPAWN_SERIAL
||
mall_conf
->
spawn_type
==
COMM_SPAWN_MERGE
)
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
+=
MPI_Wtime
()
-
time_adapt
;
mall_conf
->
results
->
spawn_time
[
mall_conf
->
grp
]
+=
MPI_Wtime
()
-
time_adapt
;
}
}
result
=
MAL_DIST_ADAPTED
;
result
=
MAL_DIST_ADAPTED
;
}
else
{
}
else
{
result
=
MAL_DIST_COMPLETED
;
result
=
MAL_DIST_COMPLETED
;
}
}
printf
(
"PADRES 11
\n
"
);
fflush
(
stdout
);
MPI_Barrier
(
MPI_COMM_WORLD
);
MPI_Comm_disconnect
(
&
(
mall
->
intercomm
));
MPI_Comm_disconnect
(
&
(
mall
->
intercomm
));
state
=
MAL_NOT_STARTED
;
state
=
MAL_NOT_STARTED
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment