|
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 |
#include "mpi.h"
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#include "mpitest.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* tests noncontiguous reads/writes using nonblocking collective I/O */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* this test is almost exactly like i_noncontig_coll.c with the following changes:
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* . generalized file writing/reading to handle arbitrary number of processors
|
|
Packit Service |
c5cf8c |
* . provides the "cb_config_list" hint with several permutations of the
|
|
Packit Service |
c5cf8c |
* avaliable processors.
|
|
Packit Service |
c5cf8c |
* [ makes use of code copied from ROMIO's ADIO code to collect the names of
|
|
Packit Service |
c5cf8c |
* the processors ]
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* we are going to muck with this later to make it evenly divisible by however many compute nodes we have */
|
|
Packit Service |
c5cf8c |
#define STARTING_SIZE 5000
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int test_file(char *filename, int mynod, int nprocs, char *cb_hosts, const char *msg, int verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define ADIOI_Free free
|
|
Packit Service |
c5cf8c |
#define ADIOI_Malloc malloc
|
|
Packit Service |
c5cf8c |
#define FPRINTF fprintf
|
|
Packit Service |
c5cf8c |
/* I have no idea what the "D" stands for; it's how things are done in adio.h
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
struct ADIO_cb_name_arrayD {
|
|
Packit Service |
c5cf8c |
int refct;
|
|
Packit Service |
c5cf8c |
int namect;
|
|
Packit Service |
c5cf8c |
char **names;
|
|
Packit Service |
c5cf8c |
};
|
|
Packit Service |
c5cf8c |
typedef struct ADIO_cb_name_arrayD *ADIO_cb_name_array;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void handle_error(int errcode, const char *str);
|
|
Packit Service |
c5cf8c |
int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array * arrayp);
|
|
Packit Service |
c5cf8c |
void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
|
|
Packit Service |
c5cf8c |
void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
|
|
Packit Service |
c5cf8c |
void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
|
|
Packit Service |
c5cf8c |
void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void handle_error(int errcode, const char *str)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char msg[MPI_MAX_ERROR_STRING];
|
|
Packit Service |
c5cf8c |
int resultlen;
|
|
Packit Service |
c5cf8c |
MPI_Error_string(errcode, msg, &resultlen);
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "%s: %s\n", str, msg);
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* cb_gather_name_array() - gather a list of processor names from all processes
|
|
Packit Service |
c5cf8c |
* in a communicator and store them on rank 0.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* This is a collective call on the communicator(s) passed in.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Obtains a rank-ordered list of processor names from the processes in
|
|
Packit Service |
c5cf8c |
* "dupcomm".
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Returns 0 on success, -1 on failure.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* NOTE: Needs some work to cleanly handle out of memory cases!
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array * arrayp)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* this is copied from ROMIO, but since this test is for correctness,
|
|
Packit Service |
c5cf8c |
* not performance, note that we have removed the parts where ROMIO
|
|
Packit Service |
c5cf8c |
* uses a keyval to cache the name array. We'll just rebuild it if we
|
|
Packit Service |
c5cf8c |
* need to */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
char my_procname[MPI_MAX_PROCESSOR_NAME], **procname = 0;
|
|
Packit Service |
c5cf8c |
int *procname_len = NULL, my_procname_len, *disp = NULL, i;
|
|
Packit Service |
c5cf8c |
int commsize, commrank;
|
|
Packit Service |
c5cf8c |
ADIO_cb_name_array array = NULL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(comm, &commsize);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(comm, &commrank);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Get_processor_name(my_procname, &my_procname_len);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* allocate space for everything */
|
|
Packit Service |
c5cf8c |
array = (ADIO_cb_name_array) malloc(sizeof(*array));
|
|
Packit Service |
c5cf8c |
if (array == NULL) {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
array->refct = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (commrank == 0) {
|
|
Packit Service |
c5cf8c |
/* process 0 keeps the real list */
|
|
Packit Service |
c5cf8c |
array->namect = commsize;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
array->names = (char **) ADIOI_Malloc(sizeof(char *) * commsize);
|
|
Packit Service |
c5cf8c |
if (array->names == NULL) {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
procname = array->names; /* simpler to read */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
procname_len = (int *) ADIOI_Malloc(commsize * sizeof(int));
|
|
Packit Service |
c5cf8c |
if (procname_len == NULL) {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* everyone else just keeps an empty list as a placeholder */
|
|
Packit Service |
c5cf8c |
array->namect = 0;
|
|
Packit Service |
c5cf8c |
array->names = NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* gather lengths first */
|
|
Packit Service |
c5cf8c |
MPI_Gather(&my_procname_len, 1, MPI_INT, procname_len, 1, MPI_INT, 0, comm);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (commrank == 0) {
|
|
Packit Service |
c5cf8c |
#ifdef CB_CONFIG_LIST_DEBUG
|
|
Packit Service |
c5cf8c |
for (i = 0; i < commsize; i++) {
|
|
Packit Service |
c5cf8c |
FPRINTF(stderr, "len[%d] = %d\n", i, procname_len[i]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < commsize; i++) {
|
|
Packit Service |
c5cf8c |
/* add one to the lengths because we need to count the
|
|
Packit Service |
c5cf8c |
* terminator, and we are going to use this list of lengths
|
|
Packit Service |
c5cf8c |
* again in the gatherv.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
procname_len[i]++;
|
|
Packit Service |
c5cf8c |
procname[i] = malloc(procname_len[i]);
|
|
Packit Service |
c5cf8c |
if (procname[i] == NULL) {
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* create our list of displacements for the gatherv. we're going
|
|
Packit Service |
c5cf8c |
* to do everything relative to the start of the region allocated
|
|
Packit Service |
c5cf8c |
* for procname[0]
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* I suppose it is theoretically possible that the distance between
|
|
Packit Service |
c5cf8c |
* malloc'd regions could be more than will fit in an int. We don't
|
|
Packit Service |
c5cf8c |
* cover that case.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
disp = malloc(commsize * sizeof(int));
|
|
Packit Service |
c5cf8c |
disp[0] = 0;
|
|
Packit Service |
c5cf8c |
for (i = 1; i < commsize; i++) {
|
|
Packit Service |
c5cf8c |
disp[i] = (int) (procname[i] - procname[0]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* now gather strings */
|
|
Packit Service |
c5cf8c |
if (commrank == 0) {
|
|
Packit Service |
c5cf8c |
MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
|
|
Packit Service |
c5cf8c |
procname[0], procname_len, disp, MPI_CHAR, 0, comm);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* if we didn't do this, we would need to allocate procname[]
|
|
Packit Service |
c5cf8c |
* on all processes...which seems a little silly.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR,
|
|
Packit Service |
c5cf8c |
NULL, NULL, NULL, MPI_CHAR, 0, comm);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (commrank == 0) {
|
|
Packit Service |
c5cf8c |
/* no longer need the displacements or lengths */
|
|
Packit Service |
c5cf8c |
free(disp);
|
|
Packit Service |
c5cf8c |
free(procname_len);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef CB_CONFIG_LIST_DEBUG
|
|
Packit Service |
c5cf8c |
for (i = 0; i < commsize; i++) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "name[%d] = %s\n", i, procname[i]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*arrayp = array;
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *ptr;
|
|
Packit Service |
c5cf8c |
int i, p;
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
ptr = dest;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < array->namect; i++) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* chop off that last comma */
|
|
Packit Service |
c5cf8c |
dest[strlen(dest) - 1] = '\0';
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *ptr;
|
|
Packit Service |
c5cf8c |
int i, p;
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
ptr = dest;
|
|
Packit Service |
c5cf8c |
for (i = (array->namect - 1); i >= 0; i--) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
dest[strlen(dest) - 1] = '\0';
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *ptr;
|
|
Packit Service |
c5cf8c |
int i, p;
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
ptr = dest;
|
|
Packit Service |
c5cf8c |
/* evens */
|
|
Packit Service |
c5cf8c |
for (i = (array->namect - 1); i >= 0; i -= 2) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* odds */
|
|
Packit Service |
c5cf8c |
for (i = (array->namect - 2); i > 0; i -= 2) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
dest[strlen(dest) - 1] = '\0';
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *ptr;
|
|
Packit Service |
c5cf8c |
int i, p;
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
ptr = dest;
|
|
Packit Service |
c5cf8c |
for (i = (array->namect / 2); i < array->namect; i++) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (i = 0; i < (array->namect / 2); i++) {
|
|
Packit Service |
c5cf8c |
p = snprintf(ptr, len, "%s,", array->names[i]);
|
|
Packit Service |
c5cf8c |
ptr += p;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
dest[strlen(dest) - 1] = '\0';
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int main(int argc, char **argv)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, mynod, nprocs, len, errs = 0, sum_errs = 0, verbose = 0;
|
|
Packit Service |
c5cf8c |
char *filename;
|
|
Packit Service |
c5cf8c |
char *cb_config_string;
|
|
Packit Service |
c5cf8c |
int cb_config_len;
|
|
Packit Service |
c5cf8c |
ADIO_cb_name_array array;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MTest_Init(&argc, &argv);
|
|
Packit Service |
c5cf8c |
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
|
|
Packit Service |
c5cf8c |
MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* process 0 takes the file name as a command-line argument and
|
|
Packit Service |
c5cf8c |
* broadcasts it to other processes */
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
filename = "testfile";
|
|
Packit Service |
c5cf8c |
len = strlen(filename);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
filename = (char *) malloc(len + 1);
|
|
Packit Service |
c5cf8c |
MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* want to hint the cb_config_list, but do so in a non-sequential way */
|
|
Packit Service |
c5cf8c |
cb_gather_name_array(MPI_COMM_WORLD, &array);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* sanity check */
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
if (array->namect < 2) {
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Run this test on two or more hosts\n");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* get space for the permuted cb_config_string */
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
cb_config_len = 0;
|
|
Packit Service |
c5cf8c |
for (i = 0; i < array->namect; i++) {
|
|
Packit Service |
c5cf8c |
/* +1: space for either a , or \0 if last */
|
|
Packit Service |
c5cf8c |
cb_config_len += strlen(array->names[i]) + 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
++cb_config_len;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Bcast(&cb_config_len, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
if ((cb_config_string = malloc(cb_config_len)) == NULL) {
|
|
Packit Service |
c5cf8c |
perror("malloc");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, 1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* first, no hinting */
|
|
Packit Service |
c5cf8c |
errs += test_file(filename, mynod, nprocs, NULL, "collective w/o hinting", verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* hint, but no change in order */
|
|
Packit Service |
c5cf8c |
default_str(mynod, cb_config_len, array, cb_config_string);
|
|
Packit Service |
c5cf8c |
errs += test_file(filename, mynod, nprocs, cb_config_string,
|
|
Packit Service |
c5cf8c |
"collective w/ hinting: default order", verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* reverse order */
|
|
Packit Service |
c5cf8c |
reverse_str(mynod, cb_config_len, array, cb_config_string);
|
|
Packit Service |
c5cf8c |
errs += test_file(filename, mynod, nprocs, cb_config_string,
|
|
Packit Service |
c5cf8c |
"collective w/ hinting: reverse order", verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* reverse, every other */
|
|
Packit Service |
c5cf8c |
reverse_alternating_str(mynod, cb_config_len, array, cb_config_string);
|
|
Packit Service |
c5cf8c |
errs += test_file(filename, mynod, nprocs, cb_config_string,
|
|
Packit Service |
c5cf8c |
"collective w/ hinting: permutation1", verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* second half, first half */
|
|
Packit Service |
c5cf8c |
simple_shuffle_str(mynod, cb_config_len, array, cb_config_string);
|
|
Packit Service |
c5cf8c |
errs += test_file(filename, mynod, nprocs, cb_config_string,
|
|
Packit Service |
c5cf8c |
"collective w/ hinting: permutation2", verbose);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mynod)
|
|
Packit Service |
c5cf8c |
free(filename);
|
|
Packit Service |
c5cf8c |
free(cb_config_string);
|
|
Packit Service |
c5cf8c |
MTest_Finalize(errs);
|
|
Packit Service |
c5cf8c |
return MTestReturnValue(errs);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define SEEDER(x,y,z) ((x)*1000000 + (y) + (x)*(z))
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int test_file(char *filename, int mynod, int nprocs, char *cb_hosts, const char *msg, int verbose)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPI_Datatype typevec, newtype, t[3];
|
|
Packit Service |
c5cf8c |
int *buf, i, b[3], errcode, errors = 0;
|
|
Packit Service |
c5cf8c |
MPI_File fh;
|
|
Packit Service |
c5cf8c |
MPI_Aint d[3];
|
|
Packit Service |
c5cf8c |
MPI_Request request;
|
|
Packit Service |
c5cf8c |
MPI_Status status;
|
|
Packit Service |
c5cf8c |
int SIZE = (STARTING_SIZE / nprocs) * nprocs;
|
|
Packit Service |
c5cf8c |
MPI_Info info;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (mynod == 0 && verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "%s\n", msg);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
buf = (int *) malloc(SIZE * sizeof(int));
|
|
Packit Service |
c5cf8c |
if (buf == NULL) {
|
|
Packit Service |
c5cf8c |
perror("test_file");
|
|
Packit Service |
c5cf8c |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (cb_hosts != NULL) {
|
|
Packit Service |
c5cf8c |
MPI_Info_create(&info;;
|
|
Packit Service |
c5cf8c |
MPI_Info_set(info, "cb_config_list", cb_hosts);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
info = MPI_INFO_NULL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Type_vector(SIZE / nprocs, 1, nprocs, MPI_INT, &typevec);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
b[0] = b[1] = b[2] = 1;
|
|
Packit Service |
c5cf8c |
d[0] = 0;
|
|
Packit Service |
c5cf8c |
d[1] = mynod * sizeof(int);
|
|
Packit Service |
c5cf8c |
d[2] = SIZE * sizeof(int);
|
|
Packit Service |
c5cf8c |
t[0] = MPI_LB;
|
|
Packit Service |
c5cf8c |
t[1] = typevec;
|
|
Packit Service |
c5cf8c |
t[2] = MPI_UB;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Type_struct(3, b, d, t, &newtype);
|
|
Packit Service |
c5cf8c |
MPI_Type_commit(&newtype);
|
|
Packit Service |
c5cf8c |
MPI_Type_free(&typevec);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous "
|
|
Packit Service |
c5cf8c |
"in file using collective I/O\n");
|
|
Packit Service |
c5cf8c |
MPI_File_delete(filename, info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh;;
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "MPI_File_open");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "MPI_File_set_view");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = SEEDER(mynod, i, SIZE);
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iwrite_all(fh, buf, 1, newtype, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "nc mem - nc file: MPI_File_iwrite_all");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iread_at_all(fh, 0, buf, 1, newtype, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "nc mem - nc file: MPI_File_iread_at_all");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* the verification for N compute nodes is tricky. Say we have 3
|
|
Packit Service |
c5cf8c |
* processors.
|
|
Packit Service |
c5cf8c |
* process 0 sees: 0 -1 -1 3 -1 -1 ...
|
|
Packit Service |
c5cf8c |
* process 1 sees: -1 34 -1 -1 37 -1 ...
|
|
Packit Service |
c5cf8c |
* process 2 sees: -1 -1 68 -1 -1 71 ... */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* verify those leading -1s exist if they should */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < mynod; i++) {
|
|
Packit Service |
c5cf8c |
if (buf[i] != -1) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* now the modulo games are hairy. processor 0 sees real data in the 0th,
|
|
Packit Service |
c5cf8c |
* 3rd, 6th... elements of the buffer (assuming nprocs==3). proc 1 sees
|
|
Packit Service |
c5cf8c |
* the data in 1st, 4th, 7th..., and proc 2 sees it in 2nd, 5th, 8th */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (/* 'i' set in above loop */ ; i < SIZE; i++) {
|
|
Packit Service |
c5cf8c |
if (((i - mynod) % nprocs) && buf[i] != -1) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (!((i - mynod) % nprocs) && buf[i] != SEEDER(mynod, i, SIZE)) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
|
|
Packit Service |
c5cf8c |
mynod, i, buf[i], SEEDER(mynod, i, SIZE));
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in "
|
|
Packit Service |
c5cf8c |
"file using collective I/O\n");
|
|
Packit Service |
c5cf8c |
MPI_File_delete(filename, info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = SEEDER(mynod, i, SIZE);
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iwrite_at_all(fh, mynod * (SIZE / nprocs) * sizeof(int),
|
|
Packit Service |
c5cf8c |
buf, 1, newtype, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS)
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "nc mem - c file: MPI_File_iwrite_at_all");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iread_at_all(fh, mynod * (SIZE / nprocs) * sizeof(int),
|
|
Packit Service |
c5cf8c |
buf, 1, newtype, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS)
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "nc mem - c file: MPI_File_iread_at_all");
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* just like as above */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < mynod; i++) {
|
|
Packit Service |
c5cf8c |
if (buf[i] != -1) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (/* i set in above loop */ ; i < SIZE; i++) {
|
|
Packit Service |
c5cf8c |
if (((i - mynod) % nprocs) && buf[i] != -1) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (!((i - mynod) % nprocs) && buf[i] != SEEDER(mynod, i, SIZE)) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
|
|
Packit Service |
c5cf8c |
mynod, i, buf[i], SEEDER(mynod, i, SIZE));
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!mynod) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in "
|
|
Packit Service |
c5cf8c |
"file using collective I/O\n");
|
|
Packit Service |
c5cf8c |
MPI_File_delete(filename, info);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "MPI_File_set_view");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = SEEDER(mynod, i, SIZE);
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iwrite_all(fh, buf, SIZE, MPI_INT, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS)
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "c mem - nc file: MPI_File_iwrite_all");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Barrier(MPI_COMM_WORLD);
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++)
|
|
Packit Service |
c5cf8c |
buf[i] = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
errcode = MPI_File_iread_at_all(fh, 0, buf, SIZE, MPI_INT, &request);
|
|
Packit Service |
c5cf8c |
if (errcode != MPI_SUCCESS)
|
|
Packit Service |
c5cf8c |
handle_error(errcode, "c mem - nc file: MPI_File_iread_at_all");
|
|
Packit Service |
c5cf8c |
MPI_Wait(&request, &status);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* same crazy checking */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < SIZE; i++) {
|
|
Packit Service |
c5cf8c |
if (buf[i] != SEEDER(mynod, i, SIZE)) {
|
|
Packit Service |
c5cf8c |
if (verbose)
|
|
Packit Service |
c5cf8c |
fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
|
|
Packit Service |
c5cf8c |
mynod, i, buf[i], SEEDER(mynod, i, SIZE));
|
|
Packit Service |
c5cf8c |
errors++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_File_close(&fh;;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPI_Type_free(&newtype);
|
|
Packit Service |
c5cf8c |
free(buf);
|
|
Packit Service |
c5cf8c |
if (info != MPI_INFO_NULL)
|
|
Packit Service |
c5cf8c |
MPI_Info_free(&info;;
|
|
Packit Service |
c5cf8c |
return errors;
|
|
Packit Service |
c5cf8c |
}
|