예제 #1
0
/* Run tests for darray functions. */
int main(int argc, char **argv)
{
    int my_rank;
    int ntasks;
    int num_flavors; /* Number of PIO netCDF flavors in this build. */
    int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */
    MPI_Comm test_comm; /* A communicator for this test. */
    int ret;         /* Return code. */

    /* Initialize test. */
    if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, MIN_NTASKS,
                              MIN_NTASKS, -1, &test_comm)))
        ERR(ERR_INIT);

    if ((ret = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_RETURN_ERROR, NULL)))
        return ret;

    /* Only do something on max_ntasks tasks. */
    if (my_rank < TARGET_NTASKS)
    {
        int rearranger[NUM_REARRANGERS_TO_TEST] = {PIO_REARR_BOX, PIO_REARR_SUBSET};
        int iosysid;  /* The ID for the parallel I/O system. */
        int ioproc_stride = 1;    /* Stride in the mpi rank between io tasks. */
        int ioproc_start = 0;     /* Zero based rank of first processor to be used for I/O. */
        int ret;      /* Return code. */

        /* Figure out iotypes. */
        if ((ret = get_iotypes(&num_flavors, flavor)))
            ERR(ret);

        for (int r = 0; r < NUM_REARRANGERS_TO_TEST; r++)
        {
            /* Initialize the PIO IO system. This specifies how
             * many and which processors are involved in I/O. */
            if ((ret = PIOc_Init_Intracomm(test_comm, TARGET_NTASKS, ioproc_stride,
                                           ioproc_start, rearranger[r], &iosysid)))
                return ret;

            /* Run tests. */
            if ((ret = test_all_darray(iosysid, num_flavors, flavor, my_rank,
                                       rearranger[r], test_comm)))
                return ret;

            /* Finalize PIO system. */
            if ((ret = PIOc_finalize(iosysid)))
                return ret;

        } /* next rearranger */
    } /* endif my_rank < TARGET_NTASKS */

    /* Finalize the MPI library. */
    if ((ret = pio_test_finalize(&test_comm)))
        return ret;

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);
    return 0;
}
예제 #2
0
/* Run Tests for Init_Intercomm. */
int main(int argc, char **argv)
{
    /* Zero-based rank of processor. */
    int my_rank;

    /* Number of processors involved in current execution. */
    int ntasks;

    int num_flavors; /* Number of PIO netCDF flavors in this build. */
    int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */

    /* Names for the output files. */
    char filename[NUM_FLAVORS][NC_MAX_NAME + 1];

    /* The ID for the parallel I/O system. */
    int iosysid[COMPONENT_COUNT];

    /* Return code. */
    int ret;

    MPI_Comm test_comm;

    char too_long_name[PIO_MAX_NAME * 5 + 1];

    /* Create a name that is too long. */
    memset(too_long_name, 74, PIO_MAX_NAME * 5);
    too_long_name[PIO_MAX_NAME * 5] = 0;

    /* Set up test. */
    if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, TARGET_NTASKS, TARGET_NTASKS,
                              -1, &test_comm)))
        ERR(ERR_INIT);

    /* Figure out iotypes. */
    if ((ret = get_iotypes(&num_flavors, flavor)))
        ERR(ret);

    if (my_rank < TARGET_NTASKS)
    {

        /* How many processors will be used for our IO and 2 computation components. */
        int num_procs[COMPONENT_COUNT] = {2};

        /* Is the current process a computation task? */
        int comp_task = my_rank < 2 ? 0 : 1;

        /* Index of computation task in iosysid array. Varies by rank and
         * does not apply to IO component processes. */
        int my_comp_idx = comp_task ? 0 : -1;

        /* Initialize the IO system. */
        if ((ret = PIOc_init_async(test_comm, NUM_IO_PROCS, NULL, COMPONENT_COUNT,
                                   num_procs, NULL, NULL, NULL, PIO_REARR_BOX, iosysid)))
            ERR(ERR_AWFUL);

        /* All the netCDF calls are only executed on the computation
         * tasks. The IO tasks have not returned from PIOc_Init_Intercomm,
         * and when the do, they should go straight to finalize. */
        if (comp_task)
        {
            for (int fmt = 0; fmt < num_flavors; fmt++)
            {
                int ncid, varid, dimid;
                PIO_Offset start[NDIM], count[NDIM] = {0};
                int data[DIM_LEN];

                /* Create the filename for this flavor. */
                sprintf(filename[fmt], "test_intercomm2_%d.nc", flavor[fmt]);

                /* Create a netCDF file with one dimension and one variable. */
                if ((ret = PIOc_createfile(iosysid[my_comp_idx], &ncid, &flavor[fmt], filename[fmt],
                                           NC_CLOBBER)))
                    ERR(ret);

                /* End define mode, then re-enter it. */
                if ((ret = PIOc_enddef(ncid)))
                    ERR(ret);
                if ((ret = PIOc_redef(ncid)))
                    ERR(ret);

                /* Test the inq_format function. */
                int myformat;
                if (PIOc_inq_format(ncid + TEST_VAL_42, &myformat) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if ((ret = PIOc_inq_format(ncid, &myformat)))
                    ERR(ret);
                if ((flavor[fmt] == PIO_IOTYPE_PNETCDF || flavor[fmt] == PIO_IOTYPE_NETCDF) &&
                    myformat != 1)
                    ERR(ERR_AWFUL);
                else if ((flavor[fmt] == PIO_IOTYPE_NETCDF4C || flavor[fmt] == PIO_IOTYPE_NETCDF4P) &&
                         myformat != 3)
                    ERR(ERR_AWFUL);

                /* Test the inq_type function for atomic types. */
                char type_name[NC_MAX_NAME + 1];
                PIO_Offset type_size;
                nc_type xtype[NUM_TYPES] = {NC_CHAR, NC_BYTE, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE,
                                            NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
                int type_len[NUM_TYPES] = {1, 1, 2, 4, 4, 8, 1, 2, 4, 8, 8};
                int max_type = flavor[fmt] == PIO_IOTYPE_NETCDF ? NC_DOUBLE : NC_UINT64;

                /* This should not work. */
                if (PIOc_inq_type(ncid + TEST_VAL_42, xtype[0], type_name, &type_size) != PIO_EBADID)
                    ERR(ERR_WRONG);

                /* These should work. */
                for (int i = 0; i < max_type; i++)
                {
                    if ((ret = PIOc_inq_type(ncid, xtype[i], type_name, &type_size)))
                        ERR(ret);
                    if (type_size != type_len[i])
                        ERR(ERR_AWFUL);
                }

                /* Define a dimension. */
                char dimname2[NC_MAX_NAME + 1];
                if ((ret = PIOc_def_dim(ncid, FIRST_DIM_NAME, DIM_LEN, &dimid)))
                    ERR(ret);
                if ((ret = PIOc_inq_dimname(ncid, 0, dimname2)))
                    ERR(ret);
                if (strcmp(dimname2, FIRST_DIM_NAME))
                    ERR(ERR_WRONG);
                if ((ret = PIOc_rename_dim(ncid, 0, DIM_NAME)))
                    ERR(ret);

                /* These should not work. */
                if (PIOc_rename_dim(ncid + TEST_VAL_42, 0, DIM_NAME) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_rename_dim(ncid, 0, NULL) != PIO_EINVAL)
                    ERR(ERR_WRONG);
                if (PIOc_rename_dim(ncid, 0, too_long_name) != PIO_EINVAL)
                    ERR(ERR_WRONG);

                /* Define a 1-D variable. */
                char varname2[NC_MAX_NAME + 1];
                if ((ret = PIOc_def_var(ncid, FIRST_VAR_NAME, NC_INT, NDIM, &dimid, &varid)))
                    ERR(ret);
                if ((ret = PIOc_inq_varname(ncid, 0, varname2)))
                    ERR(ret);
                if (strcmp(varname2, FIRST_VAR_NAME))
                    ERR(ERR_WRONG);
                if ((ret = PIOc_rename_var(ncid, 0, VAR_NAME)))
                    ERR(ret);

                /* These should not work. */
                if (PIOc_rename_var(ncid + TEST_VAL_42, 0, VAR_NAME) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_rename_var(ncid, 0, NULL) != PIO_EINVAL)
                    ERR(ERR_WRONG);
                if (PIOc_rename_var(ncid, 0, too_long_name) != PIO_EINVAL)
                    ERR(ERR_WRONG);

                /* Add a global attribute. */
                int att_data = ATT_VALUE;
                short short_att_data = ATT_VALUE;
                float float_att_data = ATT_VALUE;
                double double_att_data = ATT_VALUE;
                char attname2[NC_MAX_NAME + 1];

                /* Write an att and rename it. */
                if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, FIRST_ATT_NAME, NC_INT, 1, &att_data)))
                    ERR(ret);
                if ((ret = PIOc_inq_attname(ncid, NC_GLOBAL, 0, attname2)))
                    ERR(ret);
                if (strcmp(attname2, FIRST_ATT_NAME))
                    ERR(ERR_WRONG);
                if ((ret = PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, ATT_NAME)))
                    ERR(ret);

                /* These should not work. */
                if (PIOc_inq_attname(ncid + TEST_VAL_42, NC_GLOBAL, 0, attname2) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_rename_att(ncid + TEST_VAL_42, NC_GLOBAL, FIRST_ATT_NAME, ATT_NAME) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, NULL) != PIO_EINVAL)
                    ERR(ERR_WRONG);
                if (PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, too_long_name) != PIO_EINVAL)
                    ERR(ERR_WRONG);
                if (PIOc_del_att(ncid + TEST_VAL_42, NC_GLOBAL, FIRST_ATT_NAME) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_del_att(ncid, NC_GLOBAL, NULL) != PIO_EINVAL)
                    ERR(ERR_WRONG);
                if (PIOc_del_att(ncid, NC_GLOBAL, too_long_name) != PIO_EINVAL)
                    ERR(ERR_WRONG);

                /* Write an att and delete it. */
                if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, FIRST_ATT_NAME, NC_INT, 1, &att_data)))
                    ERR(ret);
                if ((ret = PIOc_del_att(ncid, NC_GLOBAL, FIRST_ATT_NAME)))
                    ERR(ret);
                /* if ((ret = PIOc_inq_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, NULL, NULL)) != PIO_ENOTATT) */
                /* { */
                /*      printf("ret = %d\n", ret); */
                /*      ERR(ERR_AWFUL); */
                /* } */

                /* Write some atts of different types. */
                if ((ret = PIOc_put_att_short(ncid, NC_GLOBAL, SHORT_ATT_NAME, NC_SHORT, 1, &short_att_data)))
                    ERR(ret);
                if ((ret = PIOc_put_att_float(ncid, NC_GLOBAL, FLOAT_ATT_NAME, NC_FLOAT, 1, &float_att_data)))
                    ERR(ret);
                if ((ret = PIOc_put_att_double(ncid, NC_GLOBAL, DOUBLE_ATT_NAME, NC_DOUBLE, 1, &double_att_data)))
                    ERR(ret);

                /* Check some att types. */
                nc_type myatttype;
                if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, SHORT_ATT_NAME, &myatttype)))
                    ERR(ret);
                if (myatttype != NC_SHORT)
                    ERR(ERR_WRONG);
                if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, FLOAT_ATT_NAME, &myatttype)))
                    ERR(ret);
                if (myatttype != NC_FLOAT)
                    ERR(ERR_WRONG);
                if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, DOUBLE_ATT_NAME, &myatttype)))
                    ERR(ret);
                if (myatttype != NC_DOUBLE)
                    ERR(ERR_WRONG);

                /* End define mode. */
                if ((ret = PIOc_enddef(ncid)))
                    ERR(ret);

                /* Write some data. For the PIOc_put/get functions, all
                 * data must be on compmaster before the function is
                 * called. Only compmaster's arguments are passed to the
                 * async msg handler. All other computation tasks are
                 * ignored. */
                for (int i = 0; i < DIM_LEN; i++)
                    data[i] = i;
                start[0] = 0;
                count[0] = DIM_LEN;
                if ((ret = PIOc_put_vars_tc(ncid, varid, start, count, NULL, NC_INT, data)))
                    ERR(ret);

                /* Close the file. */
                if ((ret = PIOc_closefile(ncid)))
                    ERR(ret);

                /* Check the file for correctness. */
                if ((ret = check_file(iosysid[my_comp_idx], flavor[fmt], filename[fmt], my_rank)))
                    ERR(ret);

                /* Now delete the file. */
                /* if ((ret = PIOc_deletefile(iosysid, filename[fmt]))) */
                /*      ERR(ret); */
                /* if ((ret = PIOc_openfile(iosysid, &ncid, &flavor[fmt], filename[fmt], */
                /*                           NC_NOWRITE)) != PIO_ENFILE) */
                /*      ERR(ERR_AWFUL); */

            } /* next netcdf flavor */

            /* Finalize the IO system. Only call this from the computation tasks. */
            if ((ret = PIOc_finalize(iosysid[my_comp_idx])))
                ERR(ret);
        }
    } /* my_rank < TARGET_NTASKS */

    /* Finalize test. */
    if ((ret = pio_test_finalize(&test_comm)))
        return ERR_AWFUL;

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);

    return 0;
}
예제 #3
0
/** Run async tests. */
int
main(int argc, char **argv)
{
    int my_rank; /* Zero-based rank of processor. */
    int ntasks; /* Number of processors involved in current execution. */
    int iosysid[COMPONENT_COUNT]; /* The ID for the parallel I/O system. */
    int flv; /* Index for loop of PIO netcdf flavors. */
    int ret; /* Return code. */

    int flavor[NUM_FLAVORS] = {PIO_IOTYPE_PNETCDF, PIO_IOTYPE_NETCDF,
			       PIO_IOTYPE_NETCDF4C, PIO_IOTYPE_NETCDF4P};

    /* Num procs for IO and computation. */
    int num_procs[NUM_COMBOS][COMPONENT_COUNT + 1] = {{3, 1}, {2, 2}, {1, 3}};

    /* Number of processors that will do IO. */
    int num_io_procs[NUM_COMBOS] = {3, 2, 1};

    /* Initialize test. */
    if ((ret = pio_test_init(argc, argv, &my_rank, &ntasks, TARGET_NTASKS)))
	ERR(ERR_INIT);
    
    for (int combo = 0; combo < NUM_COMBOS; combo++)
    {
	/* Is the current process a computation task? */
	int comp_task = my_rank < num_io_procs[combo] ? 0 : 1;
	
	/* Initialize the IO system. */
	if ((ret = PIOc_Init_Async(MPI_COMM_WORLD, num_io_procs[combo], NULL, COMPONENT_COUNT,
				   num_procs[combo], NULL, iosysid)))
	    ERR(ERR_INIT);
	
	for (int c = 0; c < COMPONENT_COUNT; c++)
	    printf("%d iosysid[%d] = %d\n", my_rank, c, iosysid[c]);
	
	/* All the netCDF calls are only executed on the computation
	 * tasks. The IO tasks have not returned from PIOc_Init_Intercomm,
	 * and when the do, they should go straight to finalize. */
	if (comp_task)
	{
	    for (int flv = 0; flv < NUM_FLAVORS; flv++)
	    {
		char filename[NC_MAX_NAME + 1]; /* Test filename. */
		int my_comp_idx = 0; /* Index in iosysid array. */
		
		for (int sample = 0; sample < NUM_SAMPLES; sample++)
		{
		    /* Create a filename. */
		    sprintf(filename, "%s_%s_%d_%d.nc", TEST_NAME, flavor_name(flv), sample, my_comp_idx);
		    
		    /* Create sample file. */
		    printf("%d %s creating file %s\n", my_rank, TEST_NAME, filename);
		    if ((ret = create_nc_sample(sample, iosysid[my_comp_idx], flavor[flv], filename, my_rank)))
			ERR(ret);
		    
		    /* Check the file for correctness. */
		    if ((ret = check_nc_sample(sample, iosysid[my_comp_idx], flavor[flv], filename, my_rank)))
			ERR(ret);
		}
	    } /* next netcdf flavor */
	    
	    /* Finalize the IO system. Only call this from the computation tasks. */
	    printf("%d %s Freeing PIO resources\n", my_rank, TEST_NAME);
	    for (int c = 0; c < COMPONENT_COUNT; c++)
	    {
		if ((ret = PIOc_finalize(iosysid[c])))
		    ERR(ret);
		printf("%d %s PIOc_finalize completed for iosysid = %d\n", my_rank, TEST_NAME,
		       iosysid[c]);
	    }
	} /* endif comp_task */

	/* Wait for everyone to catch up. */
	printf("%d %s waiting for all processes!\n", my_rank, TEST_NAME);
	MPI_Barrier(MPI_COMM_WORLD);
    } /* next combo */

    /* Finalize test. */
    printf("%d %s finalizing...\n", my_rank, TEST_NAME);
    if ((ret = pio_test_finalize()))
	ERR(ERR_AWFUL);

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);

    return 0;
}
예제 #4
0
/* Run async tests. */
int main(int argc, char **argv)
{
    int my_rank; /* Zero-based rank of processor. */
    int ntasks; /* Number of processors involved in current execution. */
    int iosysid_world; /* The ID for the parallel I/O system. */
    int even_iosysid; /* The ID for iosystem of even_comm. */
    int overlap_iosysid; /* The ID for iosystem of even_comm. */
    MPI_Group world_group; /* An MPI group of world. */
    MPI_Group even_group; /* An MPI group of 0 and 2. */
    MPI_Group overlap_group; /* An MPI group of 0, 1, and 3. */
    MPI_Comm even_comm = MPI_COMM_NULL; /* Communicator for tasks 0, 2 */
    MPI_Comm overlap_comm = MPI_COMM_NULL; /* Communicator for tasks 0, 1, 2. */
    int even_rank = -1, overlap_rank = -1; /* Tasks rank in communicator. */
    int even_size = 0, overlap_size = 0; /* Size of communicator. */
    int num_flavors; /* Number of PIO netCDF flavors in this build. */
    int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */
    MPI_Comm test_comm;
    int rearranger[NUM_REARRANGERS] = {PIO_REARR_BOX, PIO_REARR_SUBSET};
    int ret; /* Return code. */

    /* Initialize test. */
    if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, TARGET_NTASKS, TARGET_NTASKS,
                              -1, &test_comm)))
        ERR(ERR_INIT);

    /* Test code runs on TARGET_NTASKS tasks. The left over tasks do
     * nothing. */
    if (my_rank < TARGET_NTASKS)
    {
        /* Figure out iotypes. */
        if ((ret = get_iotypes(&num_flavors, flavor)))
            ERR(ret);

        /* Test with both rearrangers. */
        for (int r = 0; r < NUM_REARRANGERS; r++)
        {
            /* Initialize PIO system on world. */
            if ((ret = PIOc_Init_Intracomm(test_comm, NUM_IO4, STRIDE1, BASE0, rearranger[r],
                                           &iosysid_world)))
                ERR(ret);

            /* Set the error handler. */
            if ((ret = PIOc_set_iosystem_error_handling(iosysid_world, PIO_BCAST_ERROR, NULL)))
                ERR(ret);

            /* Get MPI_Group of world comm. */
            if ((ret = MPI_Comm_group(test_comm, &world_group)))
                ERR(ret);

            /* Create a group with tasks 0 and 2. */
            int even_ranges[EVEN_NUM_RANGES][3] = {{0, 2, 2}};
            if ((ret = MPI_Group_range_incl(world_group, EVEN_NUM_RANGES, even_ranges,
                                            &even_group)))
                ERR(ret);

            /* Create a communicator from the even_group. */
            if ((ret = MPI_Comm_create(test_comm, even_group, &even_comm)))
                ERR(ret);

            /* Learn my rank and the total number of processors in even group. */
            if (even_comm != MPI_COMM_NULL)
            {
                if ((ret = MPI_Comm_rank(even_comm, &even_rank)))
                    MPIERR(ret);
                if ((ret = MPI_Comm_size(even_comm, &even_size)))
                    MPIERR(ret);
            }

            /* Create a group with tasks 0, 1, and 3. */
            int overlap_ranges[OVERLAP_NUM_RANGES][3] = {{0, 0, 1}, {1, 3, 2}};
            if ((ret = MPI_Group_range_incl(world_group, OVERLAP_NUM_RANGES, overlap_ranges,
                                            &overlap_group)))
                ERR(ret);

            /* Create a communicator from the overlap_group. */
            if ((ret = MPI_Comm_create(test_comm, overlap_group, &overlap_comm)))
                ERR(ret);

            /* Learn my rank and the total number of processors in overlap
             * group. */
            if (overlap_comm != MPI_COMM_NULL)
            {
                if ((ret = MPI_Comm_rank(overlap_comm, &overlap_rank)))
                    MPIERR(ret);
                if ((ret = MPI_Comm_size(overlap_comm, &overlap_size)))
                    MPIERR(ret);
            }

            /* Initialize PIO system for even. */
            if (even_comm != MPI_COMM_NULL)
            {
                if ((ret = PIOc_Init_Intracomm(even_comm, NUM_IO1, STRIDE1, BASE1, rearranger[r],
                                               &even_iosysid)))
                    ERR(ret);

                /* These should not work. */
                if (PIOc_set_hint(even_iosysid + TEST_VAL_42, NULL, NULL) != PIO_EBADID)
                    ERR(ERR_WRONG);
                if (PIOc_set_hint(even_iosysid, NULL, NULL) != PIO_EINVAL)
                    ERR(ERR_WRONG);

                /* Set the hint (which will be ignored). */
                if ((ret = PIOc_set_hint(even_iosysid, "hint", "hint_value")))
                    ERR(ret);

                /* Set the error handler. */
                /*PIOc_Set_IOSystem_Error_Handling(even_iosysid, PIO_BCAST_ERROR);*/
                if ((ret = PIOc_set_iosystem_error_handling(even_iosysid, PIO_BCAST_ERROR, NULL)))
                    ERR(ret);
            }

            /* Initialize PIO system for overlap comm. */
            if (overlap_comm != MPI_COMM_NULL)
            {
                if ((ret = PIOc_Init_Intracomm(overlap_comm, NUM_IO2, STRIDE1, BASE1, rearranger[r],
                                               &overlap_iosysid)))
                    ERR(ret);

                /* Set the error handler. */
                PIOc_Set_IOSystem_Error_Handling(overlap_iosysid, PIO_BCAST_ERROR);
            }

            for (int i = 0; i < num_flavors; i++)
            {
                char fname0[PIO_MAX_NAME + 1];
                char fname1[PIO_MAX_NAME + 1];
                char fname2[PIO_MAX_NAME + 1];

                sprintf(fname0, "%s_file_0_iotype_%d_rearr_%d.nc", TEST_NAME, flavor[i], rearranger[r]);
                if ((ret = create_file(test_comm, iosysid_world, flavor[i], fname0, ATTNAME,
                                       DIMNAME, my_rank)))
                    ERR(ret);

                sprintf(fname1, "%s_file_1_iotype_%d_rearr_%d.nc", TEST_NAME, flavor[i], rearranger[r]);
                if ((ret = create_file(test_comm, iosysid_world, flavor[i], fname1, ATTNAME,
                                       DIMNAME, my_rank)))
                    ERR(ret);

                sprintf(fname2, "%s_file_2_iotype_%d_rearr_%d.nc", TEST_NAME, flavor[i], rearranger[r]);
                if ((ret = create_file(test_comm, iosysid_world, flavor[i], fname2, ATTNAME,
                                       DIMNAME, my_rank)))
                    ERR(ret);

                /* Now check the first file from WORLD communicator. */
                int ncid;
                if ((ret = open_and_check_file(test_comm, iosysid_world, flavor[i], &ncid, fname0,
                                               ATTNAME, DIMNAME, 1, my_rank)))
                    ERR(ret);

                /* Now have the even communicators check the files. */
                int ncid2;
                if (even_comm != MPI_COMM_NULL)
                {
                    if ((ret = open_and_check_file(even_comm, even_iosysid, flavor[i], &ncid2,
                                                   fname2, ATTNAME, DIMNAME, 1, my_rank)))
                        ERR(ret);
                    if ((ret = check_file(even_comm, even_iosysid, flavor[i], ncid2, fname2,
                                          ATTNAME, DIMNAME, my_rank)))
                        ERR(ret);
                }

                /* Now have the overlap communicators check the files. */
                int ncid3;
                if (overlap_comm != MPI_COMM_NULL)
                {
                    if ((ret = open_and_check_file(overlap_comm, overlap_iosysid, flavor[i],
                                                   &ncid3, fname1, ATTNAME, DIMNAME, 1, my_rank)))
                        ERR(ret);
                    if ((ret = check_file(overlap_comm, overlap_iosysid, flavor[i], ncid3, fname1,
                                          ATTNAME, DIMNAME, my_rank)))
                        ERR(ret);
                }

                /* Close the still-open files. */
                if (even_comm != MPI_COMM_NULL)
                    if ((ret = PIOc_closefile(ncid2)))
                        ERR(ret);
                if (overlap_comm != MPI_COMM_NULL)
                    if ((ret = PIOc_closefile(ncid3)))
                        ERR(ret);
                if ((ret = PIOc_closefile(ncid)))
                    ERR(ret);

            } /* next iotype */
        
            /* Finalize PIO systems. */
            if (even_comm != MPI_COMM_NULL)
                if ((ret = PIOc_finalize(even_iosysid)))
                    ERR(ret);
            if (overlap_comm != MPI_COMM_NULL)
            {
                if ((ret = PIOc_finalize(overlap_iosysid)))
                    ERR(ret);
            }
            if ((ret = PIOc_finalize(iosysid_world)))
                ERR(ret);

            /* Free MPI resources used by test. */
            if ((ret = MPI_Group_free(&overlap_group)))
                ERR(ret);
            if ((ret = MPI_Group_free(&even_group)))
                ERR(ret);
            if ((ret = MPI_Group_free(&world_group)))
                ERR(ret);
            if (overlap_comm != MPI_COMM_NULL)
                if ((ret = MPI_Comm_free(&overlap_comm)))
                    ERR(ret);
            if (even_comm != MPI_COMM_NULL)
                if ((ret = MPI_Comm_free(&even_comm)))
                    ERR(ret);
        } /* next rearranger */
    } /* my_rank < TARGET_NTASKS */

    /* Finalize test. */
    if ((ret = pio_test_finalize(&test_comm)))
        return ERR_AWFUL;

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);

    return 0;
}
예제 #5
0
/* Run tests for darray functions. */
int main(int argc, char **argv)
{
    int my_rank;
    int ntasks;
    int num_flavors; /* Number of PIO netCDF flavors in this build. */
    int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */
    MPI_Comm test_comm; /* A communicator for this test. */
    int ret;         /* Return code. */

    /* Initialize test. */
    if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, MIN_NTASKS,
                              MIN_NTASKS, -1, &test_comm)))
        ERR(ERR_INIT);

    if ((ret = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_RETURN_ERROR, NULL)))
        return ret;

    /* Only do something on max_ntasks tasks. */
    if (my_rank < TARGET_NTASKS)
    {
        int iosysid;  /* The ID for the parallel I/O system. */
        int ioproc_stride = 1;    /* Stride in the mpi rank between io tasks. */
        int ioproc_start = 0;     /* Zero based rank of first processor to be used for I/O. */
        int wioid, rioid;
        int maplen = MAPLEN;
        MPI_Offset wcompmap[MAPLEN];
        MPI_Offset rcompmap[MAPLEN];
        int rearranger[NUM_REARRANGERS_TO_TEST] = {PIO_REARR_BOX, PIO_REARR_SUBSET};

        /* Data we will write for each type. */
        signed char byte_data[MAPLEN];
        char char_data[MAPLEN];
        short short_data[MAPLEN];
        int int_data[MAPLEN];
        float float_data[MAPLEN];
        double double_data[MAPLEN];
#ifdef _NETCDF4
        unsigned char ubyte_data[MAPLEN];
        unsigned short ushort_data[MAPLEN];
        unsigned int uint_data[MAPLEN];
        long long int64_data[MAPLEN];
        unsigned long long uint64_data[MAPLEN];
#endif /* _NETCDF4 */

        /* Expected results for each type. */
        signed char byte_expected[MAPLEN];
        char char_expected[MAPLEN];
        short short_expected[MAPLEN];
        int int_expected[MAPLEN];
        float float_expected[MAPLEN];
        double double_expected[MAPLEN];
#ifdef _NETCDF4
        unsigned char ubyte_expected[MAPLEN];
        unsigned short ushort_expected[MAPLEN];
        unsigned int uint_expected[MAPLEN];
        long long int64_expected[MAPLEN];
        unsigned long long uint64_expected[MAPLEN];
#endif /* _NETCDF4 */

        /* Custom fill value for each type. */
        signed char byte_fill = -2;
        char char_fill = 2;
        short short_fill = -2;
        int int_fill = -2;
        float float_fill = -2;
        double double_fill = -2;
#ifdef _NETCDF4
        unsigned char ubyte_fill = 2;
        unsigned short ushort_fill = 2;
        unsigned int uint_fill = 2;
        long long int64_fill = 2;
        unsigned long long uint64_fill = 2;
#endif /* _NETCDF4 */

        /* Default fill value for each type. */
        signed char byte_default_fill = NC_FILL_BYTE;
        char char_default_fill = NC_FILL_CHAR;
        short short_default_fill = NC_FILL_SHORT;
        int int_default_fill = NC_FILL_INT;
        float float_default_fill = NC_FILL_FLOAT;
        double double_default_fill = NC_FILL_DOUBLE;
#ifdef _NETCDF4
        unsigned char ubyte_default_fill = NC_FILL_UBYTE;
        unsigned short ushort_default_fill = NC_FILL_USHORT;
        unsigned int uint_default_fill = NC_FILL_UINT;
        long long int64_default_fill = NC_FILL_INT64;
        unsigned long long uint64_default_fill = NC_FILL_UINT64;
#endif /* _NETCDF4 */

        int ret;      /* Return code. */

        /* Set up the compmaps. Don't forget these are 1-based
         * numbers, like in Fortran! */
        for (int i = 0; i < MAPLEN; i++)
        {
            wcompmap[i] = i % 2 ? my_rank * MAPLEN + i + 1 : 0; /* Even values missing. */
            rcompmap[i] = my_rank * MAPLEN + i + 1;
        }

        /* Figure out iotypes. */
        if ((ret = get_iotypes(&num_flavors, flavor)))
            ERR(ret);

        /* Test for each rearranger. */
        for (int r = 0; r < NUM_REARRANGERS_TO_TEST; r++)
        {
            /* Initialize the PIO IO system. This specifies how
             * many and which processors are involved in I/O. */
            if ((ret = PIOc_Init_Intracomm(test_comm, NUM_IO_PROCS, ioproc_stride, ioproc_start,
                                           rearranger[r], &iosysid)))
                return ret;

            /* Test with and without custom fill values. */
            for (int fv = 0; fv < NUM_TEST_CASES_FILLVALUE; fv++)
            {
#ifndef _NETCDF4
#define NUM_TYPES 6
                int test_type[NUM_TYPES] = {PIO_BYTE, PIO_CHAR, PIO_SHORT, PIO_INT, PIO_FLOAT, PIO_DOUBLE};
#else
#define NUM_TYPES 11
                int test_type[NUM_TYPES] = {PIO_BYTE, PIO_CHAR, PIO_SHORT, PIO_INT, PIO_FLOAT, PIO_DOUBLE,
                                            PIO_UBYTE, PIO_USHORT, PIO_UINT, PIO_INT64, PIO_UINT64};
                
#endif /* _NETCDF4 */

                /* Determine what data to write. Put value of 42 into
                 * array elements that will not get written. Due to
                 * the decomposition, these will be replaced by fill
                 * values. */
                for (int i = 0; i < MAPLEN; i++)
                {
                    byte_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    char_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    short_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    int_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    float_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    double_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
#ifdef _NETCDF4
                    ubyte_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    ushort_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    uint_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    int64_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
                    uint64_data[i] = i % 2 ? my_rank * MAPLEN + i + 1 : TEST_VAL_42;
#endif /* _NETCDF4 */
                }

                /* Determine what data to expect from the test. For
                 * even values of i, the fill value will be used, and
                 * it may be custom or default fill value. */
                for (int i = 0; i < MAPLEN; i++)
                {
                    byte_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? byte_default_fill : byte_fill);
                    char_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? char_default_fill : char_fill);
                    short_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? short_default_fill : short_fill);
                    int_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? int_default_fill : int_fill);
                    float_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? float_default_fill : float_fill);
                    double_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? double_default_fill : double_fill);
#ifdef _NETCDF4
                    ubyte_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? ubyte_default_fill : ubyte_fill);
                    ushort_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? ushort_default_fill : ushort_fill);
                    uint_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? uint_default_fill : uint_fill);
                    int64_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? int64_default_fill : int64_fill);
                    uint64_expected[i] = i % 2 ? my_rank * MAPLEN + i + 1 : (fv ? uint64_default_fill : uint64_fill);
#endif /* _NETCDF4 */
                }

                /* Test for each available type. */
                for (int t = 0; t < NUM_TYPES; t++)
                {
                    void *expected;
                    void *fill;
                    void *data;
                    int ncid, dimid, varid;
                    char filename[NC_MAX_NAME + 1];

                    switch (test_type[t])
                    {
                    case PIO_BYTE:
                        expected = byte_expected;
                        fill = fv ? &byte_default_fill : &byte_fill;
                        data = byte_data;
                        break;
                    case PIO_CHAR:
                        expected = char_expected;
                        fill = fv ? &char_default_fill : &char_fill;
                        data = char_data;
                        break;
                    case PIO_SHORT:
                        expected = short_expected;
                        fill = fv ? &short_default_fill : &short_fill;
                        data = short_data;
                        break;
                    case PIO_INT:
                        expected = int_expected;
                        fill = fv ? &int_default_fill : &int_fill;
                        data = int_data;
                        break;
                    case PIO_FLOAT:
                        expected = float_expected;
                        fill = fv ? &float_default_fill : &float_fill;
                        data = float_data;
                        break;
                    case PIO_DOUBLE:
                        expected = double_expected;
                        fill = fv ? &double_default_fill : &double_fill;
                        data = double_data;
                        break;
#ifdef _NETCDF4
                    case PIO_UBYTE:
                        expected = ubyte_expected;
                        fill = fv ? &ubyte_default_fill : &ubyte_fill;
                        data = ubyte_data;
                        break;
                    case PIO_USHORT:
                        expected = ushort_expected;
                        fill = fv ? &ushort_default_fill : &ushort_fill;
                        data = ushort_data;
                        break;
                    case PIO_UINT:
                        expected = uint_expected;
                        fill = fv ? &uint_default_fill : &uint_fill;
                        data = uint_data;
                        break;
                    case PIO_INT64:
                        expected = int64_expected;
                        fill = fv ? &int64_default_fill : &int64_fill;
                        data = int64_data;
                        break;
                    case PIO_UINT64:
                        expected = uint64_expected;
                        fill = fv ? &uint64_default_fill : &uint64_fill;
                        data = uint64_data;
                        break;
#endif /* _NETCDF4 */
                    default:
                        return ERR_AWFUL;
                    }

                    /* Initialize decompositions. */
                    if ((ret = PIOc_InitDecomp(iosysid, test_type[t], NDIM1, dim_len, maplen, wcompmap,
                                               &wioid, &rearranger[r], NULL, NULL)))
                        return ret;
                    if ((ret = PIOc_InitDecomp(iosysid, test_type[t], NDIM1, dim_len, maplen, rcompmap,
                                               &rioid, &rearranger[r], NULL, NULL)))
                        return ret;

                    /* Create the test file in each of the available iotypes. */
                    for (int fmt = 0; fmt < num_flavors; fmt++)
                    {
                        PIO_Offset type_size;
                        void *data_in;

                        /* Byte type doesn't work with pnetcdf. */
                        if (flavor[fmt] == PIO_IOTYPE_PNETCDF && (test_type[t] == PIO_BYTE || test_type[t] == PIO_CHAR))
                            continue;

                        /* NetCDF-4 types only work with netCDF-4 formats. */
                        if (test_type[t] > PIO_DOUBLE && flavor[fmt] != PIO_IOTYPE_NETCDF4C &&
                            flavor[fmt] != PIO_IOTYPE_NETCDF4P)
                            continue;

                        /* Put together filename. */
                        sprintf(filename, "%s_iotype_%d_rearr_%d_type_%d.nc", TEST_NAME, flavor[fmt],
                                rearranger[r], test_type[t]);

                        /* Create file. */
                        if ((ret = PIOc_createfile(iosysid, &ncid, &flavor[fmt], filename, NC_CLOBBER)))
                            return ret;

                        /* Define metadata. */
                        if ((ret = PIOc_def_dim(ncid, DIM_NAME, dim_len[0], &dimid)))
                            return ret;
                        if ((ret = PIOc_def_var(ncid, VAR_NAME, test_type[t], NDIM1, &dimid, &varid)))
                            return ret;
                        if ((ret = PIOc_put_att(ncid, varid, FILL_VALUE_NAME, test_type[t],
                                                1, fill)))
                            return ret;
                        if ((ret = PIOc_enddef(ncid)))
                            return ret;

                        /* Write some data. */
                        if ((ret = PIOc_write_darray(ncid, varid, wioid, MAPLEN, data, fill)))
                            return ret;
                        if ((ret = PIOc_sync(ncid)))
                            return ret;

                        /* What is size of type? */
                        if ((ret = PIOc_inq_type(ncid, test_type[t], NULL, &type_size)))
                            return ret;

                        /* Allocate space to read data into. */
                        if (!(data_in = malloc(type_size * MAPLEN)))
                            return PIO_ENOMEM;

                        /* Read the data. */
                        if ((ret = PIOc_read_darray(ncid, varid, rioid, MAPLEN, data_in)))
                            return ret;

                        /* Check results. */
                        if (memcmp(data_in, expected, type_size * MAPLEN))
                            return ERR_AWFUL;

                        /* Release storage. */
                        free(data_in);

                        /* Close file. */
                        if ((ret = PIOc_closefile(ncid)))
                            return ret;
                    } /* next iotype */

                    /* Free decompositions. */
                    if ((ret = PIOc_freedecomp(iosysid, wioid)))
                        return ret;
                    if ((ret = PIOc_freedecomp(iosysid, rioid)))
                        return ret;

                } /* next type */
            } /* next fill value test case */
        } /* next rearranger */

        /* Finalize PIO system. */
        if ((ret = PIOc_finalize(iosysid)))
            return ret;

    } /* endif my_rank < TARGET_NTASKS */

    /* Finalize the MPI library. */
    if ((ret = pio_test_finalize(&test_comm)))
        return ret;

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);
    return 0;
}
예제 #6
0
/* Run async tests. */
int main(int argc, char **argv)
{
    int my_rank; /* Zero-based rank of processor. */
    int ntasks; /* Number of processors involved in current execution. */
    int iosysid[COMPONENT_COUNT]; /* The ID for the parallel I/O system. */
    int num_flavors; /* Number of PIO netCDF flavors in this build. */
    int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */
    int ret; /* Return code. */
    MPI_Comm test_comm;

    /* Num procs for computation. */
    int num_procs2[NUM_COMBOS][COMPONENT_COUNT] = {{1}, {2}, {3}};

    /* Number of processors that will do IO. */
    int num_io_procs[NUM_COMBOS] = {3, 2, 1};

    /* Initialize test. */
    if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, TARGET_NTASKS, TARGET_NTASKS,
                              -1, &test_comm)))
        ERR(ERR_INIT);

    /* Test code runs on TARGET_NTASKS tasks. The left over tasks do
     * nothing. */
    if (my_rank < TARGET_NTASKS)
    {
        /* Figure out iotypes. */
        if ((ret = get_iotypes(&num_flavors, flavor)))
            ERR(ret);

        for (int combo = 0; combo < NUM_COMBOS; combo++)
        {
            /* Is the current process a computation task? */
            int comp_task = my_rank < num_io_procs[combo] ? 0 : 1;

            /* Initialize the IO system. */
            if ((ret = PIOc_init_async(test_comm, num_io_procs[combo], NULL, COMPONENT_COUNT,
                                       num_procs2[combo], NULL, NULL, NULL, PIO_REARR_BOX, iosysid)))
                ERR(ERR_INIT);

            /* All the netCDF calls are only executed on the computation
             * tasks. The IO tasks have not returned from PIOc_Init_Intercomm,
             * and when the do, they should go straight to finalize. */
            if (comp_task)
            {
                for (int flv = 0; flv < num_flavors; flv++)
                {
                    char filename[NC_MAX_NAME + 1]; /* Test filename. */
                    int my_comp_idx = 0; /* Index in iosysid array. */

                    for (int sample = 0; sample < NUM_SAMPLES; sample++)
                    {
                        char iotype_name[NC_MAX_NAME + 1];

                        /* Create a filename. */
                        if ((ret = get_iotype_name(flavor[flv], iotype_name)))
                            return ret;
                        sprintf(filename, "%s_%s_%d_%d.nc", TEST_NAME, iotype_name, sample, my_comp_idx);

                        /* Create sample file. */
                        if ((ret = create_nc_sample(sample, iosysid[my_comp_idx], flavor[flv], filename, my_rank, NULL)))
                            ERR(ret);

                        /* Check the file for correctness. */
                        if ((ret = check_nc_sample(sample, iosysid[my_comp_idx], flavor[flv], filename, my_rank, NULL)))
                            ERR(ret);
                    }
                } /* next netcdf flavor */

                /* Finalize the IO system. Only call this from the computation tasks. */
                for (int c = 0; c < COMPONENT_COUNT; c++)
                    if ((ret = PIOc_finalize(iosysid[c])))
                        ERR(ret);
            } /* endif comp_task */

            /* Wait for everyone to catch up. */
            MPI_Barrier(test_comm);
        } /* next combo */
    }/* my_rank < TARGET_NTASKS */

    /* Finalize test. */
    if ((ret = pio_test_finalize(&test_comm)))
        return ERR_AWFUL;

    printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);

    return 0;
}