
my $output=q(./smpi_simgrid.prv);

my $input=q(./smpi_simgrid.trace);

use strict;
use Env;

my($arg);
my($strict_option) = "";

while(defined($arg=shift(@ARGV))) {
    for ($arg) {
        print "$arg \n";
        if (/^-i$/) { $input = shift(@ARGV); last; }
        if (/^-o$/) { $output = shift(@ARGV); last; }
        if (/^-ns$/){ $strict_option = "-n -z"; last; }
        print "unrecognized argument '$arg'";
    }
}

my $pjfile=$input;
$pjfile=~ s/\.trace$/.pjdump/;
$pjfile ne $input or die;

$ENV{LANG}="C";

system("pj_dump $strict_option $input | grep State | sed 's/ //g' | sort -n -t ',' -k 4n > $pjfile");
my $duration = `tail -n 1 $pjfile`;
my @duration = split(/,/,$duration);
$duration = $duration[4];
$duration *= 1E9;
my $nb_nodes = `sed -e 's/.*rank-//' -e 's/,.*//' $pjfile | sort | uniq | wc -l`;
chomp($nb_nodes);
my(%smpi_to_pcf) = (
    "action_allReduce" => "10",
    "action_allToAll"  => "11",
    "action_barrier"   => "8",
    "action_bcast"     => "7",
    "action_gather"    => "13",
    "action_reduce"    => "9",
    "action_reducescatter" => "80",
#        "smpi_replay_finalize" => "32",
#        "smpi_replay_init" => "31"
    );

my($pcf_file_content)="DEFAULT_OPTIONS

LEVEL               THREAD
UNITS               NANOSEC
LOOK_BACK           100
SPEED               1
FLAG_ICONS          ENABLED
NUM_OF_STATE_COLORS 1000
YMAX_SCALE          37


DEFAULT_SEMANTIC

THREAD_FUNC          State As Is


STATES
0    Idle
1    Running
2    Not created
3    Waiting a message
4    Blocking Send
5    Synchronization
6    Test/Probe
7    Scheduling and Fork/Join
8    Wait/WaitAll
9    Blocked
10    Immediate Send
11    Immediate Receive
12    I/O
13    Group Communication
14    Tracing Disabled
15    Others
16    Send Receive
17    Memory transfer


STATES_COLOR
0    {117,195,255}
1    {0,0,255}
2    {255,255,255}
3    {255,0,0}
4    {255,0,174}
5    {179,0,0}
6    {0,255,0}
7    {255,255,0}
8    {235,0,0}
9    {0,162,0}
10    {255,0,255}
11    {100,100,177}
12    {172,174,41}
13    {255,144,26}
14    {2,255,177}
15    {192,224,0}
16    {66,66,66}
17    {255,0,96}

EVENT_TYPE
9   50000001    MPI Point-to-point
VALUES
2   MPI_Recv
1   MPI_Send
0   Outside MPI

EVENT_TYPE
9   50000002    MPI Collective Comm
VALUES
18   MPI_Allgatherv
10   MPI_Allreduce
11   MPI_Alltoall
12   MPI_Alltoallv
8   MPI_Barrier
7   MPI_Bcast
13   MPI_Gather
14   MPI_Gatherv
80   MPI_Reduce_scatter
9   MPI_Reduce
0   Outside MPI


EVENT_TYPE
9   50000003    MPI Other
VALUES
21   MPI_Comm_create
19   MPI_Comm_rank
20   MPI_Comm_size
32   MPI_Finalize
31   MPI_Init
0   Outside MPI


EVENT_TYPE
1    50100001    Send Size in MPI Global OP
1    50100002    Recv Size in MPI Global OP
1    50100003    Root in MPI Global OP
1    50100004    Communicator in MPI Global OP


EVENT_TYPE
6    40000001    Application
VALUES
0      End
1      Begin


EVENT_TYPE
6    40000003    Flushing Traces
VALUES
0      End
1      Begin


GRADIENT_COLOR
0    {0,255,2}
1    {0,244,13}
2    {0,232,25}
3    {0,220,37}
4    {0,209,48}
5    {0,197,60}
6    {0,185,72}
7    {0,173,84}
8    {0,162,95}
9    {0,150,107}
10    {0,138,119}
11    {0,127,130}
12    {0,115,142}
13    {0,103,154}
14    {0,91,166}


GRADIENT_NAMES
0    Gradient 0
1    Grad. 1/MPI Events
2    Grad. 2/OMP Events
3    Grad. 3/OMP locks
4    Grad. 4/User func
5    Grad. 5/User Events
6    Grad. 6/General Events
7    Grad. 7/Hardware Counters
8    Gradient 8
9    Gradient 9
10    Gradient 10
11    Gradient 11
12    Gradient 12
13    Gradient 13
14    Gradient 14


EVENT_TYPE
9    40000018    Tracing mode:
VALUES
1      Detailed
2      CPU Bursts
";

my($pcf_output)=$output;
$pcf_output =~ s/\.prv$/.pcf/;
open OUTPUT, "> $pcf_output";
print OUTPUT $pcf_file_content;
close OUTPUT;

my($line);
open(INPUT,$pjfile) or die;
open(OUTPUT,"> $output") or die;
my(@tab);

@tab=();
foreach (1..$nb_nodes) {
    push @tab,1;
}
my $node_list = join(',',@tab);
@tab=();
foreach (1..$nb_nodes) {
    push @tab,"1:$_";
}
my $thread_list = join(',',@tab);

print OUTPUT "#Paraver (generated with perl from SMPI):${duration}_ns:$nb_nodes($node_list):1:$nb_nodes($thread_list),9\n";

my $comm_list = join(':',(1..$nb_nodes));
my $comm=1;
print OUTPUT "c:1:$comm:$nb_nodes:$comm_list\n";  $comm++;
foreach (1..$nb_nodes) {
    print OUTPUT "c:1:$comm:1:$_\n";  
}

while(defined($line=<INPUT>)) {
    chomp($line);
    my($Foo1,$rank,$Foo2,$start,$end,$duration,$Foo3,$type) = split(/,/,$line);
    $rank=~ s/\D*//g;
    $rank++;
    $start *= 1E9;
    $end *= 1E9;
    if(defined($smpi_to_pcf{$type})) {
        print OUTPUT "1:$rank:1:$rank:1:$start:$end:13\n"; # group communication
        print OUTPUT "2:$rank:1:$rank:1:$start:50000002:$smpi_to_pcf{$type}\n";
        print OUTPUT "2:$rank:1:$rank:1:$end:50000002:0\n"; # Output MPI
#          print OUTPUT "1:$rank:1:$rank:1:$start:$end:$smpi_to_pcf{$type}\n";
    } else {
        warn("Unknown type $type: Skipping $line\n");
    }
}
