Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F63758976
dumpers.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, May 22, 07:38
Size
6 KB
Mime Type
text/x-c
Expires
Fri, May 24, 07:38 (2 d)
Engine
blob
Format
Raw Data
Handle
17815210
Attached To
rSCINTROPARALLEL Poisson code for introduction to parallelism
dumpers.cc
View Options
/* -------------------------------------------------------------------------- */
#include "dumpers.hh"
#include "grid.hh"
/* -------------------------------------------------------------------------- */
#include <array>
#include <fstream>
#include <iomanip>
#include <sstream>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void
Dumper
::
set_min
(
float
min
)
{
m_min
=
min
;
}
void
Dumper
::
set_max
(
float
max
)
{
m_max
=
max
;
}
float
Dumper
::
min
()
const
{
return
m_min
;
}
float
Dumper
::
max
()
const
{
return
m_max
;
}
/* -------------------------------------------------------------------------- */
void
DumperASCII
::
dump
(
const
Grid
&
grid
,
int
step
)
{
std
::
ofstream
fout
;
std
::
stringstream
sfilename
;
sfilename
<<
"out_"
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
5
)
<<
step
<<
".pgm"
;
fout
.
open
(
sfilename
.
str
());
int
m
=
grid
.
m
();
int
n
=
grid
.
n
();
fout
<<
"P2"
<<
std
::
endl
<<
"# CREATOR: Poisson program"
<<
std
::
endl
;
fout
<<
m
<<
" "
<<
n
<<
std
::
endl
;
fout
<<
255
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
m
;
i
++
)
{
for
(
int
j
=
0
;
j
<
n
;
j
++
)
{
int
v
=
255.
*
(
grid
(
i
,
j
)
-
m_min
)
/
(
m_max
-
m_min
);
v
=
std
::
min
(
v
,
255
);
fout
<<
v
<<
std
::
endl
;
}
}
}
/* -------------------------------------------------------------------------- */
void
DumperBinary
::
dump
(
const
Grid
&
grid
,
int
step
)
{
std
::
stringstream
sfilename
;
std
::
array
<
int
,
2
>
coords
{
0
,
0
},
dims
{
0
,
0
};
#if defined(_MPI)
int
prank
{
0
},
psize
{
1
};
MPI_Comm_rank
(
m_communicator
,
&
prank
);
MPI_Comm_size
(
m_communicator
,
&
psize
);
std
::
array
<
int
,
2
>
periods
{
0
,
0
};
MPI_Cart_get
(
m_communicator
,
dims
.
size
(),
dims
.
data
(),
periods
.
data
(),
coords
.
data
());
#else
dims
=
{
1
,
1
};
#endif
sfilename
<<
"out_"
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
5
)
<<
step
<<
".bmp"
;
int
h
=
grid
.
m
();
int
w
=
grid
.
n
();
int
global_w
=
w
;
std
::
array
<
int
,
2
>
starts
=
{
0
,
0
};
std
::
array
<
int
,
2
>
local_sizes
=
{
h
,
w
};
std
::
array
<
int
,
2
>
global_sizes
=
local_sizes
;
#if defined(_MPI)
// removing the ghosts
if
(
prank
==
0
)
std
::
cout
<<
dims
[
0
]
<<
" "
<<
dims
[
1
]
<<
"
\n
"
;
for
(
std
::
size_t
i
=
0
;
i
<
local_sizes
.
size
();
++
i
)
{
if
(
dims
[
i
]
>
1
)
{
local_sizes
[
i
]
-=
(
coords
[
i
]
==
0
||
coords
[
i
]
==
dims
[
i
]
-
1
?
1
:
2
);
starts
[
i
]
+=
(
coords
[
i
]
==
0
?
0
:
1
);
}
}
std
::
array
<
MPI_Comm
,
2
>
comms
;
// determining the local offset
std
::
array
<
int
,
2
>
offset
=
{
0
,
0
};
std
::
vector
<
std
::
vector
<
int
>>
line_col_size
(
2
);
for
(
size_t
i
=
0
;
i
<
line_col_size
.
size
();
++
i
)
{
std
::
array
<
int
,
2
>
remain_dims
=
{
false
,
false
};
remain_dims
[
i
]
=
true
;
MPI_Cart_sub
(
m_communicator
,
remain_dims
.
data
(),
&
(
comms
[
i
]));
line_col_size
[
i
].
resize
(
dims
[
i
]);
MPI_Allgather
(
&
local_sizes
[
i
],
1
,
MPI_INT
,
line_col_size
[
i
].
data
(),
1
,
MPI_INT
,
comms
[
i
]);
global_sizes
[
i
]
=
0
;
for
(
int
j
=
0
;
j
<
dims
[
i
];
++
j
)
{
global_sizes
[
i
]
+=
line_col_size
[
i
][
j
];
}
}
//for (int i = dims[0] - 1; i > coords[0]; --i) {
for
(
int
i
=
0
;
i
<
coords
[
0
];
++
i
)
{
offset
[
0
]
+=
line_col_size
[
0
][
i
];
}
for
(
int
i
=
0
;
i
<
coords
[
1
];
++
i
)
{
offset
[
1
]
+=
line_col_size
[
1
][
i
];
}
#endif
global_w
=
4
*
((
24
*
global_sizes
[
1
]
+
31
)
/
32
);
// if the file width (3*w) is not a multiple of 4 adds enough bytes to make it
// a multiple of 4
int
padding
=
global_w
-
3
*
global_sizes
[
1
];
w
=
3
*
local_sizes
[
1
];
if
(
coords
[
1
]
==
dims
[
1
]
-
1
)
{
w
+=
padding
;
}
else
{
padding
=
0
;
}
int
filesize
=
54
+
global_sizes
[
0
]
*
global_w
;
std
::
vector
<
char
>
img
(
local_sizes
[
0
]
*
w
);
std
::
fill
(
img
.
begin
(),
img
.
end
(),
0
);
for
(
int
i
=
0
;
i
<
local_sizes
[
0
];
i
++
)
{
for
(
int
j
=
0
;
j
<
local_sizes
[
1
];
j
++
)
{
float
v
=
((
grid
(
i
+
starts
[
0
],
j
+
starts
[
1
])
-
m_min
)
/
(
m_max
-
m_min
));
float
r
=
v
*
255
;
// Red channel
float
g
=
v
*
255
;
// Green channel
float
b
=
0.f
;
//prank * 255 / psize; // Red channel
r
=
std
::
min
(
r
,
255.f
);
g
=
std
::
min
(
g
,
255.f
);
b
=
std
::
min
(
b
,
255.f
);
img
[
w
*
i
+
3
*
j
+
0
]
=
r
;
img
[
w
*
i
+
3
*
j
+
1
]
=
g
;
img
[
w
*
i
+
3
*
j
+
2
]
=
b
;
}
}
auto
write_bytes
=
[](
auto
&&
array
,
auto
&&
value
)
{
array
[
0
]
=
value
;
array
[
1
]
=
value
>>
8
;
array
[
2
]
=
value
>>
16
;
array
[
3
]
=
value
>>
24
;
};
std
::
array
<
char
,
14
>
bmpfileheader
=
{
'B'
,
'M'
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
54
,
0
,
0
,
0
};
std
::
array
<
char
,
40
>
bmpinfoheader
=
{
40
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
24
,
0
};
write_bytes
(
&
bmpfileheader
[
2
],
filesize
);
write_bytes
(
&
bmpinfoheader
[
4
],
global_sizes
[
1
]);
write_bytes
(
&
bmpinfoheader
[
8
],
global_sizes
[
0
]);
write_bytes
(
&
bmpinfoheader
[
20
],
filesize
-
54
);
#if defined(_MPI)
MPI_File
fh
;
MPI_Status
status
;
MPI_Datatype
subarray_t
;
#if defined(_DEBUG_MPI)
for
(
int
i
=
0
;
i
<
psize
;
++
i
)
{
if
(
prank
==
i
)
std
::
cerr
<<
prank
<<
" ("
<<
coords
[
0
]
<<
", "
<<
coords
[
1
]
<<
")"
<<
" - "
<<
local_sizes
[
0
]
<<
"x"
<<
local_sizes
[
1
]
<<
"("
<<
w
<<
") + "
<<
offset
[
0
]
<<
"x"
<<
offset
[
1
]
<<
"("
<<
3
*
offset
[
1
]
<<
") ++ ["
<<
global_sizes
[
0
]
<<
"x"
<<
global_sizes
[
1
]
<<
"("
<<
global_w
<<
")] "
<<
padding
<<
"
\n
"
;
MPI_Barrier
(
m_communicator
);
}
#endif
global_sizes
[
1
]
=
global_w
;
local_sizes
[
1
]
=
w
;
offset
[
1
]
*=
3
;
MPI_Type_create_subarray
(
global_sizes
.
size
(),
global_sizes
.
data
(),
local_sizes
.
data
(),
offset
.
data
(),
MPI_ORDER_C
,
MPI_CHAR
,
&
subarray_t
);
MPI_Type_commit
(
&
subarray_t
);
// opening a file in write and create mode
MPI_File_open
(
MPI_COMM_WORLD
,
sfilename
.
str
().
c_str
(),
MPI_MODE_WRONLY
|
MPI_MODE_CREATE
,
MPI_INFO_NULL
,
&
fh
);
// defining the size of the file
MPI_File_set_size
(
fh
,
filesize
);
// rank 0 writes the header
if
(
prank
==
0
)
{
MPI_File_write_at
(
fh
,
0
,
bmpfileheader
.
data
(),
14
,
MPI_CHAR
,
&
status
);
MPI_File_write_at
(
fh
,
14
,
bmpinfoheader
.
data
(),
40
,
MPI_CHAR
,
&
status
);
}
if
(
prank
==
0
)
{
std
::
cout
<<
filesize
<<
std
::
endl
;
}
MPI_File_set_view
(
fh
,
54
,
MPI_CHAR
,
subarray_t
,
"native"
,
MPI_INFO_NULL
);
MPI_File_write
(
fh
,
img
.
data
(),
img
.
size
(),
MPI_CHAR
,
&
status
);
MPI_File_close
(
&
fh
);
#endif
}
Event Timeline
Log In to Comment