|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2014 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Wei-keng Liao (wkliao@ece.northwestern.edu) September 8, 2008 */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Uses nonblocking collective I/O.*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include <mpi.h>
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define YLEN 5
|
|
Packit Service |
c5cf8c |
#define XLEN 10
|
|
Packit Service |
c5cf8c |
#define SUB_XLEN 3
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* rjl: I was just too lazy to compute this at run-time */
|
|
Packit Service |
c5cf8c |
char compare_buf[XLEN * 4][YLEN * 4] = {
|
|
Packit Service |
c5cf8c |
{'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
Packit Service |
c5cf8c |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* set this if you want a dump of the global array
|
|
Packit Service |
c5cf8c |
#define VERBOSE 1
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define HANDLE_ERROR(err) \
|
|
Packit Service |
c5cf8c |
if (err != MPI_SUCCESS) { \
|
|
Packit Service |
c5cf8c |
char msg[MPI_MAX_ERROR_STRING]; \
|
|
Packit Service |
c5cf8c |
int resultlen; \
|
|
Packit Service |
c5cf8c |
MPI_Error_string(err, msg, &resultlen); \
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "%s line %d: %s\n", __FILE__, __LINE__, msg); \
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1); \
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*----< main() >------------------------------------------------------------*/
|
|
Packit Service |
c5cf8c |
int main(int argc, char **argv)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, j, err, rank, np, num_io;
|
|
Packit Service |
c5cf8c |
char *buf, *filename;
|
|
Packit Service |
c5cf8c |
int rank_dim[2], array_of_sizes[2];
|
|
Packit Service |
c5cf8c |
int array_of_subsizes[2];
|
|
Packit Service |
c5cf8c |
int count, *blocklengths, global_array_size;
|
|
Packit Service |
c5cf8c |
MPI_Count ftype_size;
|
|
Packit Service |
c5cf8c |
MPI_Aint *displacements;
|
|
Packit Service |
c5cf8c |
MPI_File fh;
|
|
Packit Service |
c5cf8c |
MPI_Datatype ftype;
|
|
Packit Service |
c5cf8c |
MPI_Request *request;
|
|
Packit Service |
c5cf8c |
MPI_Status *statuses;
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
MPI_Offset offset = 0;
|
|
Packit Service |
c5cf8c |
int errs = 0;
|
|
Packit Service |
c5cf8c |
#ifdef VERBOSE
|
|
Packit Service |
c5cf8c |
int k;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &np);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (np != 4) {
|
|
Packit Service |
c5cf8c |
if (!rank)
|
|
Packit Service |
c5cf8c |
printf("Please run with 4 processes. Exiting ...\n\n");
|
|
Packit Service |
c5cf8c |
return 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
filename = (argc > 1) ? argv[1] : "testfile";
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
num_io = 2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
request = (MPI_Request *) malloc(num_io * sizeof(MPI_Request));
|
|
Packit Service |
c5cf8c |
statuses = (MPI_Status *) malloc(num_io * sizeof(MPI_Status));
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*-----------------------------------------------------------------------*/
|
|
Packit Service |
c5cf8c |
/* process rank in each dimension */
|
|
Packit Service |
c5cf8c |
rank_dim[0] = rank / 2;
|
|
Packit Service |
c5cf8c |
rank_dim[1] = rank % 2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* global 2D array size */
|
|
Packit Service |
c5cf8c |
array_of_sizes[0] = YLEN * 2;
|
|
Packit Service |
c5cf8c |
array_of_sizes[1] = XLEN * 2;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
global_array_size = array_of_sizes[0] * array_of_sizes[1];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
array_of_subsizes[0] = YLEN / 2;
|
|
Packit Service |
c5cf8c |
array_of_subsizes[1] = XLEN * SUB_XLEN / 5;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
offset = rank_dim[0] * YLEN * array_of_sizes[1] + rank_dim[1] * XLEN;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* define data type for file view */
|
|
Packit Service |
c5cf8c |
count = array_of_subsizes[0] * 2; /* 2 is the no. blocks along X */
|
|
Packit Service |
c5cf8c |
blocklengths = (int *) malloc(count * sizeof(int));
|
|
Packit Service |
c5cf8c |
displacements = (MPI_Aint *) malloc(count * sizeof(MPI_Aint));
|
|
Packit Service |
c5cf8c |
for (i = 0; i < count; i++)
|
|
Packit Service |
c5cf8c |
blocklengths[i] = array_of_subsizes[1] / 2;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < array_of_subsizes[0]; i++)
|
|
Packit Service |
c5cf8c |
for (j = 0; j < 2; j++)
|
|
Packit Service |
c5cf8c |
displacements[i * 2 + j] = offset + i * 2 * array_of_sizes[1]
|
|
Packit Service |
c5cf8c |
+ j * XLEN / 2;
|
|
Packit Service |
c5cf8c |
MPI_Type_create_hindexed(count, blocklengths, displacements, MPI_CHAR, &ftype);
|
|
Packit Service |
c5cf8c |
MPI_Type_commit(&ftype);
|
|
Packit Service |
c5cf8c |
MPI_Type_size_x(ftype, &ftype_size);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* subarray's layout in the global array
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
P0's 's layout P1's layout
|
|
Packit Service |
c5cf8c |
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
|
|
Packit Service |
c5cf8c |
[ 0] 0 1 2 3 4 5 | D E F G H I
|
|
Packit Service |
c5cf8c |
[ 1] |
|
|
Packit Service |
c5cf8c |
[ 2] 6 7 8 9 : ; | J K L M N O
|
|
Packit Service |
c5cf8c |
[ 3] |
|
|
Packit Service |
c5cf8c |
[ 4] |
|
|
Packit Service |
c5cf8c |
[ 5] |
|
|
Packit Service |
c5cf8c |
[ 6] |
|
|
Packit Service |
c5cf8c |
[ 7] |
|
|
Packit Service |
c5cf8c |
[ 8] |
|
|
Packit Service |
c5cf8c |
[ 9] |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
P2's 's layout P3's layout
|
|
Packit Service |
c5cf8c |
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
|
|
Packit Service |
c5cf8c |
[ 0] |
|
|
Packit Service |
c5cf8c |
[ 1] |
|
|
Packit Service |
c5cf8c |
[ 2] |
|
|
Packit Service |
c5cf8c |
[ 3] |
|
|
Packit Service |
c5cf8c |
[ 4] |
|
|
Packit Service |
c5cf8c |
[ 5] X Y Z [ \ ] | l m n o p q
|
|
Packit Service |
c5cf8c |
[ 6] |
|
|
Packit Service |
c5cf8c |
[ 7] ^ _ ` a b c | r s t u v w
|
|
Packit Service |
c5cf8c |
[ 8] |
|
|
Packit Service |
c5cf8c |
[ 9] |
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* initialize the write buffer */
|
|
Packit Service |
c5cf8c |
buf = (char *) malloc(array_of_subsizes[0] * array_of_subsizes[1]);
|
|
Packit Service |
c5cf8c |
for (i = 0; i < array_of_subsizes[0] * array_of_subsizes[1]; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = '0' + rank * 20 + i % 79;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* zero file contents --------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
if (rank == 0) {
|
|
Packit Service |
c5cf8c |
char *wr_buf = (char *) calloc(num_io * global_array_size, 1);
|
|
Packit Service |
c5cf8c |
err = MPI_File_open(MPI_COMM_SELF, filename,
|
|
Packit Service |
c5cf8c |
MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh;;
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_write(fh, wr_buf, num_io * global_array_size, MPI_CHAR, &status);
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
free(wr_buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* open the file -------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
err = MPI_File_open(MPI_COMM_WORLD, filename,
|
|
Packit Service |
c5cf8c |
MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh;;
|
|
Packit Service |
c5cf8c |
if (err != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
printf("Error: MPI_File_open() filename %s\n", filename);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
exit(1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* MPI nonblocking collective write */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < num_io; i++) {
|
|
Packit Service |
c5cf8c |
offset = i * global_array_size;
|
|
Packit Service |
c5cf8c |
/* set the file view */
|
|
Packit Service |
c5cf8c |
err = MPI_File_set_view(fh, offset, MPI_BYTE, ftype, "native", MPI_INFO_NULL);
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_iwrite_all(fh, buf, ftype_size, MPI_CHAR, &request[i]);
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
err = MPI_Waitall(num_io, request, statuses);
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* read and print file contents ----------------------------------------- */
|
|
Packit Service |
c5cf8c |
if (rank == 0) {
|
|
Packit Service |
c5cf8c |
char *ptr;
|
|
Packit Service |
c5cf8c |
char *rd_buf = (char *) calloc(num_io * global_array_size, 1);
|
|
Packit Service |
c5cf8c |
err = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh;;
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_read(fh, rd_buf, num_io * global_array_size, MPI_CHAR, &status);
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
err = MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
HANDLE_ERROR(err);
|
|
Packit Service |
c5cf8c |
#ifdef VERBOSE
|
|
Packit Service |
c5cf8c |
printf("-------------------------------------------------------\n");
|
|
Packit Service |
c5cf8c |
printf(" [");
|
|
Packit Service |
c5cf8c |
for (i = 0; i < 2; i++) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < XLEN; j++)
|
|
Packit Service |
c5cf8c |
printf(" %d", j);
|
|
Packit Service |
c5cf8c |
printf(" ");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("]\n\n");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
ptr = rd_buf;
|
|
Packit Service |
c5cf8c |
for (k = 0; k < num_io; k++) {
|
|
Packit Service |
c5cf8c |
for (i = 0; i < 2 * YLEN; i++) {
|
|
Packit Service |
c5cf8c |
printf("[%2d]", k * 2 * YLEN + i);
|
|
Packit Service |
c5cf8c |
for (j = 0; j < 2 * XLEN; j++) {
|
|
Packit Service |
c5cf8c |
if (j > 0 && j % XLEN == 0)
|
|
Packit Service |
c5cf8c |
printf(" ");
|
|
Packit Service |
c5cf8c |
if (*ptr != 0)
|
|
Packit Service |
c5cf8c |
printf(" %c", *ptr);
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
printf(" ");
|
|
Packit Service |
c5cf8c |
ptr++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
printf("\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
ptr = rd_buf;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < 2 * YLEN * num_io; i++) {
|
|
Packit Service |
c5cf8c |
for (j = 0; j < 2 * XLEN; j++) {
|
|
Packit Service |
c5cf8c |
if (*ptr != compare_buf[i][j]) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "expected %d got %d at [%d][%d]\n",
|
|
Packit Service |
c5cf8c |
*ptr, compare_buf[i][j], i, j);
|
|
Packit Service |
c5cf8c |
errs++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
ptr++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
free(rd_buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
free(blocklengths);
|
|
Packit Service |
c5cf8c |
free(displacements);
|
|
Packit Service |
c5cf8c |
free(buf);
|
|
Packit Service |
c5cf8c |
free(request);
|
|
Packit Service |
c5cf8c |
free(statuses);
|
|
Packit Service |
c5cf8c |
MPI_Type_free(&ftype);
|
|
Packit Service |
c5cf8c |
MTest_Finalize(errs);
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* command-line outputs are: (the global array is written twice)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
% mpiexec -n 4 wkl_subarray
|
|
Packit Service |
c5cf8c |
-------------------------------------------------------
|
|
Packit Service |
c5cf8c |
[ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ]
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
[ 0] 0 1 2 3 4 5 D E F G H I
|
|
Packit Service |
c5cf8c |
[ 1]
|
|
Packit Service |
c5cf8c |
[ 2] 6 7 8 9 : ; J K L M N O
|
|
Packit Service |
c5cf8c |
[ 3]
|
|
Packit Service |
c5cf8c |
[ 4]
|
|
Packit Service |
c5cf8c |
[ 5] X Y Z [ \ ] l m n o p q
|
|
Packit Service |
c5cf8c |
[ 6]
|
|
Packit Service |
c5cf8c |
[ 7] ^ _ ` a b c r s t u v w
|
|
Packit Service |
c5cf8c |
[ 8]
|
|
Packit Service |
c5cf8c |
[ 9]
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
[10] 0 1 2 3 4 5 D E F G H I
|
|
Packit Service |
c5cf8c |
[11]
|
|
Packit Service |
c5cf8c |
[12] 6 7 8 9 : ; J K L M N O
|
|
Packit Service |
c5cf8c |
[13]
|
|
Packit Service |
c5cf8c |
[14]
|
|
Packit Service |
c5cf8c |
[15] X Y Z [ \ ] l m n o p q
|
|
Packit Service |
c5cf8c |
[16]
|
|
Packit Service |
c5cf8c |
[17] ^ _ ` a b c r s t u v w
|
|
Packit Service |
c5cf8c |
[18]
|
|
Packit Service |
c5cf8c |
[19]
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*/
|