Exemple #1
0
/*
 * mpi_io_shared
 *
 * creates a single-shared-file
 * writes with independent-io
 * reads with independent-io
 * writes with collective-io
 * reads with collective-io
 */
int mpi_io_shared (char *path, int size, int rank)
{
    MPI_File fh;
    char filepath[512];
    MPI_Offset offset;
    MPI_Status status;
    void *buf;
    int bufcount = BYTES_PER_RANK;
    int rc;

    buf = malloc(bufcount);
    if (!buf) { return 0; }

    memset(buf, 0xa, bufcount);

    sprintf(filepath, "%s/%s", path, "cp-bench-mpio-shared");
    rc = MPI_File_open(MPI_COMM_WORLD,
                       filepath,
                       (MPI_MODE_CREATE|MPI_MODE_RDWR|MPI_MODE_DELETE_ON_CLOSE),
                       MPI_INFO_NULL,
                       &fh);
    MPI_CHECK(rc,"MPI_File_open");

    /* Indep Write */
    offset = rank * bufcount;
    rc = MPI_File_write_at(fh,offset,buf,bufcount,MPI_BYTE,&status);
    MPI_CHECK(rc,"MPI_File_write_at");

    MPI_Barrier(MPI_COMM_WORLD);

    /* Indep Read */
    offset = ((rank+1)%size) * bufcount;
    rc = MPI_File_read_at(fh,offset,buf,bufcount,MPI_BYTE,&status);
    MPI_CHECK(rc,"MPI_File_read_at");

    /* Collective Write */
    offset = rank * bufcount;
    rc = MPI_File_write_at_all(fh, offset, buf, bufcount, MPI_BYTE, &status);
    MPI_CHECK(rc,"MPI_File_write_at_all");

    /* Collective Read */
    offset = ((rank+1)%size) * bufcount;
    rc = MPI_File_read_at_all(fh, offset, buf, bufcount, MPI_BYTE, &status);
    MPI_CHECK(rc,"MPI_File_read_at_all");

    rc = MPI_File_close(&fh);
    MPI_CHECK(rc,"MPI_File_close");

    free(buf);

    return 1;
}
Exemple #2
0
/* This test checks if datareps given are little- or big-endian */
int main( int argc, char* argv[] ) {
    int sample_i = 123456789, i, j;
    char sample_i_le[4] = {0x15,0xcd,0x5b,0x07}, c[4];
    const char* datarep[3] = { "native", "external32", "internal" };
    MPI_File fileh;
    int rank;
    FILE* fileh_std;

    if( sizeof(int) != 4 ) { printf( "non-supported sizeof(int)=%ld\n", sizeof(int) ); return (-1); }

    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );

    /* For each datarep */
    for( i = 0; i < 3; i++ ) {

        /* Open file */
        CHECK(MPI_File_open( MPI_COMM_WORLD, TEST_FILENAME, 
		    MPI_MODE_RDWR | MPI_MODE_CREATE, MPI_INFO_NULL, &fileh ) );

        /* Set view */
	CHECK(MPI_File_set_view( fileh, 0, MPI_INT, MPI_INT, datarep[i], MPI_INFO_NULL ));

        /* Write into file */
	CHECK(MPI_File_write_at( fileh, (MPI_Offset)rank, (void*)&sample_i, 1, 
		    MPI_INT, MPI_STATUS_IGNORE ));

        /* Close file */
        CHECK(MPI_File_close( &fileh ));

        /* Check if your datarep is little or big endian */
        MPI_Barrier( MPI_COMM_WORLD );
        if( rank == 0 ) {
            fileh_std = fopen( TEST_FILENAME, "r" );
            for( j = 0; j < 4; j++ ) {
                if( feof( fileh_std ) ) { printf( "unexpected eof, aborted\n" ); return (-1); }
                fscanf( fileh_std, "%c", &c[j] );
            }
            is_little_or_big_endian( datarep[i], c, sample_i_le, 4 );
            fclose( fileh_std );
        }

        /* Delete file */
        if( rank == 0 ) {
            CHECK(MPI_File_delete( TEST_FILENAME, MPI_INFO_NULL ));
        }
    }

    MPI_Finalize();

    return 0;
}
Exemple #3
0
FORT_DLL_SPEC void FORT_CALL mpi_file_write_at_ ( MPI_Fint *v1, MPI_Offset *v2, void*v3, MPI_Fint *v4, MPI_Fint *v5, MPI_Fint *v6, MPI_Fint *ierr ){
#ifdef MPI_MODE_RDONLY

#ifndef HAVE_MPI_F_INIT_WORKS_WITH_C
    if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0; }
#endif

    if (v6 == MPI_F_STATUS_IGNORE) { v6 = (MPI_Fint*)MPI_STATUS_IGNORE; }
    *ierr = MPI_File_write_at( MPI_File_f2c(*v1), (MPI_Offset)*v2, v3, (int)*v4, (MPI_Datatype)(*v5), (MPI_Status *)v6 );
#else
*ierr = MPI_ERR_INTERN;
#endif
}
void dump_time_field(char* file_prefix, grid_parms grid, double field)
{
	MPI_Status status;
	MPI_Offset displacement = 0;
	MPI_File fw;
	char* buffer = (char*)checked_malloc(NUM_DBL_TO_CHAR_BYTES * sizeof(char), SRC_LOC);
	char* write_buffer;
	int root = 0;
	char filename[50];

	int length = sprintf(buffer, "%2.12lf\n", field);

	int *recv_count = (int*) checked_malloc(grid.num_ranks_branch * sizeof(int), SRC_LOC);
	int *disp = (int*) checked_malloc(grid.num_ranks_branch * sizeof(int), SRC_LOC);

	/// Gathering the lengths of buffer from each MPI process.
	CHECK_MPI_ERROR(MPI_Gather(&length, 1, MPI_INT, recv_count, 1, MPI_INT, root, grid.cart_comm));

	int total_buffer_length = 0;
	for (int i = 0; i < grid.num_ranks_branch; i++)
	{
		disp[i] = total_buffer_length;
		total_buffer_length += recv_count[i];
	}

	if (grid.rank_branch == 0)
	{
		write_buffer = (char*) checked_malloc(total_buffer_length * sizeof(char), SRC_LOC);
	}

	// Gathering the buffers from all MPI processes.
	CHECK_MPI_ERROR(MPI_Gatherv(buffer, length, MPI_CHAR, write_buffer, recv_count, disp, MPI_CHAR, root, grid.cart_comm));

	if (grid.rank_branch == 0)
	{
		sprintf(filename, "%s/%s_%d_%d.txt", grid.time_profiling_dir, file_prefix, grid.domain_index, grid.branch_tag);

		CHECK_MPI_ERROR(MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fw));
		CHECK_MPI_ERROR(MPI_File_write_at(fw, 0, write_buffer, total_buffer_length, MPI_CHAR, &status));
		MPI_File_close(&fw);
	}

	if (grid.rank_branch == 0)
	{
		free(write_buffer);
	}

	free(recv_count);
	free(buffer);
	free(disp);
}
Exemple #5
0
void Mpi2Evolution::OpenFiles(int is_restart){
	World* pW= World::instance();
	if (pW->saveEvolStepSize == 0) return;


#ifndef HAVE_MPI_THREADS
	if (pW->m_myRank == 0)
		cout << "\n!!! Warning: !!!\nSaving spin evolution in parallel JEMRIS mode requires MPI2.0 (parallel file I/O). no evol files will be written.\nUse MPI2.0 or sequential jemris.\n" << endl;
#else
	long M     = pW->TotalADCNumber / pW->saveEvolStepSize ;
	string fname;
	int SpinNo = pW->TotalSpinNumber;

	MPI_Bcast(&is_restart,1,MPI_INT,0,MPI_COMM_WORLD);

	MPI_Bcast(&SpinNo,1,MPI_INT,0,MPI_COMM_WORLD);
	MPI_Offset filesize;
	filesize = (SpinNo * 7 +2)* sizeof(double);
    MPI_Status status;

	for (int i=0; i<M; i++) {
        stringstream sF;
        sF << pW->saveEvolFileName << "_" << setw(3) << setfill('0') << i+1 << ".bin";
        if (is_restart != 1){
         // delete existing old file; (c) by Rolf Rabenseifer...
  /*       	MPI::File fh=MPI::File::Open(MPI::COMM_WORLD,(sF.str()).c_str(),MPI::MODE_DELETE_ON_CLOSE | MPI::MODE_CREATE | MPI::MODE_WRONLY, MPI::INFO_NULL  );
         	fh.Close();*/
 	// above lines lead to trouble on our cluster. try different approach:
 		if (pW->m_myRank == 0) {
 			ofstream myfile;
 			myfile.open ((sF.str()).c_str(),ios::out | ios::binary| ios::trunc);
 			myfile.close();
 		}
 		MPI_Barrier(MPI_COMM_WORLD);
        }
	MPI_File mpifh;
	MPI_File_open (MPI_COMM_WORLD, charstar(sF.str()),MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &mpifh);
        m_files.push_back(mpifh);

		MPI_File_preallocate(m_files[i], filesize);
		if (pW->m_myRank == 1) {
			double dummy = (double) SpinNo;
            MPI_File_write_at(m_files[i], 0, &dummy, 1, MPI_DOUBLE,&status);
			m_first_write.push_back(true);
		}
	}

#endif

}
void dump_coords(grid_parms grid, celltype2** ec, checkpoint_handle* check, const char* message){

	MPI_Status	status;
	MPI_Offset	disp;
	int write_element_count	=	grid.num_ec_axially;
	double buffer[write_element_count];

	int k = 0;
		int i =1;
		for (int j = 1; j <= grid.num_ec_axially; j++) {
				buffer[k]	=	ec[i][j].z_coord;
				k++;
			}
		int offset = grid.rank/grid.n;
		disp = (offset * write_element_count * sizeof(double));
		CHECK(MPI_File_write_at(check->coords, disp, &buffer, write_element_count, MPI_DOUBLE, &status));
}
void dump_ec(grid_parms grid, celltype2 **ec, checkpoint_handle *check, int write_count){
	MPI_Status status[8];
	MPI_Offset disp;
	int write_element_count, time_offset_in_file;

	write_element_count = grid.num_ec_axially * grid.num_ec_circumferentially;
	time_offset_in_file = write_count * write_element_count * grid.tasks
			* sizeof(double);

	double b1[grid.num_ec_circumferentially * grid.num_ec_axially],
			b2[grid.num_ec_circumferentially * grid.num_ec_axially],
			b3[grid.num_ec_circumferentially * grid.num_ec_axially],
			b4[grid.num_ec_circumferentially * grid.num_ec_axially],
			b5[grid.num_ec_circumferentially * grid.num_ec_axially],
			b6[grid.num_ec_circumferentially * grid.num_ec_axially],
			b7[grid.num_ec_circumferentially * grid.num_ec_axially];
	int k;

	k = 0;
	for (int i = 1; i <= grid.num_ec_circumferentially; i++) {
		for (int j = 1; j <= grid.num_ec_axially; j++) {
			b1[k] = ec[i][j].q[ec_Ca];
			b2[k] = ec[i][j].q[ec_SR];
			b3[k] = ec[i][j].q[ec_Vm];
			b4[k] = ec[i][j].q[ec_IP3];
			b5[k] = ec[i][j].B[cpl_Ca];
			b6[k] = ec[i][j].B[cpl_Vm];
			b7[k] = ec[i][j].B[cpl_IP3];
			k++;
		}
	}
	disp = time_offset_in_file
			+ (grid.rank * write_element_count * sizeof(double));
	CHECK(
			MPI_File_write_at(check->cj, disp, &b1, write_element_count, MPI_DOUBLE, &status[0]));
	CHECK(
			MPI_File_write_at(check->sj, disp, &b2, write_element_count, MPI_DOUBLE, &status[1]));
	CHECK(
			MPI_File_write_at(check->vj, disp, &b3, write_element_count, MPI_DOUBLE, &status[2]));
	CHECK(
			MPI_File_write_at(check->Ij, disp, &b4, write_element_count, MPI_DOUBLE, &status[3]));
	CHECK(
			MPI_File_write_at(check->cpCj, disp, &b5, write_element_count, MPI_DOUBLE, &status[4]));
	CHECK(
			MPI_File_write_at(check->cpVj, disp, &b6, write_element_count, MPI_DOUBLE, &status[5]));
	CHECK(
			MPI_File_write_at(check->cpIj, disp, &b7, write_element_count, MPI_DOUBLE, &status[6]));
}
Exemple #8
0
int savematrix_cross_rows(MPI_File *fh, float *data, int numrows, int rank, int numtasks, int m, int n)
{
	MPI_Offset offset = 0;
	int i = 0, j = 0;
	MPI_Status status;
	MPI_Datatype rowtype;
	MPI_Datatype filetype;
	int result = 0;
	
	MPI_Type_contiguous(n, MPI_FLOAT, &rowtype);
	MPI_Type_commit(&rowtype);
	
	MPI_Type_vector(numrows, 1, numtasks, rowtype, &filetype);
	MPI_Type_commit(&filetype);
	
	offset = rank;
	
	MPI_File_set_view(*fh, offset*n*sizeof(float), rowtype, filetype, "native", MPI_INFO_NULL);
	
	result = MPI_File_write_at(*fh, 0, data, numrows, rowtype, &status);
	if(result != MPI_SUCCESS)
	{
		printf("Proc %d write at %d error!\n", rank, offset);
	}
	
	#if 1
	if(rank == 0)
	{
		for(i = 0; i < numrows; i++)
		{
			printf("Proc %d write row %d: ", rank, i);
			for(j = 0; j < n; j++)
			{
				printf("%f, ", data[i*n+j]);
			}
			printf("\n");
		}
	}
	#endif
	
	MPI_Type_free(&rowtype);
	MPI_Type_free(&filetype);
	
	return n*numrows;
}
Exemple #9
0
JNIEXPORT void JNICALL Java_mpi_File_writeAt(
        JNIEnv *env, jobject jthis, jlong fh, jlong fileOffset,
        jobject buf, jboolean db, jint off, jint count,
        jlong jType, jint bType, jlongArray stat)
{
    MPI_Datatype type = (MPI_Datatype)jType;
    void *ptr;
    ompi_java_buffer_t *item;
    ompi_java_getReadPtr(&ptr, &item, env, buf, db, off, count, type, bType);
    MPI_Status status;

    int rc = MPI_File_write_at((MPI_File)fh, (MPI_Offset)fileOffset,
                               ptr, count, type, &status);

    ompi_java_exceptionCheck(env, rc);
    ompi_java_releaseReadPtr(ptr, item, buf, db);
    ompi_java_status_set(env, stat, &status);
}
void dump_JPLC(grid_parms grid, celltype2 **ec, checkpoint_handle *check, const char *message){

/*	MPI_Status	status;
	MPI_Offset	disp;
	int write_element_count	=	grid.num_ec_circumferentially * grid.num_ec_axially;
	double buffer[write_element_count];

	int k = 0;
		for (int i = 1; i <= grid.num_ec_circumferentially; i++) {
			for (int j = 1; j <= grid.num_ec_axially; j++) {
				buffer[k]	=	ec[i][j].JPLC;
				k++;
			}
		}

	int k = 0;
			int i=1;
				for (int j = 1; j <= grid.num_ec_axially; j++) {
					buffer[k]	=	ec[i][j].JPLC;
					k++;
				}
	int offset = grid.rank/grid.n;
	//disp = (grid.rank * write_element_count * sizeof(double));
	disp = (offset * write_element_count * sizeof(double));
	CHECK(MPI_File_write_at(check->jplc, disp, &buffer, write_element_count, MPI_DOUBLE, &status));*/

		MPI_Status	status;
		MPI_Offset	disp;
		int write_element_count	=	grid.num_ec_axially;
		double buffer[write_element_count];

		int k = 0;
				int i=1;
					for (int j = 1; j <= grid.num_ec_axially; j++) {
						buffer[k]	=	ec[i][j].JPLC;
						k++;
					}
		int offset = grid.rank/grid.n;
		disp = (offset * write_element_count * sizeof(double));
		CHECK(MPI_File_write_at(check->jplc, disp, &buffer, write_element_count, MPI_DOUBLE, &status));
}
Exemple #11
0
	/*!
	Writes the geometry into given open file starting at given offset.

	Returns true on success, false otherwise.

	The number of bytes written by this function can be obtained
	from geometry_data_size().
	*/
	bool write(MPI_File file, MPI_Offset offset) const
	{
		const int
			temp_id = No_Geometry::geometry_id,
			ret_val = MPI_File_write_at(
				file,
				offset,
				(void*) &temp_id,
				1,
				MPI_INT,
				MPI_STATUS_IGNORE
			);
		if (ret_val != MPI_SUCCESS) {
			std::cerr << __FILE__ << ":" << __LINE__
				<< " Couldn't write geometry data to given file: " << Error_String()(ret_val)
				<< std::endl;
			return false;
		}

		return true;
	}
Exemple #12
0
int main(int argc, char *argv[])
{
    int i, myrank, buf[BUFSIZE];
	int count, nprocs;
    char *filename;
    MPI_File thefile;
    MPI_Offset offset;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
	MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

	if (argc < 3) {
		fprintf(stderr, "Usage: %s <count> <output file>\n", argv[0]);
		exit(1);
	}
	count = atoi(argv[1]);
	filename = argv[2];

    for (i = 0; i < BUFSIZE; i++)
        buf[i] = myrank * BUFSIZE + i;
    MPI_File_open(MPI_COMM_WORLD, filename, (MPI_MODE_WRONLY | MPI_MODE_CREATE),
		  MPI_INFO_NULL, &thefile);
    MPI_File_set_view(thefile, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL);


    offset = myrank * BUFSIZE;
	for (i=0; i<count; i++) {
#ifdef DEBUG
		printf("Wrote round %d\n", i);
#endif
    	MPI_File_write_at(thefile, offset, buf, BUFSIZE, MPI_INT, MPI_STATUS_IGNORE);
		offset += nprocs*BUFSIZE;

	}
    MPI_File_close(&thefile);
    MPI_Finalize();
    return 0;
}
Exemple #13
0
int main(int argc, char* argv[])
{
	if (argc != 3) {
		fprintf(stderr, "%s\n", usage);
		return 0;
	}

	/* Initialisation */
	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &nb_proc);
	
	MPI_Status  status;

	int nb_elem = atoi(argv[1]);	// nombre d'éléments total
	int sort_type = atoi(argv[2]);	// type de l'algorithme de tri

	k = nb_elem / nb_proc;

	int *tab_sort = (int *)malloc(k*sizeof(int));
	int *tab_tmp = (int *)malloc(k*sizeof(int));
	
	if ((tab_tmp == NULL) || (tab_sort == NULL)) {
		fprintf(stderr, "Erreur allocation mémoire du tableau \n");
		MPI_Finalize();
		exit(1);
	}

	int left = my_rank-1;
	int right = my_rank+1;

	// initialise le tableau local
	P0 printf("Initialisation du tableau...");
	switch (sort_type) {
		case 1:	
		case 2: init_rand(tab_tmp, k); break;
		case 3:
		case 4:
		case 5: init_rand(tab_sort, k); break;
	}
	P0 printf(" OK!\n");

	P0 printf("Calcul...\n");

	// début du chronométrage
	double start, end;
	start = MPI_Wtime();
	
	// choix de l'algorithme de tri
	switch (sort_type) {
		case 1: PRAM(tab_tmp, tab_sort); break;
		case 2: PRAM_omp(tab_tmp, tab_sort); break;
		case 3: quick_sort(tab_sort, k); break;
		case 4: quick_sort_omp(tab_sort, k); break;
		case 5: qsort(tab_sort, k, sizeof(int), compare); break;
	}

	// tri pair-impair
	int step;
	for (step = 0; step < nb_proc; step++) {
		if ((my_rank%2) - (step%2) == 0) {
			if (my_rank != nb_proc-1) {
				MPI_Recv(tab_tmp, k, MPI_INT, right, TAG_TAB, MPI_COMM_WORLD, &status);
				merge_sort(tab_sort, tab_tmp);
				MPI_Send(tab_tmp, k, MPI_INT, right, TAG_TAB, MPI_COMM_WORLD);
			}
		}
		else {
			if (my_rank != 0) {
				MPI_Send(tab_sort, k, MPI_INT, left, TAG_TAB, MPI_COMM_WORLD);
				MPI_Recv(tab_sort, k, MPI_INT, left, TAG_TAB, MPI_COMM_WORLD, &status);
			}
		}
	}
	
	// fin du chronométrage
	end = MPI_Wtime();

	print_results(end - start);

	// écriture dans le fichier 	
	if (nb_elem <= NMAX) {
		P0 printf("Ecriture du fichier...");

		MPI_File file; 
		MPI_Offset my_offset;
		char filename[strlen("/Vrac/ppar_cassat_ducamain_sort")+1];
		strcpy(filename, "/Vrac/ppar_cassat_ducamain_sort");	

		my_offset = my_rank * sizeof(int) * k;
		MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &file);
		MPI_File_write_at(file, my_offset, tab_sort, k, MPI_INT, &status);
		// printf("(%d) a écrit: ", my_rank);
		// print_tab(tab_sort, k);
		
		// attends que tous aient écrit
		MPI_Barrier(MPI_COMM_WORLD);
		
		MPI_File_read_ordered(file, tab_sort, k, MPI_INT, &status);
		MPI_File_close(&file);
		// printf("(%d) a lu: ", my_rank);
		// print_tab(tab_sort, k);

		P0 printf(" OK!\n");
	}

	// Vérification du tri
	P0 printf("Vérification du tri...\n");

	if (!check_sort(tab_sort, k) && (my_rank == 0))
		printf("\tTri correct!\n");

	#ifdef BENCH
	P0 fprintf(stderr, "\t%d\t%d\t%d", sort_type, nb_elem, nb_proc);

	#ifdef _OPENMP
	#pragma omp parallel
	{
		if ((my_rank == 0) && (omp_get_thread_num() == 0))
			fprintf(stderr, "\t%d", omp_get_num_threads());
	}
	#endif
	
	P0 fprintf(stderr, "\n");
	#endif 

	free(tab_sort);
	free(tab_tmp);

	/* Desactivation */
	MPI_Finalize();
	return 0;
}
Exemple #14
0
int main(int argc, char *argv[])
{
    MPI_File fh;
    char emsg[MPI_MAX_ERROR_STRING];
    int emsglen, err, ec, errs = 0;
    int amode, rank;
    char *name = 0;
    MPI_Status st;
    int outbuf[BUFLEN], inbuf[BUFLEN];

    MTest_Init(&argc, &argv);

    name = "not-a-file-to-use";
    /* Try to open a file that does/should not exist */
    /* Note that no error message should be printed by MPI_File_open,
     * even when there is an error */
    err = MPI_File_open(MPI_COMM_WORLD, name, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
    if (err == MPI_SUCCESS) {
        errs++;
        printf("Did not return error when opening a file that does not exist\n");
        MPI_File_close(&fh);
        MPI_File_delete(name, MPI_INFO_NULL);
    } else {
        MPI_Error_class(err, &ec);
        MPI_Error_string(err, emsg, &emsglen);
        MTestPrintfMsg(2, "Error msg from open: %s\n", emsg);
        if (ec != MPI_ERR_NO_SUCH_FILE && ec != MPI_ERR_IO) {
            errs++;
            printf("Did not return class ERR_NO_SUCH_FILE or ERR_IO\n");
            printf("Returned class %d, message %s\n", ec, emsg);
        }
    }

    /* Now, create a file, write data into it; close, then reopen as
     * read only and try to write to it */

    amode = MPI_MODE_CREATE | MPI_MODE_WRONLY;
    name = "mpio-test-openerrs";

    err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
    if (err) {
        errs++;
        MTestPrintErrorMsg("Unable to open file for writing", err);
    } else {
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        memset(outbuf, 'A' + rank, BUFLEN);

        err = MPI_File_write_at(fh, rank * BUFLEN, outbuf, BUFLEN, MPI_BYTE, &st);
        if (err) {
            errs++;
            MTestPrintErrorMsg("Unable to write file", err);
        }
        MPI_File_close(&fh);
    }

    /* Now, open for read only, and delete on close */
    amode = MPI_MODE_RDONLY | MPI_MODE_DELETE_ON_CLOSE;

    err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
    if (err) {
        errs++;
        MTestPrintErrorMsg("Unable to reopen file for reading", err);
    } else {
        /* Try to read it */

        /* Clear buffer before reading into it */

        memset(inbuf, 0, BUFLEN);

        err = MPI_File_read_at(fh, rank * BUFLEN, inbuf, BUFLEN, MPI_BYTE, &st);
        if (err) {
            errs++;
            MTestPrintErrorMsg("Unable to read file", err);
        }

        /* Try to write it (should fail) */
        err = MPI_File_write_at(fh, rank * BUFLEN, outbuf, BUFLEN, MPI_BYTE, &st);
        if (err == MPI_SUCCESS) {
            errs++;
            printf("Write operation succeeded to read-only file\n");
        } else {
            /* Look at error class */
            MPI_Error_class(err, &ec);
            if (ec != MPI_ERR_READ_ONLY && ec != MPI_ERR_ACCESS) {
                errs++;
                printf("Unexpected error class %d when writing to read-only file\n", ec);
                MTestPrintErrorMsg("Error msg is: ", err);
            }
        }
        err = MPI_File_close(&fh);
        if (err) {
            errs++;
            MTestPrintErrorMsg("Failed to close", err);
        }

        /* No MPI_Barrier is required here */

        /*
         *  Test open without CREATE to see if DELETE_ON_CLOSE worked.
         *  This should fail if file was deleted correctly.
         */

        amode = MPI_MODE_RDONLY;
        err = MPI_File_open(MPI_COMM_WORLD, name, amode, MPI_INFO_NULL, &fh);
        if (err == MPI_SUCCESS) {
            errs++;
            printf("File was not deleted!\n");
            MPI_File_close(&fh);
        } else {
            MPI_Error_class(err, &ec);
            if (ec != MPI_ERR_NO_SUCH_FILE && ec != MPI_ERR_IO) {
                errs++;
                printf("Did not return class ERR_NO_SUCH_FILE or ERR_IO\n");
                printf("Returned class %d, message %s\n", ec, emsg);
            }
        }
    }
    /* */

    /* Find out how many errors we saw */
    MTest_Finalize(errs);

    return MTestReturnValue(errs);
}
void dump_rank_info(checkpoint_handle *check, conductance cpl_cef,
		grid_parms grid) {
	MPI_Status status;
	MPI_Offset disp;
	int bytes = 2 * 1024; 			// 2kB space
	char* buffer;
	buffer = (char*) checked_malloc(bytes,
			"allocation for logfile segment space\n");

sprintf(buffer,
			"BRANCH_TAG	=	%d\n[Universal_Rank, Cart_Rank= (%d,%d)] \tcoords= %d,%d\t nbrs: local (u,d,l,r)=(%d %d %d %d) \t "
					"remote: (up1,up2,down1,down2)=(%d %d %d %d)\n\n flip_array: (%d,%d,%d,%d)\n\n"
					"Boundary_tag = %c\n(T = Top\t B= Bottom\t I=Interior edges of the bifurcation segmensts, parent or children\t N=Interior of the subdomain)\n"
					"COUPLING COEFFICIENTS\n"
					"Vm_hm_smc=%2.5lf\nVm_hm_ec=%2.5lf\nCa_hm_smc=%2.5lf\nCa_hm_ec=%2.5lf\nIP3_hm_smc=%2.5lf\n"
					"IP3_hm_ec=%2.5lf\nVm_ht_smc=%2.5lf\nVm_ht_ec=%2.5lf\nCa_ht_smc=%2.5lf\nCa_ht_ec=%2.5lf\n"
					"IP3_ht_smc=%2.5lf\nIP3_ht_ec=%2.5lf\n\n"
					"Spatial Gradient info:\nUniform JPLC\t=%2.5lf\nMinimum JPLC\t=%2.5lf\nMaximum JPLC\t=%2.5lf\nGradient\t=%2.5lf\n"
					"Total Tasks=%d\n"
					"Number of grid points in axial direction =%d\n"
					"Number of grid points in circumferential direction =%d\n"
					"Number of ECs per node (axially) =%d\n"
					"Number of SMCs per node (circumferentially) =%d\n"
					"Total ECs on this node =%d\n"
					"Total SMCs on this node =%d\n"
					"Total number of cells on this node =%d\n"
					"\nTotal ECs in the full computational domain =%d\n"
					"Total SMCs in the full computational domain =%d\n"
					"Total number of cells in the full computational domain =%d\n"
					"Total number of equations in the full computational domain =%d\n "
					"z_coordinates:       start = %lf     end = %lf\n local_z_start = %lf  local_z_end = %lf\n"

					"------------------------------------------------------------------",

			grid.branch_tag, grid.universal_rank, grid.rank, grid.coords[0],
			grid.coords[1], grid.nbrs[local][UP], grid.nbrs[local][DOWN],
			grid.nbrs[local][LEFT], grid.nbrs[local][RIGHT],
			grid.nbrs[remote][UP1], grid.nbrs[remote][UP2],
			grid.nbrs[remote][DOWN1], grid.nbrs[remote][DOWN2],
			grid.flip_array[0], grid.flip_array[1], grid.flip_array[2],
			grid.flip_array[3], grid.my_domain.internal_info.boundary_tag,
			cpl_cef.Vm_hm_smc, cpl_cef.Vm_hm_ec, cpl_cef.Ca_hm_smc,
			cpl_cef.Ca_hm_ec, cpl_cef.IP3_hm_smc, cpl_cef.IP3_hm_ec,
			cpl_cef.Vm_ht_smc, cpl_cef.Vm_ht_ec, cpl_cef.Ca_ht_smc,
			cpl_cef.Ca_ht_ec, cpl_cef.IP3_ht_smc, cpl_cef.IP3_ht_ec,
			grid.uniform_jplc, grid.min_jplc, grid.max_jplc, grid.gradient,
			grid.numtasks,grid.m,grid.n,
			grid.num_ec_axially, grid.num_smc_circumferentially,
			grid.num_ec_axially * grid.num_ec_circumferentially,
			grid.num_smc_axially * grid.num_smc_circumferentially,
			(grid.num_ec_axially * grid.num_ec_circumferentially)
					+ (grid.num_smc_axially * grid.num_smc_circumferentially),
			(grid.num_ec_circumferentially * grid.num_ec_axially * grid.numtasks),
			(grid.num_smc_circumferentially * grid.num_smc_axially
					* grid.numtasks),
			((grid.num_ec_axially * grid.num_ec_circumferentially)
					+ (grid.num_smc_axially * grid.num_smc_circumferentially))
					* grid.numtasks, grid.NEQ * grid.numtasks,
					grid.my_domain.z_offset_start,grid.my_domain.z_offset_end,
					grid.my_domain.local_z_start, grid.my_domain.local_z_end);


	disp	=	grid.rank * bytes;

	CHECK(MPI_File_write_at(check->logptr, disp, buffer, bytes, MPI_CHAR, &status));

}
int main (int argc, char *argv[]) {
	int rank, size;

	MPI_File fh_in, fh_out;
	MPI_Offset offset;
	MPI_Status status;
	MPI_Group origin_group, new_group;
	MPI_Comm custom_world = MPI_COMM_WORLD;

	MPI_Init(&argc, &argv);
	MPI_Comm_size(custom_world, &size);
	MPI_Comm_rank(custom_world, &rank);

	// read command
	if (argc < 4) {
		if (rank == MASTER_RANK) {
			fprintf(stderr, "Insufficient args\n");
			fprintf(stderr, "Usage: %s N input_file output_file", argv[0]);
		}
		return 0;
	}

	const int N = atoi(argv[1]);
	const char *INPUT_NAME = argv[2];
	const char *OUTPUT_NAME = argv[3];

	// Deal with the case where (N < size)
	if (N < size) {
		// obtain the group of proc. in the world communicator
		MPI_Comm_group(custom_world, &origin_group);

		// remove unwanted ranks
		int ranges[][3] = {{N, size-1, 1}};
		MPI_Group_range_excl(origin_group, 1, ranges, &new_group);

		// create a new communicator
		MPI_Comm_create(custom_world, new_group, &custom_world);

		if (custom_world == MPI_COMM_NULL) {
			// terminate those unwanted processes
			MPI_Finalize();
			exit(0);
		}

		size = N;
	}

	// Read file using MPI-IO
	int *local_buf;
	int num_per_node = N / size;
	offset = rank * num_per_node * sizeof(int);

	if (rank == (size - 1)) {
		num_per_node += N % size;
	}

	local_buf = malloc(num_per_node * sizeof(int));

	MPI_File_open(custom_world, INPUT_NAME, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh_in);
	MPI_File_read_at(fh_in, offset, local_buf, num_per_node, MPI_INT, &status);
	MPI_File_close(&fh_in);

	// Odd-even sort
	int sorted = false, all_sorted = false;
	int recv;
	while (!sorted || !all_sorted) {
		sorted = true;
		// local sorting
		int i;
		// odd-phase
		for (i = 1; i < num_per_node; i += 2) {
			if (local_buf[i] < local_buf[i-1]) {
				swap(&local_buf[i], &local_buf[i-1]);
				sorted = false;
			}
		}
		// even-phase
		for (i = 0; i < num_per_node; i += 2) {
			if(i == 0) { continue; }
			if (local_buf[i] < local_buf[i-1]) {
				swap(&local_buf[i], &local_buf[i-1]);
				sorted = false;
			}
		}

		// transportation
		// odd phase
		if (rank % 2) {
			MPI_Send(&local_buf[0], 1, MPI_INT, rank - 1, MSG_RECV, custom_world);
			MPI_Recv(&recv, 1, MPI_INT, rank - 1, MSG_RECV, custom_world, &status);
			if (recv > local_buf[0]) {
				local_buf[0] = recv;
				sorted = false;
			}
		} else if (rank != (size - 1)) {
			MPI_Recv(&recv, 1, MPI_INT, rank + 1, MSG_RECV, custom_world, &status);
			if(recv < local_buf[num_per_node - 1]) {
				swap(&recv, &local_buf[num_per_node - 1]);
				sorted = false;
			}
			MPI_Send(&recv, 1, MPI_INT, rank + 1, MSG_RECV, custom_world);
		}

		// even phase
		if ((rank % 2) == 0 && rank != MASTER_RANK) {
			MPI_Send(&local_buf[0], 1, MPI_INT, rank - 1, MSG_RECV, custom_world);
			MPI_Recv(&recv, 1, MPI_INT, rank - 1, MSG_RECV, custom_world, &status);
			if (recv > local_buf[0]) {
				local_buf[0] = recv;
				sorted = false;
			}
		} else if(rank > MASTER_RANK && rank != (size - 1)) {
			MPI_Recv(&recv, 1, MPI_INT, rank + 1, MSG_RECV, custom_world, &status);
			if(recv < local_buf[num_per_node - 1]) {
				swap(&recv, &local_buf[num_per_node - 1]);
				sorted = false;
			}
			MPI_Send(&recv, 1, MPI_INT, rank + 1, MSG_RECV, custom_world);
		}

		MPI_Allreduce(&sorted, &all_sorted, 1, MPI_INT, MPI_LAND, custom_world);
	}

	// Write file using MPI-IO
	MPI_File_open(custom_world, OUTPUT_NAME, MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh_out);
	MPI_File_write_at(fh_out, offset, local_buf, num_per_node, MPI_INT, &status);
	MPI_File_close(&fh_out);

	free(local_buf);

	MPI_Barrier(custom_world);
	MPI_Finalize();

	return 0;
}
Exemple #17
0
int main( int argc, char *argv[] )
{
    unsigned int itr;

    int operacao;
    int verbose;
    int juntar;
    char * chave_file;
    char * entrada_file;
    char * saida_file;

    octeto Nb,Nk,Nr;
    octeto bloco[4*8];
    octeto chave[4*8*15];

    int worldsize, rank;
    MPI_Status status;
    MPI_File chave_handle;
    MPI_File entrada_handle;
    MPI_File saida_handle;

    MPI_Offset entrada_bytes;
    unsigned int numero_blocos;
    unsigned int blocos_processo;
    MPI_Offset bloco_byte_inicio;
    MPI_Offset bloco_byte_fim;
    MPI_Offset iterador;

    Tabela * tabela;
    octeto * tabelaEmpacotada;
    unsigned int proc;
    unsigned int tamanho_tabela;
    Tabela * tabela2;
    unsigned int no_proc;
    unsigned int no_resto;
    unsigned int i;
    BTreeNode * node;
    Indice * indice;


    MPI_Init(&argc,&argv);

    MPI_Comm_size(MPI_COMM_WORLD,&worldsize);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    operacao = INDEFINIDA;
    verbose = 0;
    juntar = 0;
    chave_file = NULL;
    entrada_file = NULL;
    saida_file = NULL;
    for(itr = 1;itr < (unsigned int)argc;itr++)
    {
/* Instrucoes de uso */
        if( strcmp(argv[itr],"-a") == 0 || strcmp(argv[itr],"--ajuda") == 0 || 
            strcmp(argv[itr],"-h") == 0 || strcmp(argv[itr],"--help") == 0 )
        {
            if(rank == 0)
            {
                printf(" Uso: mpiexec -n [PROCESSOS] ./sm-rijndael [ARGUMENTO VALOR].\n");
                printf(" Encripta/Decripta um arquivo usando o algoritmo Rijndael(AES) extendido,\n");
                printf(" realizando um pre-processamento de blocos repetidos.\n");
                printf("  Argumentos opcionais:\n");
                printf("   -v,--verbose: Exibe mensagens de conclusao da operacao.\n");
                printf("   -j,--juntar: Concatena as tabelas de cada processo em um mestre.\n");
                printf("  Argumentos obrigatorios:\n");
                printf("   -op,--operacao: Informa se o objetivo da execucao eh encriptar ou decriptar.\n");
                printf("                    * Os valores possiveis sao: \'encriptar\' e \'decriptar\'.\n");
                printf("   -e,-i,--entrada,--input: Caminho e nome do arquivo a ser criptografado.\n");
                printf("   -s,-o,--saida,--output: Caminho e nome do arquivo resultante do processo de criptografia da entrada.\n");
                printf("   -c,-k,--chave,--key: Caminho e nome do arquivo contendo a chave.\n");
                printf("  O arquivo contendo a chave eh em formato binario de acordo com a seguinte especificacao:\n");
                printf("   - O primeiro byte deve conter o tamanho do bloco (em palavras de 4 bytes).\n");
                printf("      * O bloco pode possuir tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - O segundo byte deve conter o tamanho da chave (em palavras de 4 bytes).\n");
                printf("      * Esta aplicacao aceita chaves com tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - Os proximos 4*[tamanho da chave] bytes do arquivo sao os bytes componentes da chave, que\n");
                printf("     devem estar (obrigatoriamente) escritos no formato hexadecimal da linguagem C (0xff).\n");
                printf("   * Eh recomendavel o uso de um editor hexadecimal na construcao do arquivo chave.\n");
            }
            goto finalizando;
        }

/* Juntar: Concatena as tabelas de cada processo em um mestre */
        else
        if( strcmp(argv[itr],"-j") == 0 || strcmp(argv[itr],"--juntar") == 0)
        {
            juntar = 1;
        }

/* Verbose: exibir mensagens de finalizacao */
        else
        if( strcmp(argv[itr],"-v") == 0 || strcmp(argv[itr],"--verbose") == 0)
        {
            verbose = 1;
        }

/* Operacao a ser realizada */
        else
        if( strcmp(argv[itr],"-op") == 0 || strcmp(argv[itr],"--operacao") == 0 )
        {
            if( itr+1 < argc )
            {
                if( strcmp(argv[itr+1],"encriptar") == 0 )
                {
                    operacao = ENCRIPTAR;
                }
                else
                if( strcmp(argv[itr+1],"decriptar") == 0 )
                {
                    operacao = DECRIPTAR;
                }
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo com a chave */
        else
        if( strcmp(argv[itr],"-c") == 0 || strcmp(argv[itr],"--chave") == 0 || 
            strcmp(argv[itr],"-k") == 0 || strcmp(argv[itr],"--key") == 0 )
        {
            if(itr+1 < argc)
            {
                chave_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de entrada */
        else
        if( strcmp(argv[itr],"-e") == 0 || strcmp(argv[itr],"--entrada") == 0 || 
            strcmp(argv[itr],"-i") == 0 || strcmp(argv[itr],"--input") == 0 )
        {
            if(itr+1 < argc)
            {
                entrada_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de saida */
        else 
        if( strcmp(argv[itr],"-s") == 0 || strcmp(argv[itr],"--saida") == 0 || 
            strcmp(argv[itr],"-o") == 0 || strcmp(argv[itr],"--output") == 0 )
        {
            if(itr+1 < argc)
            {
                saida_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }
/* Erro desconhecido */
        else
        {
            if(rank == 0)
            {
                printf("Erro nos argumentos passados.\n");
            }
            goto help;
        }
    }
/* Fim da leitura dos argumentos */

    if( operacao == INDEFINIDA || chave_file == NULL || entrada_file == NULL || saida_file == NULL )
    {
        if(rank == 0)
        {
            if( operacao == INDEFINIDA )
                printf("A operacao a ser realizada eh invalida ou nao foi especificada.\n");
            if( chave_file == NULL )
                printf("Esta faltando especificar o arquivo com a chave.\n");
            if( entrada_file == NULL )
                printf("Esta faltando especificar o arquivo de entrada.\n");
            if( saida_file == NULL )
                printf("Esta faltando especificar o arquivo de saida.\n");
        }
        goto help;
    }
/* Fim do tratamento dos argumentos */

    if( MPI_File_open( MPI_COMM_WORLD, chave_file, MPI_MODE_RDONLY, MPI_INFO_NULL, &chave_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nb,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho de um bloco no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nb< 4 || Nb > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de bloco invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nk,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nk< 4 || Nk > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de chave invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,chave,4*Nk,MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    MPI_File_close( &chave_handle );
    Nr = numero_rodadas(Nb,Nk);
    KeyExpansion(chave,Nb,Nk);

    if( MPI_File_open( MPI_COMM_WORLD, entrada_file, 
            MPI_MODE_RDONLY, 
            MPI_INFO_NULL, &entrada_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo de entrada (%s).\n",entrada_file);
        }
        goto help;
    }

    MPI_File_get_size(entrada_handle,&entrada_bytes);


    if( MPI_File_open( MPI_COMM_WORLD, saida_file, 
            MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL, 
            MPI_INFO_NULL, &saida_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na criacao do arquivo de saida (%s).\n",saida_file);
            printf("Uma possivel causa eh que o arquivo ja exista.\n");
        }
        goto help;
    }

    numero_blocos = ( entrada_bytes / (Nb*4) );
    blocos_processo = numero_blocos / worldsize;

    if( operacao == ENCRIPTAR || operacao == DECRIPTAR )
    {
        bloco_byte_inicio = 4*Nb*blocos_processo*rank;
        bloco_byte_fim = 4*Nb*blocos_processo*(rank+1);

        tabela = novaTabela(Nb*4);

        for( iterador = bloco_byte_inicio ; iterador < bloco_byte_fim ; iterador += (4*Nb) )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            novaOcorrenciaTabela(tabela,bloco,iterador);
        }
        
        iterador = 4*Nb*blocos_processo*worldsize + 4*Nb*rank;
        if( iterador < numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            novaOcorrenciaTabela(tabela,bloco,iterador);
        }
        else if( operacao == ENCRIPTAR  &&  iterador == numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }
            bloco[ 4*Nb - 1 ] = (octeto)(entrada_bytes - numero_blocos*4*Nb);
            novaOcorrenciaTabela(tabela,bloco,iterador);
        }


        if( juntar == 1 )
        {
            tabelaEmpacotada = (octeto*)malloc( entrada_bytes );
            if( rank == 0 ) /* Mestre que vai concatenar todas as arvores*/
            {
                for(proc=1;proc<worldsize;proc++)
                {
                    MPI_Recv( tabelaEmpacotada, entrada_bytes, MPI_BYTE, MPI_ANY_SOURCE, TAG_TABELA_EMPACOTADA, MPI_COMM_WORLD, &status );
                    desempacotarInserindo(tabelaEmpacotada,tabela);
                }
                
                tamanho_tabela = numeroBlocosTabela(tabela);

                no_proc = (tamanho_tabela / worldsize);
                no_resto = (tamanho_tabela % worldsize);
                
                tabela2 = novaTabela(Nb*4);
                for(proc=1;proc<worldsize;proc++)
                {
                    for(i=0;i<no_proc;i++)
                    {
                        soInsiraTabela(tabela2, popLastTabelaNode(tabela) );
                    }
                    if( no_resto > 1 )
                    {
                        soInsiraTabela(tabela2, popLastTabelaNode(tabela) );
                        no_resto--;
                    }
                    empacotarTabela(tabela2,tabelaEmpacotada);

                    MPI_Send(tabelaEmpacotada,numeroBytesTabela(tabela2), MPI_BYTE, proc, TAG_TABELA_EMPACOTADA_2, MPI_COMM_WORLD );

                    destruirArvore(tabela2->root);
                    tabela2->root = NULL;
                }
                destruirTabela(tabela2);
            }
            else
            {
                empacotarTabela(tabela,tabelaEmpacotada);
                MPI_Send(tabelaEmpacotada,numeroBytesTabela(tabela), MPI_BYTE, 0, TAG_TABELA_EMPACOTADA, MPI_COMM_WORLD );
                destruirArvore(tabela->root);
                tabela->root = NULL;

                MPI_Recv( tabelaEmpacotada, entrada_bytes, MPI_BYTE, 0, TAG_TABELA_EMPACOTADA_2, MPI_COMM_WORLD, &status );
                desempacotarInserindo(tabelaEmpacotada,tabela);
            }
            free(tabelaEmpacotada);
        }

        if( operacao == ENCRIPTAR )
            MPI_File_set_size(saida_handle,(MPI_Offset)( (numero_blocos+1)*(Nb*4) ) );
        else if( operacao == DECRIPTAR )
            MPI_File_set_size(saida_handle,entrada_bytes);

        tamanho_tabela = numeroBlocosTabela(tabela);
        for( i=0 ; i<tamanho_tabela ; i++ )
        {
            node = popLastTabelaNode(tabela);
//          memcpy (bloco,node->bloco,4*Nb);

            if( operacao == ENCRIPTAR )
                AES_encriptar_bloco(node->bloco,Nb,chave,Nr);
            else if( operacao == DECRIPTAR )
                AES_decriptar_bloco(node->bloco,Nb,chave,Nr);

            indice = node->ocorrencias;
            while( indice != NULL )
            {
                if( MPI_File_write_at(saida_handle,indice->indice,node->bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
                {
                    if( rank == 0 )
                    {
                        printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                    }
                    goto help;
                }
                indice = indice->next;
            }
            destruirArvore(node);
        }
        destruirTabela(tabela);

        if( operacao == DECRIPTAR )
        {
            MPI_Barrier( MPI_COMM_WORLD ); /*Barreira q impede q alguem leia antes do valor decriptografado ser escrito */

            if( MPI_File_read_at(saida_handle,entrada_bytes-1,bloco,1,MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao realizar leitura no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }

            MPI_Barrier( MPI_COMM_WORLD ); /* Barreira q impede q alqum processo trunque o arquivo antes de outro processo ler*/

            MPI_File_set_size(saida_handle,entrada_bytes - 4*Nb + bloco[0]);
        }

        if( rank == 0 && verbose==1)
        {
            if( operacao == ENCRIPTAR )
                printf("A encriptacao do arquivo foi realizada com sucesso.\n");
            else if( operacao == DECRIPTAR )
                printf("A decriptacao do arquivo foi realizada com sucesso.\n");
        }
    }

    goto finalizando;

sempar:
    if( rank == 0 )
    {
        printf("Sem par correspondente para a opcao %s.\n",argv[itr]);
    }

help:
    if( rank == 0 )
    {
        printf("Use a opcao --help para melhor entendimento do uso da aplicacao.\n");
    }

finalizando:
    MPI_Finalize( );
    return 0;
}
Exemple #18
0
void do_ffApply(SEXP ans,
                double *data,
                SEXP margin,
                SEXP function,
                int my_start,
                int my_end,
                int nrows,
                int ncols,
                int worldRank,
                char *out_filename) {

    MPI_Status stat;
    MPI_Comm comm = MPI_COMM_WORLD;
    MPI_File fh;

    SEXP data_chunk, R_fcall, parsedCmd = R_NilValue;
    double *rchunk;
    int i,k, offset=0, count=0;

    /* Open the file handler */
    MPI_File_open(comm, out_filename, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);

    /* The MPI_FILE_SET_VIEW routine changes the process's view of the data in the file */
    MPI_File_set_view(fh, 0, MPI_DOUBLE, MPI_DOUBLE, "native", MPI_INFO_NULL);

    /* Parse the command, returns a function object */
    PROTECT(parsedCmd = parseExpression(function));

    /* Create R LANGSXP Vector, R function holder
      length of the vector is 1 + number of arguments */
    PROTECT(R_fcall = lang2(VECTOR_ELT(parsedCmd, 0), R_NilValue));

    if (INTEGER(margin)[0] == 1) {

        PROTECT(data_chunk = allocVector(REALSXP, ncols));
        rchunk = REAL(data_chunk);

        for(i=my_start, k=0; i<my_end; i++, k++) {

            for(int j=0; j<ncols; j++) {
                rchunk[j] = data[j*nrows+i];
            }

            SETCADR(R_fcall, data_chunk);
            SET_VECTOR_ELT(ans, 0, eval(R_fcall, R_GlobalEnv));

            count = length(VECTOR_ELT(ans, 0));
            offset = i*count;

            MPI_File_write_at(fh, offset, REAL(VECTOR_ELT(ans, 0)), count, MPI_DOUBLE, &stat);

        }
    }

    if (INTEGER(margin)[0] == 2) {

        PROTECT(data_chunk = allocVector(REALSXP, nrows));
        rchunk = REAL(data_chunk);

        for(i=my_start, k=0; i<my_end; i++, k++) {

            for(int j=0; j<nrows; j++) {
                rchunk[j] = data[j+nrows*i];
            }

            SETCADR(R_fcall, data_chunk);
            SET_VECTOR_ELT(ans, 0, eval(R_fcall, R_GlobalEnv));

            count = length(VECTOR_ELT(ans, 0));
            offset = i*count;

            MPI_File_write_at(fh, offset, REAL(VECTOR_ELT(ans, 0)), count, MPI_DOUBLE, &stat);

        }
    }

    /* Close file handler */
    MPI_File_close(&fh);

    return;
}
Exemple #19
0
int main(int argc, char *argv[])
{
    int iarrayOfSizes[2], iarrayOfSubsizes[2], iarrayOfStarts[2], ilocal_size;
    int nproc[2], periods[2], icoord[2];
    int m, n, i, j, wsize, wrank, crank, ndims, lrows, lcols, grow, gcol, err;
    MPI_Datatype filetype;
    MPI_File     fh;
    MPI_Comm     cartcomm;
    MPI_Info     info0, info3;
    double       t, topen, twrite, tclose, wrate;
    double       *local_array;
    char         nstripesStr[12], stripeUnitStr[12];
    int          nstripes = -1;
    int          stripeUnit = -1;
    MPI_Offset   headerSize = 0;

    MPI_Init(0,0);

    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

    /* Get global array size */
    m = n = 128;      /* Set default size */

    /* ioda [ n ] [ m ] [ nstripes ] [ stripeunit ] [ headersize ] */
    if (argc > 0) {
	if (argc > 1) m = atoi(argv[1]);
	if (argc > 2) n = atoi(argv[2]);
	if (argc > 3) nstripes = atoi(argv[3]);
	if (argc > 4) stripeUnit = atoi(argv[4]);
        if (argc > 5) headerSize = atoi(argv[5]);
	if (argc > 6) {
	    if (wrank == 0)
		fprintf(stderr,"Unrecognized argument %s\n", argv[6]);
	    MPI_Abort(MPI_COMM_WORLD,1);
	}
    }
    if (wrank == 0) printf("Matrix is [%d,%d]; file dir = %s\n", m, n, MYSCRATCHDIR );

    /* The default number of stripes = totalsize/1M */
    if (nstripes < 0) {
	nstripes = n * m * sizeof(double) / (1024*1024);
	if (nstripes < 1) nstripes = 1;
    }
    if (wrank == 0) printf("nstripes = %d, stripeUnit = %d, header size = %d\n",
                           nstripes, stripeUnit, (int)headerSize);

    /* Use topology routines to get decomposition and coordinates */
    MPI_Comm_size(MPI_COMM_WORLD, &wsize);
    nproc[0] = 0; nproc[1] = 0;
    ndims = 2;
    MPI_Dims_create(wsize, ndims, nproc);
    periods[0] = 0; periods[1] = 0;
    MPI_Cart_create(MPI_COMM_WORLD, ndims, nproc, periods, 1, &cartcomm);
    MPI_Comm_rank(cartcomm, &crank);
    MPI_Cart_coords(cartcomm, crank, ndims, icoord);

    iarrayOfSizes[0]    = m;
    iarrayOfSizes[1]    = n;
    iarrayOfSubsizes[0] = m/nproc[0];
    iarrayOfSubsizes[1] = n/nproc[1];
    iarrayOfStarts[0]   = icoord[0] * iarrayOfSubsizes[0];
    iarrayOfStarts[1]   = icoord[1] * iarrayOfSubsizes[1];

    /* Initialize my block of the data */
    ilocal_size = iarrayOfSubsizes[0] * iarrayOfSubsizes[1];
    lrows = iarrayOfSubsizes[0];
    lcols = iarrayOfSubsizes[1];
    local_array = (double *)malloc(lrows*lcols*sizeof(double));
    gcol  = iarrayOfStarts[1];
    grow = iarrayOfStarts[0];
    for (i=0; i<lrows; i++) {
	for (j=0; j<lcols; j++) {
	    local_array[j*lrows+i] = (grow+i) + (gcol+j)*m;
	}
    }

    /* Fortran order simply means the data is stored by columns */
    MPI_Type_create_subarray(ndims, iarrayOfSizes, iarrayOfSubsizes,
			     iarrayOfStarts, MPI_ORDER_FORTRAN, MPI_DOUBLE,
			     &filetype);
    MPI_Type_commit(&filetype);

    info0 = MPI_INFO_NULL;
    info3 = MPI_INFO_NULL;
    if (nstripes > 0 || stripeUnit > 0) {
	MPI_Info_create(&info0);
	if (nstripes > 0) {
	    snprintf(nstripesStr, sizeof(nstripesStr), "%d", nstripes);
	    MPI_Info_set(info0, "striping_factor", nstripesStr);
	    MPI_Info_set(info0, "cb_nodes", nstripesStr);
	}
	if (stripeUnit > 0) {
	    snprintf(stripeUnitStr, sizeof(stripeUnitStr), "%d", stripeUnit);
	    MPI_Info_set(info0, "striping_unit", stripeUnitStr);
	}
	MPI_Info_dup(info0, &info3);
	MPI_Info_set(info3, "romio_no_indep_rw", "true");

	/* Other hints to consider:
	   direct_io=true

	   The default cb_buffer_size is 16777216 , but is overridden by the
	   striping unit, which is smaller by default.
	*/
    }

    /* level - 3 */
    MPI_Barrier(MPI_COMM_WORLD);
    t = MPI_Wtime();
    err = MPI_File_open(cartcomm, MYSCRATCHDIR "testfile-3.out",
			MPI_MODE_CREATE | MPI_MODE_RDWR, info3, &fh);
    topen = MPI_Wtime() - t;
    if (err != MPI_SUCCESS) myAbort(err, "open testfile-3.out");

    if (headerSize > 0) {
        /* Simulate writing a header */
        if (wrank == 0) {
	    char *header;
            header = (char *)calloc(1,(size_t)headerSize);
            MPI_File_write(fh, header, headerSize, MPI_BYTE, MPI_STATUS_IGNORE);
            free(header);
        }
        MPI_Barrier(cartcomm);
    }

    MPI_File_set_view(fh, headerSize, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL);

    MPI_Barrier(MPI_COMM_WORLD);
    t = MPI_Wtime();
    err = MPI_File_write_all(fh, local_array, ilocal_size, MPI_DOUBLE,
			     MPI_STATUS_IGNORE);
    twrite = MPI_Wtime() - t;
    if (err != MPI_SUCCESS) myAbort(err, "collective write");

    err = MPI_File_close(&fh);
    tclose = MPI_Wtime() - t;
    /* tclose is the time for the write(s) + the close, in case the
       implementation delays (some of) the writes until the close */
    if (err != MPI_SUCCESS) myAbort(err, "close testfile-3.out");

    MPI_Allreduce(MPI_IN_PLACE, &topen, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    MPI_Allreduce(MPI_IN_PLACE, &twrite, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    MPI_Allreduce(MPI_IN_PLACE, &tclose, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    if (twrite > 0)
	wrate = (double)m * (double)n * sizeof(double)/twrite;
    if (wrank == 0)
	printf("%d\t[%d,%d]\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n", wsize, m, n, nstripes, topen,
	       twrite, tclose, wrate);

    /* level - 0 */
    MPI_Barrier(MPI_COMM_WORLD);
    t = MPI_Wtime();
    err = MPI_File_open(cartcomm, MYSCRATCHDIR "testfile-0.out",
			MPI_MODE_CREATE | MPI_MODE_RDWR, info0, &fh);
    topen = MPI_Wtime() - t;
    if (err != MPI_SUCCESS) myAbort(err, "open testfile-0.out");

    if (headerSize > 0) {
        /* Simulate writing a header */
        if (wrank == 0) {
	    char *header;
            header = (char *)calloc(1,(size_t)headerSize);
            MPI_File_write(fh, header, headerSize, MPI_BYTE, MPI_STATUS_IGNORE);
            free(header);
        }
        MPI_Barrier(cartcomm);
    }

    MPI_Barrier(MPI_COMM_WORLD);
    t = MPI_Wtime();
    gcol = iarrayOfStarts[1];
    grow = iarrayOfStarts[0];
    for (j=0; j<lcols; j++) {
	MPI_Offset offset = headerSize +
	    ((MPI_Offset)(grow) + (MPI_Offset)(gcol+j)*m) * sizeof(double);
	err = MPI_File_write_at(fh, offset, local_array+j*lrows, lrows, MPI_DOUBLE,
				MPI_STATUS_IGNORE);
	if (err != MPI_SUCCESS) myAbort(err, "write at");
    }
    twrite = MPI_Wtime() - t;

    err = MPI_File_close(&fh);
    tclose = MPI_Wtime() - t;
    /* tclose is the time for the write(s) + the close, in case the
       implementation delays (some of) the writes until the close */
    if (err != MPI_SUCCESS) myAbort(err, "close testfile-0");

    MPI_Allreduce(MPI_IN_PLACE, &topen, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    MPI_Allreduce(MPI_IN_PLACE, &twrite, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    MPI_Allreduce(MPI_IN_PLACE, &tclose, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
    if (twrite > 0)
	wrate = (double)m * (double)n * sizeof(double)/twrite;
    if (wrank == 0)
	printf("%d\t[%d,%d]\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n", wsize, m, n, nstripes, topen,
	       twrite, tclose, wrate);

    if (info0 != MPI_INFO_NULL) {
	MPI_Info_free(&info0);
	MPI_Info_free(&info3);
    }
    free(local_array);
    MPI_Finalize();
    return 0;
}
Exemple #20
0
int main(int argc, char **argv)
{
    char *buf, *tmp, *buf2, *tmp2, *check;
    int i, j, mynod=0, nprocs=1, err, my_correct = 1, correct, myerrno;
    double stim, etim;
    double write_tim = 0;
    double read_tim = 0;
    double read_bw, write_bw;
    double max_read_tim, max_write_tim;
    double min_read_tim, min_write_tim;
    double ave_read_tim, ave_write_tim;
    int64_t iter_jump = 0;
    int64_t seek_position = 0;
    MPI_File fh;
    MPI_Status status;
    int nchars;

    /* startup MPI and determine the rank of this process */
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &mynod);

    /* parse the command line arguments */
    parse_args(argc, argv);

    if (mynod == 0) printf("# Using mpi-io calls.\n");


    /* kindof a weird hack- if the location of the pvfstab file was
     * specified on the command line, then spit out this location into
     * the appropriate environment variable: */

#if H5_HAVE_SETENV
/* no setenv or unsetenv */
    if (opt_pvfstab_set) {
            if((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0){
                    perror("setenv");
                    goto die_jar_jar_die;
            }
    }
#endif

    /* this is how much of the file data is covered on each iteration of
     * the test.  used to help determine the seek offset on each
     * iteration */
    iter_jump = nprocs * opt_block;

    /* setup a buffer of data to write */
    if (!(tmp = (char *) malloc(opt_block + 256))) {
            perror("malloc");
            goto die_jar_jar_die;
    }
    buf = tmp + 128 - (((long)tmp) % 128);  /* align buffer */

    if (opt_correct) {
            /* do the same buffer setup for verifiable data */
            if (!(tmp2 = (char *) malloc(opt_block + 256))) {
                    perror("malloc2");
                    goto die_jar_jar_die;
             }
            buf2 = tmp + 128 - (((long)tmp) % 128);
    }

    /* open the file for writing */
    err = MPI_File_open(MPI_COMM_WORLD, opt_file,
    MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
    if (err < 0) {
            fprintf(stderr, "node %d, open error: %s\n", mynod, strerror(errno));
            goto die_jar_jar_die;
    }

    /* now repeat the write operations the number of times
     * specified on the command line */
    for (j=0; j < opt_iter; j++) {

            /* calculate the appropriate position depending on the iteration
             * and rank of the current process */
            seek_position = (j*iter_jump)+(mynod*opt_block);

            if (opt_correct) /* fill in buffer for iteration */ {
                    for (i=mynod+j, check=buf; i<opt_block; i++,check++) *check=(char)i;
            }

            /* discover the starting time of the operation */
       MPI_Barrier(MPI_COMM_WORLD);
       stim = MPI_Wtime();

            /* write out the data */
            nchars = opt_block/sizeof(char);
            err = MPI_File_write_at(fh, seek_position, buf, nchars, MPI_CHAR, &status);
            if(err){
                    fprintf(stderr, "node %d, write error: %s\n", mynod,
                    strerror(errno));
            }

            /* discover the ending time of the operation */
       etim = MPI_Wtime();

       write_tim += (etim - stim);

            /* we are done with this "write" iteration */
    }

    err = MPI_File_close(&fh);
    if(err){
            fprintf(stderr, "node %d, close error after write\n", mynod);
    }

    /* wait for everyone to synchronize at this point */
    MPI_Barrier(MPI_COMM_WORLD);

    /* reopen the file to read the data back out */
    err = MPI_File_open(MPI_COMM_WORLD, opt_file,
    MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
    if (err < 0) {
            fprintf(stderr, "node %d, open error: %s\n", mynod, strerror(errno));
            goto die_jar_jar_die;
    }


    /* we are going to repeat the read operation the number of iterations
     * specified */
    for (j=0; j < opt_iter; j++) {
            /* calculate the appropriate spot give the current iteration and
             * rank within the MPI processes */
            seek_position = (j*iter_jump)+(mynod*opt_block);

            /* discover the start time */
       MPI_Barrier(MPI_COMM_WORLD);
       stim = MPI_Wtime();

            /* read in the file data */
            if (!opt_correct){
                    err = MPI_File_read_at(fh, seek_position, buf, nchars, MPI_CHAR, &status);
            }
            else{
                    err = MPI_File_read_at(fh, seek_position, buf2, nchars, MPI_CHAR, &status);
            }
            myerrno = errno;

            /* discover the end time */
       etim = MPI_Wtime();
       read_tim += (etim - stim);

       if (err < 0) fprintf(stderr, "node %d, read error, loc = %Ld: %s\n",
                    mynod, mynod*opt_block, strerror(myerrno));

            /* if the user wanted to check correctness, compare the write
             * buffer to the read buffer */
            if (opt_correct && memcmp(buf, buf2, opt_block)) {
                    fprintf(stderr, "node %d, correctness test failed\n", mynod);
                    my_correct = 0;
                    MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN,
                            MPI_COMM_WORLD);
            }

            /* we are done with this read iteration */
    }

    /* close the file */
    err = MPI_File_close(&fh);
    if(err){
            fprintf(stderr, "node %d, close error after write\n", mynod);
    }

    /* compute the read and write times */
    MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX,
            MPI_COMM_WORLD);
    MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN,
            MPI_COMM_WORLD);
    MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM,
            MPI_COMM_WORLD);

    /* calculate the average from the sum */
    ave_read_tim = ave_read_tim / nprocs;

    MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX,
            MPI_COMM_WORLD);
    MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN,
            MPI_COMM_WORLD);
    MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM,
            MPI_COMM_WORLD);

    /* calculate the average from the sum */
    ave_write_tim = ave_write_tim / nprocs;

    /* print out the results on one node */
    if (mynod == 0) {
       read_bw = ((int64_t)(opt_block*nprocs*opt_iter))/(max_read_tim*1000000.0);
       write_bw = ((int64_t)(opt_block*nprocs*opt_iter))/(max_write_tim*1000000.0);

                    printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs,
            opt_iter, (long)opt_block);

                    printf("# total_size = %ld\n", (long)(opt_block*nprocs*opt_iter));

                    printf("# Write:  min_time = %f, max_time = %f, mean_time = %f\n",
                            min_write_tim, max_write_tim, ave_write_tim);
                    printf("# Read:  min_time = %f, max_time = %f, mean_time = %f\n",
                            min_read_tim, max_read_tim, ave_read_tim);

       printf("Write bandwidth = %f Mbytes/sec\n", write_bw);
       printf("Read bandwidth = %f Mbytes/sec\n", read_bw);

            if (opt_correct) {
                    printf("Correctness test %s.\n", correct ? "passed" : "failed");
            }
    }


die_jar_jar_die:

#if H5_HAVE_SETENV
/* no setenv or unsetenv */
    /* clear the environment variable if it was set earlier */
    if	(opt_pvfstab_set){
            unsetenv("PVFSTAB_FILE");
    }
#endif

    free(tmp);
    if (opt_correct) free(tmp2);
    MPI_Finalize();
    return(0);
}
Exemple #21
0
static int write_read_samples(PIDX_file_io_id io_id, int variable_index, uint64_t hz_start_index, uint64_t hz_count, unsigned char* hz_buffer, int64_t buffer_offset, PIDX_block_layout layout, int MODE)
{
  int samples_per_file, block_number, file_index, file_count, ret = 0, block_negative_offset = 0, file_number;
  int bytes_per_sample, bytes_per_datatype;
  int i = 0;
  char file_name[PATH_MAX];
  off_t data_offset = 0;

  samples_per_file = io_id->idx_d->samples_per_block * io_id->idx->blocks_per_file;

  bytes_per_datatype = (io_id->idx->variable[variable_index]->bits_per_value / 8) * (io_id->idx->chunk_size[0] * io_id->idx->chunk_size[1] * io_id->idx->chunk_size[2] * io_id->idx->chunk_size[3] * io_id->idx->chunk_size[4]) / (io_id->idx->compression_factor);
  
#if !SIMULATE_IO
  hz_buffer = hz_buffer + buffer_offset * bytes_per_datatype * io_id->idx->variable[variable_index]->values_per_sample;
#endif
  
  while (hz_count) 
  {
    block_number = hz_start_index / io_id->idx_d->samples_per_block;
    file_number = hz_start_index / samples_per_file;
    file_index = hz_start_index % samples_per_file;
    file_count = samples_per_file - file_index;
    
    if ((int64_t)file_count > hz_count)
      file_count = hz_count;

    // build file name
    int adjusted_file_index = 0;
    int l = pow(2, ((int)log2((unsigned int) file_number * io_id->idx->blocks_per_file)));
    adjusted_file_index = (l * (io_id->idx_d->idx_count[0] * io_id->idx_d->idx_count[1] * io_id->idx_d->idx_count[2]) + (((unsigned int) file_number * io_id->idx->blocks_per_file) - l) + (io_id->idx_d->color * l)) / io_id->idx->blocks_per_file;

    ret = generate_file_name(io_id->idx->blocks_per_file, io_id->idx->filename_template, /*file_number*/adjusted_file_index, file_name, PATH_MAX);
    if (ret == 1)
    {
      fprintf(stderr, "[%s] [%d] generate_file_name() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }

    data_offset = 0;
    bytes_per_sample = io_id->idx->variable[variable_index]->bits_per_value / 8;
    data_offset = file_index * bytes_per_sample * io_id->idx->variable[variable_index]->values_per_sample;
    data_offset += io_id->idx_d->start_fs_block * io_id->idx_d->fs_block_size;

    block_negative_offset = PIDX_blocks_find_negative_offset(io_id->idx->blocks_per_file, block_number, layout);
      
    data_offset -= block_negative_offset * io_id->idx_d->samples_per_block * bytes_per_sample * io_id->idx->variable[variable_index]->values_per_sample;
      
    for (l = 0; l < variable_index; l++) 
    {
      bytes_per_sample = io_id->idx->variable[l]->bits_per_value / 8;
      for (i = 0; i < io_id->idx->blocks_per_file; i++)
        if (PIDX_blocks_is_block_present((i + (io_id->idx->blocks_per_file * file_number)), layout))
          data_offset = data_offset + (io_id->idx->variable[l]->values_per_sample * bytes_per_sample * io_id->idx_d->samples_per_block);
    }
    
    if(MODE == PIDX_WRITE)
    {
#if !SIMULATE_IO
#if PIDX_HAVE_MPI

#ifdef PIDX_DUMP_IO
      if (io_id->idx_d->dump_io_info == 1 && io_id->idx->current_time_step == 0)
      {
        fprintf(io_dump_fp, "[A] Count %lld Target Disp %d (%d %d)\n", (long long)file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), (file_index * bytes_per_sample * io_id->idx->variable[variable_index]->values_per_sample - block_negative_offset * io_id->idx_d->samples_per_block * bytes_per_sample * io_id->idx->variable[variable_index]->values_per_sample)/8, (int)io_id->idx_d->start_fs_block, (int)io_id->idx_d->fs_block_size);
        fflush(io_dump_fp);
      }
#endif

      if (io_id->idx_d->parallel_mode == 1)
      {
        int rank = 0;
        MPI_Comm_rank(io_id->comm, &rank);
        MPI_File fh;
        MPI_Status status;
        int mpi_ret;
        mpi_ret = MPI_File_open(MPI_COMM_SELF, file_name, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        if (mpi_ret != MPI_SUCCESS)
        {
          fprintf(stderr, "[%s] [%d] MPI_File_open() failed. (%s) [%d]\n", __FILE__, __LINE__, file_name, file_number);
          return PIDX_err_io;
        }

        /*
        printf("[%d] Data Offset %d Count %d\n", rank, data_offset, (file_count));
        int x = 0;
        for (x = 0; x < file_count; x++)
        {
          double x1;
          memcpy(&x1, hz_buffer + x * sizeof(double), sizeof(double));
          printf("Values %d %f\n", x, x1);
        }
        */

        mpi_ret = MPI_File_write_at(fh, data_offset, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), MPI_BYTE, &status);
        if (mpi_ret != MPI_SUCCESS)
        {
          fprintf(stderr, "[%s] [%d] MPI_File_open() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }

        int write_count;
        MPI_Get_count(&status, MPI_BYTE, &write_count);
        if (write_count != file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8))
        {
          fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }
        MPI_File_close(&fh);
      }
      else
      {
        int fh;
        fh = open(file_name, O_WRONLY);
        ssize_t write_count = pwrite(fh, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), data_offset);
        if (write_count != file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8))
        {
          fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }
        close(fh);
      }
#else
      int fh;
      fh = open(file_name, O_WRONLY);
      /*
      double x1, x2, x3, x4;
      memcpy(&x1, hz_buffer, sizeof(double));
      memcpy(&x2, hz_buffer + sizeof(double), sizeof(double));
      memcpy(&x3, hz_buffer + 2*sizeof(double), sizeof(double));
      memcpy(&x4, hz_buffer + 3*sizeof(double), sizeof(double));
      printf("[%d] [%d %d] Values %f %f %f %f\n", variable_index, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), data_offset, x1, x2, x3, x4);
      */
      ssize_t write_count = pwrite(fh, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), data_offset);
      if (write_count != file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8))
      {
        fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }
      close(fh);
#endif
#endif
    }
    if(MODE == PIDX_READ)
    {
#if PIDX_HAVE_MPI
      if (io_id->idx_d->parallel_mode == 1)
      {
        MPI_File fh;
        MPI_Status status;
        int mpi_ret;
        mpi_ret = MPI_File_open(MPI_COMM_SELF, file_name, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
        if (mpi_ret != MPI_SUCCESS)
        {
          fprintf(stderr, "[%s] [%d] MPI_File_open() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }

        mpi_ret = MPI_File_read_at(fh, data_offset, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), MPI_BYTE, &status);
        if (mpi_ret != MPI_SUCCESS)
        {
          fprintf(stderr, "[%s] [%d] MPI_File_open() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }

        MPI_File_close(&fh);
      }
      else
      {
        int fh;
        fh = open(file_name, O_RDONLY);
        ssize_t read_count = pread(fh, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), data_offset);
        if (read_count != file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8))
        {
          fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }
        close(fh);
      }
#else
      int fh;
      fh = open(file_name, O_RDONLY);
      ssize_t read_count = pread(fh, hz_buffer, file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8), data_offset);
      if (read_count != file_count * io_id->idx->variable[variable_index]->values_per_sample * (io_id->idx->variable[variable_index]->bits_per_value/8))
      {
        fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }
      close(fh);
#endif
    }

    hz_count -= file_count;
    hz_start_index += file_count;
    hz_buffer += file_count * io_id->idx->variable[variable_index]->values_per_sample * bytes_per_datatype;

#if PIDX_HAVE_MPI

#else

#endif

  }
  return PIDX_success;
}
Exemple #22
0
/*
 * sweep_access_size
 *
 * read and write from file using various access sizes that
 * fall into the 10 buckets.
 *
 * mpi-io
 * mpi contiguous data type
 * shared file
 */
int sweep_access_size(char *path, int size, int rank)
{
    MPI_File fh;
    MPI_Offset offset;
    MPI_Datatype dt;
    MPI_Status status;
    int rc;
    int blksize;
    int pblksize;
    int count;
    void* buf;
    char filepath[512];

    sprintf(filepath, "%s/%s", path, "access_sweep");

    rc = MPI_File_open(MPI_COMM_WORLD, filepath,
                   (MPI_MODE_CREATE|MPI_MODE_RDWR|MPI_MODE_DELETE_ON_CLOSE),
                       MPI_INFO_NULL,
                       &fh);
    MPI_CHECK(rc,"MPI_File_open");

    for (pblksize=0,count=6,blksize=(((int)pow(2,count))+1);
         count <= 30;
         count++,pblksize=blksize,blksize=(((int)pow(2,count))+1))
    {
        int test;

        rc = MPI_Type_contiguous(blksize, MPI_BYTE, &dt);
        MPI_CHECK(rc,"MPI_Type_contiguous");

        rc = MPI_Type_commit(&dt);
        MPI_CHECK(rc,"MPI_Type_commit");

        buf = malloc(blksize);
        if (!buf) { return 0; }

        offset = ((MPI_Offset)pblksize*(MPI_Offset)size)+
                 ((MPI_Offset)rank*(MPI_Offset)blksize);

        rc = MPI_File_write_at(fh, offset, buf, 1, dt, &status);
        MPI_CHECK(rc,"MPI_File_write_at");

        MPI_Barrier(MPI_COMM_WORLD);

        offset = ((MPI_Offset)pblksize*(MPI_Offset)size)+
                 ((MPI_Offset)((rank+1)%size)*(MPI_Offset)blksize);

        rc = MPI_File_read_at(fh, offset, buf, 1, dt, &status);
        MPI_CHECK(rc,"MPI_File_read_at");

        rc = MPI_Type_free(&dt);
        MPI_CHECK(rc,"MPI_Type_free");

        free(buf);
    }

    rc = MPI_File_close(&fh);
    MPI_CHECK(rc,"MPI_File_close");

    return 1; 
}
Exemple #23
0
int main(int argc, char** argv) {
  MPI_Init(&argc, &argv);

  setup_globals();

  /* Parse arguments. */
  int SCALE = 16;
  int edgefactor = 16; /* nedges / nvertices, i.e., 2*avg. degree */
  // if (argc >= 2) SCALE = atoi(argv[1]);
  // if (argc >= 3) edgefactor = atoi(argv[2]);
  char* name = argv[1];
  if (argc >= 3) SCALE = atoi(argv[2]);
  if (argc >= 4) edgefactor = atoi(argv[3]);
  // if (argc <= 1 || argc >= 4 || SCALE == 0 || edgefactor == 0) {
  //   if (rank == 0) {
  //     fprintf(stderr, "Usage: %s SCALE edgefactor\n  SCALE = log_2(# vertices) [integer, required]\n  edgefactor = (# edges) / (# vertices) = .5 * (average vertex degree) [integer, defaults to 16]\n(Random number seed and Kronecker initiator are in main.c)\n", argv[0]);
  //   }
  if (argc <= 2 || argc >= 5 || SCALE == 0 || edgefactor == 0) {
    if (rank == 0) {
      fprintf(stderr, "Usage: %s filename SCALE edgefactor\n  SCALE = log_2(# vertices) [integer, required]\n  edgefactor = (# edges) / (# vertices) = .5 * (average vertex degree) [integer, defaults to 16]\n(Random number seed and Kronecker initiator are in main.c)\n", argv[0]);
    }
    MPI_Abort(MPI_COMM_WORLD, 1);
  }
  uint64_t seed1 = 2, seed2 = 3;

  // const char* filename = getenv("TMPFILE");
  const char* filename = name;

  /* If filename is NULL, store data in memory */

  tuple_graph tg;
  tg.nglobaledges = (int64_t)(edgefactor) << SCALE;
  int64_t nglobalverts = (int64_t)(1) << SCALE;

  tg.data_in_file = (filename != NULL);

  if (tg.data_in_file) {
      printf("data in file \n");

    MPI_File_set_errhandler(MPI_FILE_NULL, MPI_ERRORS_ARE_FATAL);
    // MPI_File_open(MPI_COMM_WORLD, (char*)filename, MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &tg.edgefile);
    MPI_File_open(MPI_COMM_WORLD, (char*)filename, MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &tg.edgefile);
    MPI_File_set_size(tg.edgefile, tg.nglobaledges * sizeof(packed_edge));
    MPI_File_set_view(tg.edgefile, 0, packed_edge_mpi_type, packed_edge_mpi_type, "native", MPI_INFO_NULL);
    MPI_File_set_atomicity(tg.edgefile, 0);
  }

  /* Make the raw graph edges. */
  /* Get roots for BFS runs, plus maximum vertex with non-zero degree (used by
   * validator). */
  int num_bfs_roots = 64;
  int64_t* bfs_roots = (int64_t*)xmalloc(num_bfs_roots * sizeof(int64_t));
  int64_t max_used_vertex = 0;

  double make_graph_start = MPI_Wtime();
  {
    /* Spread the two 64-bit numbers into five nonzero values in the correct
     * range. */
    uint_fast32_t seed[5];
    make_mrg_seed(seed1, seed2, seed);

    /* As the graph is being generated, also keep a bitmap of vertices with
     * incident edges.  We keep a grid of processes, each row of which has a
     * separate copy of the bitmap (distributed among the processes in the
     * row), and then do an allreduce at the end.  This scheme is used to avoid
     * non-local communication and reading the file separately just to find BFS
     * roots. */
    MPI_Offset nchunks_in_file = (tg.nglobaledges + FILE_CHUNKSIZE - 1) / FILE_CHUNKSIZE;
    int64_t bitmap_size_in_bytes = int64_min(BITMAPSIZE, (nglobalverts + CHAR_BIT - 1) / CHAR_BIT);
    if (bitmap_size_in_bytes * size * CHAR_BIT < nglobalverts) {
      bitmap_size_in_bytes = (nglobalverts + size * CHAR_BIT - 1) / (size * CHAR_BIT);
    }
    int ranks_per_row = ((nglobalverts + CHAR_BIT - 1) / CHAR_BIT + bitmap_size_in_bytes - 1) / bitmap_size_in_bytes;
    int nrows = size / ranks_per_row;
    int my_row = -1, my_col = -1;
    unsigned char* restrict has_edge = NULL;
    MPI_Comm cart_comm;
    {
      int dims[2] = {size / ranks_per_row, ranks_per_row};
      int periods[2] = {0, 0};
      MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 1, &cart_comm);
    }
    int in_generating_rectangle = 0;
    if (cart_comm != MPI_COMM_NULL) {
      in_generating_rectangle = 1;
      {
        int dims[2], periods[2], coords[2];
        MPI_Cart_get(cart_comm, 2, dims, periods, coords);
        my_row = coords[0];
        my_col = coords[1];
      }
      MPI_Comm this_col;
      MPI_Comm_split(cart_comm, my_col, my_row, &this_col);
      MPI_Comm_free(&cart_comm);
      has_edge = (unsigned char*)xMPI_Alloc_mem(bitmap_size_in_bytes);
      memset(has_edge, 0, bitmap_size_in_bytes);
      /* Every rank in a given row creates the same vertices (for updating the
       * bitmap); only one writes them to the file (or final memory buffer). */
      packed_edge* buf = (packed_edge*)xmalloc(FILE_CHUNKSIZE * sizeof(packed_edge));
      MPI_Offset block_limit = (nchunks_in_file + nrows - 1) / nrows;
      // fprintf(stderr, "%d: nchunks_in_file = %" PRId64 ", block_limit = %" PRId64 " in grid of %d rows, %d cols\n", rank, (int64_t)nchunks_in_file, (int64_t)block_limit, nrows, ranks_per_row);
      if (tg.data_in_file) {
        tg.edgememory_size = 0;
        tg.edgememory = NULL;
      } else {
        int my_pos = my_row + my_col * nrows;
        int last_pos = (tg.nglobaledges % ((int64_t)FILE_CHUNKSIZE * nrows * ranks_per_row) != 0) ?
                       (tg.nglobaledges / FILE_CHUNKSIZE) % (nrows * ranks_per_row) :
                       -1;
        int64_t edges_left = tg.nglobaledges % FILE_CHUNKSIZE;
        int64_t nedges = FILE_CHUNKSIZE * (tg.nglobaledges / ((int64_t)FILE_CHUNKSIZE * nrows * ranks_per_row)) +
                         FILE_CHUNKSIZE * (my_pos < (tg.nglobaledges / FILE_CHUNKSIZE) % (nrows * ranks_per_row)) +
                         (my_pos == last_pos ? edges_left : 0);
        /* fprintf(stderr, "%d: nedges = %" PRId64 " of %" PRId64 "\n", rank, (int64_t)nedges, (int64_t)tg.nglobaledges); */
        tg.edgememory_size = nedges;
        tg.edgememory = (packed_edge*)xmalloc(nedges * sizeof(packed_edge));
      }
      MPI_Offset block_idx;
      for (block_idx = 0; block_idx < block_limit; ++block_idx) {
        /* fprintf(stderr, "%d: On block %d of %d\n", rank, (int)block_idx, (int)block_limit); */
        MPI_Offset start_edge_index = int64_min(FILE_CHUNKSIZE * (block_idx * nrows + my_row), tg.nglobaledges);
        MPI_Offset edge_count = int64_min(tg.nglobaledges - start_edge_index, FILE_CHUNKSIZE);
        packed_edge* actual_buf = (!tg.data_in_file && block_idx % ranks_per_row == my_col) ?
                                  tg.edgememory + FILE_CHUNKSIZE * (block_idx / ranks_per_row) :
                                  buf;
        /* fprintf(stderr, "%d: My range is [%" PRId64 ", %" PRId64 ") %swriting into index %" PRId64 "\n", rank, (int64_t)start_edge_index, (int64_t)(start_edge_index + edge_count), (my_col == (block_idx % ranks_per_row)) ? "" : "not ", (int64_t)(FILE_CHUNKSIZE * (block_idx / ranks_per_row))); */
        if (!tg.data_in_file && block_idx % ranks_per_row == my_col) {
          assert (FILE_CHUNKSIZE * (block_idx / ranks_per_row) + edge_count <= tg.edgememory_size);
        }

	// debug
	char* wtxbuf = (char*)xmalloc(FILE_CHUNKSIZE * sizeof(packed_edge));

        // generate_kronecker_range(seed, SCALE, start_edge_index, start_edge_index + edge_count, actual_buf);
        generate_kronecker_range(seed, SCALE, start_edge_index, start_edge_index + edge_count, actual_buf);
        if (tg.data_in_file && my_col == (block_idx % ranks_per_row)) { /* Try to spread writes among ranks */
          // MPI_File_write_at(tg.edgefile, start_edge_index, actual_buf, edge_count, packed_edge_mpi_type, MPI_STATUS_IGNORE);


	    // debug
	    printf("%d: %d, %d\n", rank, start_edge_index, edge_count);
	    int i;
	    // for (i = start_edge_index; i < start_edge_index + 3; i++) {
	    // if(block_idx == 0) {
	    // 	for (i = 0; i < 3; i++) {
	    // 	    if (edge_count > 3)
	    // 		printf("%d: %d\t%d\n", rank, actual_buf[i].v0, actual_buf[i].v1);
	    // 	}

	    // }

	    
	    

          MPI_File_write_at(tg.edgefile, start_edge_index, actual_buf, edge_count, packed_edge_mpi_type, MPI_STATUS_IGNORE);
        }
        ptrdiff_t i;
#ifdef _OPENMP
#pragma omp parallel for
#endif
        for (i = 0; i < edge_count; ++i) {
          int64_t src = get_v0_from_edge(&actual_buf[i]);
          int64_t tgt = get_v1_from_edge(&actual_buf[i]);
          if (src == tgt) continue;
          if (src / bitmap_size_in_bytes / CHAR_BIT == my_col) {
#ifdef _OPENMP
#pragma omp atomic
#endif
            has_edge[(src / CHAR_BIT) % bitmap_size_in_bytes] |= (1 << (src % CHAR_BIT));
          }
          if (tgt / bitmap_size_in_bytes / CHAR_BIT == my_col) {
#ifdef _OPENMP
#pragma omp atomic
#endif
            has_edge[(tgt / CHAR_BIT) % bitmap_size_in_bytes] |= (1 << (tgt % CHAR_BIT));
          }
        }
      }
      free(buf);
#if 0
      /* The allreduce for each root acts like we did this: */
      MPI_Allreduce(MPI_IN_PLACE, has_edge, bitmap_size_in_bytes, MPI_UNSIGNED_CHAR, MPI_BOR, this_col);
#endif
      MPI_Comm_free(&this_col);
    } else {
      tg.edgememory = NULL;
      tg.edgememory_size = 0;
    }
    MPI_Allreduce(&tg.edgememory_size, &tg.max_edgememory_size, 1, MPI_INT64_T, MPI_MAX, MPI_COMM_WORLD);

#ifndef GEN_ONLY
    /* Find roots and max used vertex */
    {
      uint64_t counter = 0;
      int bfs_root_idx;
      for (bfs_root_idx = 0; bfs_root_idx < num_bfs_roots; ++bfs_root_idx) {
        int64_t root;
        while (1) {
          double d[2];
          make_random_numbers(2, seed1, seed2, counter, d);
          root = (int64_t)((d[0] + d[1]) * nglobalverts) % nglobalverts;
          counter += 2;
          if (counter > 2 * nglobalverts) break;
          int is_duplicate = 0;
          int i;
          for (i = 0; i < bfs_root_idx; ++i) {
            if (root == bfs_roots[i]) {
              is_duplicate = 1;
              break;
            }
          }
          if (is_duplicate) continue; /* Everyone takes the same path here */
          int root_ok = 0;
          if (in_generating_rectangle && (root / CHAR_BIT / bitmap_size_in_bytes) == my_col) {
            root_ok = (has_edge[(root / CHAR_BIT) % bitmap_size_in_bytes] & (1 << (root % CHAR_BIT))) != 0;
          }
          MPI_Allreduce(MPI_IN_PLACE, &root_ok, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
          if (root_ok) break;
        }
        bfs_roots[bfs_root_idx] = root;
      }
      num_bfs_roots = bfs_root_idx;

      /* Find maximum non-zero-degree vertex. */
      {
        int64_t i;
        max_used_vertex = 0;
        if (in_generating_rectangle) {
          for (i = bitmap_size_in_bytes * CHAR_BIT; i > 0; --i) {
            if (i > nglobalverts) continue;
            if (has_edge[(i - 1) / CHAR_BIT] & (1 << ((i - 1) % CHAR_BIT))) {
              max_used_vertex = (i - 1) + my_col * CHAR_BIT * bitmap_size_in_bytes;
              break;
            }
          }
        }
        MPI_Allreduce(MPI_IN_PLACE, &max_used_vertex, 1, MPI_INT64_T, MPI_MAX, MPI_COMM_WORLD);
      }
    }
#endif

    if (in_generating_rectangle) {
      MPI_Free_mem(has_edge);
    }
    if (tg.data_in_file) {
      MPI_File_sync(tg.edgefile);
    }
  }

  double make_graph_stop = MPI_Wtime();
  double make_graph_time = make_graph_stop - make_graph_start;
  if (rank == 0) { /* Not an official part of the results */
    fprintf(stderr, "graph_generation:               %f s\n", make_graph_time);
  }


  //debug
#ifndef GEN_ONLY //!GEN_ONLY

  /* Make user's graph data structure. */
  double data_struct_start = MPI_Wtime();
  make_graph_data_structure(&tg);
  double data_struct_stop = MPI_Wtime();
  double data_struct_time = data_struct_stop - data_struct_start;
  if (rank == 0) { /* Not an official part of the results */
    fprintf(stderr, "construction_time:              %f s\n", data_struct_time);
  }

  /* Number of edges visited in each BFS; a double so get_statistics can be
   * used directly. */
  double* edge_counts = (double*)xmalloc(num_bfs_roots * sizeof(double));

  /* Run BFS. */
  int validation_passed = 1;
  double* bfs_times = (double*)xmalloc(num_bfs_roots * sizeof(double));
  double* validate_times = (double*)xmalloc(num_bfs_roots * sizeof(double));
  uint64_t nlocalverts = get_nlocalverts_for_pred();
  int64_t* pred = (int64_t*)xMPI_Alloc_mem(nlocalverts * sizeof(int64_t));

  int bfs_root_idx;
  for (bfs_root_idx = 0; bfs_root_idx < num_bfs_roots; ++bfs_root_idx) {
    int64_t root = bfs_roots[bfs_root_idx];

    if (rank == 0) fprintf(stderr, "Running BFS %d\n", bfs_root_idx);

    /* Clear the pred array. */
    memset(pred, 0, nlocalverts * sizeof(int64_t));

    /* Do the actual BFS. */
    double bfs_start = MPI_Wtime();
    run_bfs(root, &pred[0]);
    double bfs_stop = MPI_Wtime();
    bfs_times[bfs_root_idx] = bfs_stop - bfs_start;
    if (rank == 0) fprintf(stderr, "Time for BFS %d is %f\n", bfs_root_idx, bfs_times[bfs_root_idx]);

    /* Validate result. */
    if (rank == 0) fprintf(stderr, "Validating BFS %d\n", bfs_root_idx);

    double validate_start = MPI_Wtime();
    int64_t edge_visit_count;
    int validation_passed_one = validate_bfs_result(&tg, max_used_vertex + 1, nlocalverts, root, pred, &edge_visit_count);
    double validate_stop = MPI_Wtime();
    validate_times[bfs_root_idx] = validate_stop - validate_start;
    if (rank == 0) fprintf(stderr, "Validate time for BFS %d is %f\n", bfs_root_idx, validate_times[bfs_root_idx]);
    edge_counts[bfs_root_idx] = (double)edge_visit_count;
    if (rank == 0) fprintf(stderr, "TEPS for BFS %d is %g\n", bfs_root_idx, edge_visit_count / bfs_times[bfs_root_idx]);

    if (!validation_passed_one) {
      validation_passed = 0;
      if (rank == 0) fprintf(stderr, "Validation failed for this BFS root; skipping rest.\n");
      break;
    }
  }

  MPI_Free_mem(pred);
  free(bfs_roots);
  free_graph_data_structure();

#endif //!GEN_ONLY

  if (tg.data_in_file) {
    MPI_File_close(&tg.edgefile);
  } else {
    free(tg.edgememory); tg.edgememory = NULL;
  }

#ifndef GEN_ONLY
  /* Print results. */
  if (rank == 0) {
    if (!validation_passed) {
      fprintf(stdout, "No results printed for invalid run.\n");
    } else {
      int i;
      fprintf(stdout, "SCALE:                          %d\n", SCALE);
      fprintf(stdout, "edgefactor:                     %d\n", edgefactor);
      fprintf(stdout, "NBFS:                           %d\n", num_bfs_roots);
      fprintf(stdout, "graph_generation:               %g\n", make_graph_time);
      fprintf(stdout, "num_mpi_processes:              %d\n", size);
      fprintf(stdout, "construction_time:              %g\n", data_struct_time);
      double stats[s_LAST];
      get_statistics(bfs_times, num_bfs_roots, stats);
      fprintf(stdout, "min_time:                       %g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_time:             %g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_time:                    %g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_time:             %g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_time:                       %g\n", stats[s_maximum]);
      fprintf(stdout, "mean_time:                      %g\n", stats[s_mean]);
      fprintf(stdout, "stddev_time:                    %g\n", stats[s_std]);
      get_statistics(edge_counts, num_bfs_roots, stats);
      fprintf(stdout, "min_nedge:                      %.11g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_nedge:            %.11g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_nedge:                   %.11g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_nedge:            %.11g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_nedge:                      %.11g\n", stats[s_maximum]);
      fprintf(stdout, "mean_nedge:                     %.11g\n", stats[s_mean]);
      fprintf(stdout, "stddev_nedge:                   %.11g\n", stats[s_std]);
      double* secs_per_edge = (double*)xmalloc(num_bfs_roots * sizeof(double));
      for (i = 0; i < num_bfs_roots; ++i) secs_per_edge[i] = bfs_times[i] / edge_counts[i];
      get_statistics(secs_per_edge, num_bfs_roots, stats);
      fprintf(stdout, "min_TEPS:                       %g\n", 1. / stats[s_maximum]);
      fprintf(stdout, "firstquartile_TEPS:             %g\n", 1. / stats[s_thirdquartile]);
      fprintf(stdout, "median_TEPS:                    %g\n", 1. / stats[s_median]);
      fprintf(stdout, "thirdquartile_TEPS:             %g\n", 1. / stats[s_firstquartile]);
      fprintf(stdout, "max_TEPS:                       %g\n", 1. / stats[s_minimum]);
      fprintf(stdout, "harmonic_mean_TEPS:             %g\n", 1. / stats[s_mean]);
      /* Formula from:
       * Title: The Standard Errors of the Geometric and Harmonic Means and
       *        Their Application to Index Numbers
       * Author(s): Nilan Norris
       * Source: The Annals of Mathematical Statistics, Vol. 11, No. 4 (Dec., 1940), pp. 445-448
       * Publisher(s): Institute of Mathematical Statistics
       * Stable URL: http://www.jstor.org/stable/2235723
       * (same source as in specification). */
      fprintf(stdout, "harmonic_stddev_TEPS:           %g\n", stats[s_std] / (stats[s_mean] * stats[s_mean] * sqrt(num_bfs_roots - 1)));
      free(secs_per_edge); secs_per_edge = NULL;
      free(edge_counts); edge_counts = NULL;
      get_statistics(validate_times, num_bfs_roots, stats);
      fprintf(stdout, "min_validate:                   %g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_validate:         %g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_validate:                %g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_validate:         %g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_validate:                   %g\n", stats[s_maximum]);
      fprintf(stdout, "mean_validate:                  %g\n", stats[s_mean]);
      fprintf(stdout, "stddev_validate:                %g\n", stats[s_std]);
#if 0
      for (i = 0; i < num_bfs_roots; ++i) {
        fprintf(stdout, "Run %3d:                        %g s, validation %g s\n", i + 1, bfs_times[i], validate_times[i]);
      }
#endif
    }
  }
  free(bfs_times);
  free(validate_times);

#endif
  cleanup_globals();
  MPI_Finalize();
  return 0;
}
Exemple #24
0
int PIDX_aggregated_io(PIDX_file_io_id io_id, Agg_buffer agg_buf, PIDX_block_layout block_layout, int MODE)
{
  int64_t data_offset = 0;  
  char file_name[PATH_MAX];
  int i = 0, k = 0;
  uint32_t *headers;
  int total_header_size = 0;
#ifdef PIDX_RECORD_TIME
  double t1, t2, t3, t4, t5;
#endif

#if PIDX_HAVE_MPI
  int mpi_ret;
  MPI_File fh;
  MPI_Status status;
#else
  int fh;
#endif

  int total_chunk_size = (io_id->idx->chunk_size[0] * io_id->idx->chunk_size[1] * io_id->idx->chunk_size[2] * io_id->idx->chunk_size[3] * io_id->idx->chunk_size[4]);

  if (enable_caching == 1 && agg_buf->var_number == io_id->init_index && agg_buf->sample_number == 0)
  {
#ifdef PIDX_RECORD_TIME
    t1 = PIDX_get_time();
#endif

    int adjusted_file_index = 0;
    int l = pow(2, ((int)log2((unsigned int) agg_buf->file_number * io_id->idx->blocks_per_file)));
    adjusted_file_index = (l * (io_id->idx_d->idx_count[0] * io_id->idx_d->idx_count[1] * io_id->idx_d->idx_count[2]) + (((unsigned int) agg_buf->file_number * io_id->idx->blocks_per_file) - l) + (io_id->idx_d->color * l)) / io_id->idx->blocks_per_file;

    generate_file_name(io_id->idx->blocks_per_file, io_id->idx->filename_template, (unsigned int) /*agg_buf->file_number*/adjusted_file_index, file_name, PATH_MAX);

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    mpi_ret = MPI_File_open(MPI_COMM_SELF, file_name, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    if (mpi_ret != MPI_SUCCESS)
    {
      fprintf(stderr, "[%s] [%d] MPI_File_open() failed filename %s.\n", __FILE__, __LINE__, file_name);
      return PIDX_err_io;
    }
#else
    fh = open(file_name, O_WRONLY);
#endif
#endif

#ifdef PIDX_RECORD_TIME
    t2 = PIDX_get_time();
#endif

    data_offset = 0;
    total_header_size = (10 + (10 * io_id->idx->blocks_per_file)) * sizeof (uint32_t) * io_id->idx->variable_count;
    headers = (uint32_t*)malloc(total_header_size);
    memset(headers, 0, total_header_size);

#if !SIMULATE_IO
    if (enable_caching == 1)
      memcpy (headers, cached_header_copy, total_header_size);
    else
    {
      //TODO
    }
#endif

#ifdef PIDX_RECORD_TIME
    t3 = PIDX_get_time();
#endif

    uint64_t header_size = (io_id->idx_d->start_fs_block * io_id->idx_d->fs_block_size);

#if !SIMULATE_IO
    unsigned char* temp_buffer = (unsigned char*)realloc(agg_buf->buffer, agg_buf->buffer_size  + header_size);
    if (temp_buffer == NULL)
    {
      fprintf(stderr, "[%s] [%d] realloc() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }
    else
    {
      agg_buf->buffer = temp_buffer;
      memmove(agg_buf->buffer + header_size, agg_buf->buffer, agg_buf->buffer_size);
      memcpy(agg_buf->buffer, headers, total_header_size);
      memset(agg_buf->buffer + total_header_size, 0, (header_size - total_header_size));
    }
#endif
    free(headers);

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    mpi_ret = MPI_File_write_at(fh, 0, agg_buf->buffer, agg_buf->buffer_size + header_size, MPI_BYTE, &status);
    if (mpi_ret != MPI_SUCCESS)
    {
      fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed for filename %s.\n", __FILE__, __LINE__, file_name);
      return PIDX_err_io;
    }

    int write_count;
    MPI_Get_count(&status, MPI_BYTE, &write_count);
    if (write_count != agg_buf->buffer_size + header_size)
    {
      fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }

#else
    ssize_t write_count = pwrite(fh, agg_buf->buffer, agg_buf->buffer_size + header_size, 0);
    if (write_count != agg_buf->buffer_size + header_size)
    {
      fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }
#endif
#endif

#ifdef PIDX_RECORD_TIME
    t4 = PIDX_get_time();
#endif

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    mpi_ret = MPI_File_close(&fh);
    if (mpi_ret != MPI_SUCCESS)
    {
      fprintf(stderr, "[%s] [%d] MPI_File_open() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }
#else
    close(fh);
#endif
#endif

#ifdef PIDX_RECORD_TIME
    t5 = PIDX_get_time();
#endif

#ifdef PIDX_RECORD_TIME
    printf("V0. [R %d] [O 0 C %lld] [FVS %d %d %d] Time: O %f H %f W %f C %f\n", rank, (long long)agg_buf->buffer_size + header_size, agg_buf->file_number, agg_buf->var_number, agg_buf->sample_number, (t2-t1), (t3-t2), (t4-t3), (t5-t4));
#else
#endif
  }
  else if (agg_buf->var_number != -1 && agg_buf->sample_number != -1 && agg_buf->file_number != -1)
  {
#ifdef PIDX_RECORD_TIME
    t1 = PIDX_get_time();
#endif

    int adjusted_file_index = 0;
    int l = pow(2, ((int)log2((unsigned int) agg_buf->file_number * io_id->idx->blocks_per_file)));
    adjusted_file_index = (l * (io_id->idx_d->idx_count[0] * io_id->idx_d->idx_count[1] * io_id->idx_d->idx_count[2]) + (((unsigned int) agg_buf->file_number * io_id->idx->blocks_per_file) - l) + (io_id->idx_d->color * l)) / io_id->idx->blocks_per_file;

    generate_file_name(io_id->idx->blocks_per_file, io_id->idx->filename_template, (unsigned int) adjusted_file_index/*agg_buf->file_number*/, file_name, PATH_MAX);

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    if (MODE == PIDX_WRITE)
    {
      mpi_ret = MPI_File_open(MPI_COMM_SELF, file_name, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
      if (mpi_ret != MPI_SUCCESS)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_open() filename %s failed.\n", __FILE__, __LINE__, file_name);
        return PIDX_err_io;
      }
    }
    else
    {
      mpi_ret = MPI_File_open(MPI_COMM_SELF, file_name, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
      if (mpi_ret != MPI_SUCCESS)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_open() filename %s failed.\n", __FILE__, __LINE__, file_name);
        return PIDX_err_io;
      }
    }
#else
    if (MODE == PIDX_WRITE)
      fh = open(file_name, O_WRONLY);
    else
      fh = open(file_name, O_RDONLY);
#endif
#endif

 #ifdef PIDX_RECORD_TIME
    t2 = PIDX_get_time();
#endif

    data_offset = 0;
    data_offset += io_id->idx_d->start_fs_block * io_id->idx_d->fs_block_size;

    if (MODE == PIDX_WRITE)
    {
      for (k = 0; k < agg_buf->var_number; k++)
      {
        PIDX_variable vark = io_id->idx->variable[k];
        int bytes_per_datatype =  ((vark->bits_per_value/8) * total_chunk_size) / (io_id->idx->compression_factor);
        int64_t prev_var_sample = (int64_t) block_layout->block_count_per_file[agg_buf->file_number] * io_id->idx_d->samples_per_block * bytes_per_datatype * io_id->idx->variable[k]->values_per_sample;

        data_offset = (int64_t) data_offset + prev_var_sample;
      }

      for (i = 0; i < agg_buf->sample_number; i++)
        data_offset = (int64_t) data_offset + agg_buf->buffer_size;
    }
    else
    {
      int total_header_size = (10 + (10 * io_id->idx->blocks_per_file)) * sizeof (uint32_t) * io_id->idx->variable_count;
      headers = malloc(total_header_size);
      memset(headers, 0, total_header_size);

  #if PIDX_HAVE_MPI
      mpi_ret = MPI_File_read_at(fh, 0, headers, total_header_size , MPI_BYTE, &status);
      if (mpi_ret != MPI_SUCCESS)
      {
        fprintf(stderr, "Data offset = %lld [%s] [%d] MPI_File_write_at() failed for filename %s.\n", (long long)  data_offset, __FILE__, __LINE__, file_name);
        return PIDX_err_io;
      }
  #endif
    }

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    if (MODE == PIDX_WRITE)
    {
      //int rank;
      //MPI_Comm_rank(io_id->comm, &rank);
      //printf("W [%d] [%d %d %d] size = %d and offset = %d\n", rank, agg_buf->file_number, agg_buf->var_number, agg_buf->sample_number, agg_buf->buffer_size, data_offset);
      mpi_ret = MPI_File_write_at(fh, data_offset, agg_buf->buffer, agg_buf->buffer_size , MPI_BYTE, &status);
      if (mpi_ret != MPI_SUCCESS)
      {
        fprintf(stderr, "Data offset = %lld [%s] [%d] MPI_File_write_at() failed for filename %s.\n", (long long)  data_offset, __FILE__, __LINE__, file_name);
        return PIDX_err_io;
      }

      int write_count = 0;
      MPI_Get_count(&status, MPI_BYTE, &write_count);
      if (write_count != agg_buf->buffer_size)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }
    }
    else
    {
      int data_size = 0;
      int block_count = 0;
      for (i = 0; i < io_id->idx->blocks_per_file; i++)
      {
        if (PIDX_blocks_is_block_present(agg_buf->file_number * io_id->idx->blocks_per_file + i, block_layout))
        {
          data_offset = htonl(headers[12 + ((i + (io_id->idx->blocks_per_file * agg_buf->var_number))*10 )]);
          data_size = htonl(headers[14 + ((i + (io_id->idx->blocks_per_file * agg_buf->var_number))*10 )]);

          mpi_ret = MPI_File_read_at(fh, data_offset, agg_buf->buffer + (block_count * io_id->idx_d->samples_per_block * (io_id->idx->variable[agg_buf->var_number]->bits_per_value/8) * io_id->idx->variable[agg_buf->var_number]->values_per_sample * io_id->idx->chunk_size[0] * io_id->idx->chunk_size[1] * io_id->idx->chunk_size[2]) / io_id->idx->compression_factor, /*agg_buf->buffer_size*/data_size , MPI_BYTE, &status);
          if (mpi_ret != MPI_SUCCESS)
          {
            fprintf(stderr, "Data offset = %lld [%s] [%d] MPI_File_write_at() failed for filename %s.\n", (long long)  data_offset, __FILE__, __LINE__, file_name);
            return PIDX_err_io;
          }

          int read_count = 0;
          MPI_Get_count(&status, MPI_BYTE, &read_count);
          if (read_count != /*agg_buf->buffer_size*/data_size)
          {
            fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed. %d != %lldd\n", __FILE__, __LINE__, read_count, (long long)agg_buf->buffer_size);
            return PIDX_err_io;
          }
          block_count++;
        }
      }
      free(headers);
    }

#else
    if (MODE == PIDX_WRITE)
    {
      ssize_t write_count = pwrite(fh, agg_buf->buffer, agg_buf->buffer_size, data_offset);
      if (write_count != agg_buf->buffer_size)
      {
        fprintf(stderr, "[%s] [%d] pwrite() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }
    }
    else
    {
      ssize_t read_count = pread(fh, agg_buf->buffer, agg_buf->buffer_size, data_offset);
      if (read_count != agg_buf->buffer_size)
      {
        fprintf(stderr, "[%s] [%d] pread() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }

    }
#endif
#endif

#ifdef PIDX_RECORD_TIME
    t3 = PIDX_get_time();
#endif

#if !SIMULATE_IO
#if PIDX_HAVE_MPI
    mpi_ret = MPI_File_close(&fh);
    if (mpi_ret != MPI_SUCCESS)
    {
      fprintf(stderr, "[%s] [%d] MPI_File_open() failed.\n", __FILE__, __LINE__);
      return PIDX_err_io;
    }
#else
    close(fh);
#endif
#endif

#ifdef PIDX_RECORD_TIME
    t4 = PIDX_get_time();
#endif

#ifdef PIDX_RECORD_TIME
    printf("V. [R %d] [O %lld C %lld] [FVS %d %d %d] Time: O %f H %f W %f C %f\n", rank, (long long) data_offset, (long long)agg_buf->buffer_size, agg_buf->file_number, agg_buf->var_number, agg_buf->sample_number, (t2-t1), (t2-t2), (t3-t2), (t4-t3));
#endif
  }

  return PIDX_success;
}
Exemple #25
0
static void writePLY(
        MPI_Comm comm, std::string fname,
        int nvertices, int nverticesPerObject,
        int ntriangles, int ntrianglesPerObject,
        int nObjects,
        const std::vector<int3>& mesh,
        const std::vector<float3>& vertices)
{
    int rank;
    MPI_Check( MPI_Comm_rank(comm, &rank) );

    int totalVerts = 0;
    MPI_Check( MPI_Reduce(&nvertices, &totalVerts, 1, MPI_INT, MPI_SUM, 0, comm) );

    int totalTriangles = 0;
    MPI_Check( MPI_Reduce(&ntriangles, &totalTriangles, 1, MPI_INT, MPI_SUM, 0, comm) );

    MPI_File f;
    MPI_Check( MPI_File_open(comm, fname.c_str(), MPI_MODE_CREATE|MPI_MODE_DELETE_ON_CLOSE|MPI_MODE_WRONLY, MPI_INFO_NULL, &f) );
    MPI_Check( MPI_File_close(&f) );
    MPI_Check( MPI_File_open(comm, fname.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &f) );

    int headerSize = 0;
    MPI_Offset fileOffset = 0;

    if (rank == 0)
    {
        std::stringstream ss;

        ss <<  "ply\n";
        ss <<  "format binary_little_endian 1.0\n";
        ss <<  "element vertex " << totalVerts << "\n";
        ss <<  "property float x\nproperty float y\nproperty float z\n";
        //ss <<  "property float xnormal\nproperty float ynormal\nproperty float znormal\n";
        ss <<  "element face " << totalTriangles << "\n";
        ss <<  "property list int int vertex_index\n";
        ss <<  "end_header\n";

        std::string content = ss.str();
        headerSize = content.length();
        MPI_Check( MPI_File_write_at(f, fileOffset, content.c_str(), headerSize, MPI_CHAR, MPI_STATUS_IGNORE) );
    }

    MPI_Check( MPI_Bcast(&headerSize, 1, MPI_INT, 0, comm) );

    fileOffset += headerSize;
    
    fileOffset += writeToMPI(vertices, f, fileOffset, comm);

    int verticesOffset = 0;
    MPI_Check( MPI_Exscan(&nvertices, &verticesOffset, 1, MPI_INT, MPI_SUM, comm));

    std::vector<int4> connectivity;
    for(int j = 0; j < nObjects; ++j)
        for(int i = 0; i < ntrianglesPerObject; ++i)
        {
            int3 vertIds = mesh[i] + nverticesPerObject * j + verticesOffset;
            connectivity.push_back({3, vertIds.x, vertIds.y, vertIds.z});
        }

    fileOffset += writeToMPI(connectivity, f, fileOffset, comm);

    MPI_Check( MPI_File_close(&f));
}
Exemple #26
0
int main(int argc, char * argv[])
{
    int i;
    int ret;
    MPI_File file;
    MPI_Status status;
    char * filename = "tokufs:/hellobasicmpiio";

    MPI_Init(&argc, &argv);

    ret = MPI_File_open(MPI_COMM_WORLD, filename,
            MPI_MODE_CREATE | MPI_MODE_RDWR,
            MPI_INFO_NULL, &file);
    printf("open ret = %d\n", ret);
    if (ret != MPI_SUCCESS) {
        char * estr = malloc(1000);
        int l;
        MPI_Error_string(ret, estr, &l);
        printf("%s\n", estr);
        free(estr);
    }
    assert(ret == MPI_SUCCESS);

    /* Generate the usual 0-99 repeating buffer */
    char write_buf[BUF_SIZE];
    for (i = 0; i < BUF_SIZE; i++) {
        write_buf[i] = i % 100;
    }

    /* Write to the file as 10 seperate chunks with explicit offsets. */
    int num_chunks = 10;
    assert(BUF_SIZE % num_chunks == 0);
    int write_size = BUF_SIZE / num_chunks;
    for (i = 0; i < 10; i++) {
        ret = MPI_File_write_at(file, i * write_size,
                write_buf + i * write_size,
                write_size, MPI_CHAR, &status);
        assert(ret == MPI_SUCCESS);
    }

    /* Close the file and open it again */
    ret = MPI_File_close(&file);
    assert(ret == MPI_SUCCESS);
    ret = MPI_File_open(MPI_COMM_WORLD, filename, 
            MPI_MODE_EXCL | MPI_MODE_RDWR,
            MPI_INFO_NULL, &file);
    assert(ret == MPI_SUCCESS);

    /* Read back the file in a similar fashion, into a new buffer. */
    char read_buf[BUF_SIZE];
    int read_size = write_size;
    for (i = 0; i < 10; i++) {
        ret = MPI_File_read_at(file, i * read_size,
                read_buf + i * read_size,
                read_size, MPI_CHAR, &status);
        assert(ret == MPI_SUCCESS);
    }
    
    /* Verify the read buf is the same as the write buf */
    for (i = 0; i < BUF_SIZE; i++) {
        if (read_buf[i] != write_buf[i]) {
            printf("%s:%s: buf[%d]: expected %d, got %d\n",
                    __FILE__, __FUNCTION__,
                    i, write_buf[i], read_buf[i]);
        }
        assert(read_buf[i] == write_buf[i]);
    }

    ret = MPI_File_close(&file);
    assert(ret == 0);
    ret = MPI_Finalize();
    assert(ret == 0);

    return 0;
}
int main(int argc, char *argv[]) {
	if(argc != 5) {
		printf("ERROR: Not enough arguments.\n");
		return EXIT_FAILURE;
	}

	// Example MPI startup and using CLCG4 RNG
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &mpi_commsize);
	MPI_Comm_rank(MPI_COMM_WORLD, &mpi_myrank);

	// assign cli args to globals
	g_matrix_size = atoi(argv[1]);
	g_threads = atoi(argv[2]);
	g_file_ranks = atoi(argv[3]);
	g_out = argv[4];
	g_row_size = g_matrix_size / mpi_commsize;

	// Init 16,384 RNG streams - each rank has an independent stream
	InitDefault();

	MPI_Barrier(MPI_COMM_WORLD);

	// my_matrix stores a local slice of the 128gb matrix
	// my_transpose stores the transpose of that slice
	my_matrix = calloc(g_row_size * g_matrix_size, sizeof(unsigned int));
	my_transpose = calloc(g_row_size * g_matrix_size, sizeof(unsigned int));

	// initialize and randomize matrix thru mpi ranks
	// each rank holds some number of rows
	// held in a 1d array to make mpi sending easier
	unsigned int i, j, k, l;
	for(i = 0; i < g_row_size; ++i) {
		for(j = 0; j < g_matrix_size; ++j) {
			my_matrix[i * g_matrix_size + j] = (unsigned int)(GenVal(mpi_myrank) * 100.0) + 1;
		}
	}

	// populate transpose with own values
	unsigned int start_idx = mpi_myrank * g_row_size;
	for(i = 0; i < g_row_size; ++i) {
		for(j = start_idx; j < g_row_size * g_matrix_size; j = j + g_matrix_size) {
			// calculation for the matrix
			k = (j - start_idx) / g_matrix_size + start_idx;
			my_transpose[i + j] = my_matrix[i * g_matrix_size + k];
		}
	}

	// initialize and allocate buffers
	unsigned int bufsize = g_row_size * g_row_size;
	unsigned int *sendbuf = calloc(bufsize, sizeof(unsigned int *));
	unsigned int **recvbuf = calloc(mpi_commsize-1, sizeof(unsigned int *));
	for(i = 0; i < mpi_commsize-1; ++i) {
		recvbuf[i] = calloc(bufsize, sizeof(unsigned int));
	}

	// mpi stuff
	unsigned int num_reqs = 2 * (mpi_commsize - 1);
	unsigned int cur_req = 0;
	MPI_Request *requests = (MPI_Request *)malloc(num_reqs * sizeof(MPI_Request));
	MPI_Status *statuses = (MPI_Status *)malloc(num_reqs * sizeof(MPI_Status));

	// send to all other ranks
	for(i = 0; i < mpi_commsize; ++i) {
		if(i != mpi_myrank) {
			// store relevant data for the receiving rank
			int cnt = 0;
			int tx = 0;
			start_idx = i * g_row_size;
			for(j = 0; j < g_row_size; ++j) {
				for(k = start_idx; k < g_row_size * g_matrix_size; k = k + g_matrix_size) {
					// calculation for the matrix (a little messy, could be optimized)
					l = (k - start_idx) / g_matrix_size + start_idx;
					if(cnt >= bufsize) {
						// handles the overflow, after which we offset it (new column)
						cnt = ++tx;
					}
					sendbuf[cnt] = my_matrix[j * g_matrix_size + l];
					cnt += g_row_size;
				}
			}
			MPI_Isend(sendbuf, bufsize, MPI_UNSIGNED, i, 0, MPI_COMM_WORLD, &requests[cur_req++]);
		}
	}

	// recv from all other rows
	// handling a little messy since irecv is nonblocking
	int cnt = 0;
	for(i = 0; i < mpi_commsize; ++i) {
		if(i != mpi_myrank) {
			MPI_Irecv(recvbuf[cnt++], bufsize, MPI_UNSIGNED, i, 0, MPI_COMM_WORLD, &requests[cur_req++]);
		}
	}

	// wait on MPI messages
	MPI_Waitall(num_reqs, requests, statuses);

	// store relevant values
	k = 0;
	l = 0;
	for(i = 0; i < g_row_size; ++i) {
		for(j = 0; j < g_matrix_size; ++j) {
			if(my_transpose[i * g_matrix_size + j] == 0) {
				my_transpose[i * g_matrix_size + j] = recvbuf[k][l++];
				if(l >= bufsize) {
					k++;
					l = 0;
				}
			}
		}
	}

	MPI_Barrier(MPI_COMM_WORLD);
	
	unsigned long long t1 = 0, t2 = 0;
	if(mpi_myrank == 0) {
		t1 = GetTimeBase();
	}

	// split into pthreads
	pthread_t *call_thd;
	call_thd = (pthread_t *)malloc(g_threads * sizeof(pthread_t));
	void *status;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	pthread_mutex_init(&mutexsum, NULL);

	long x;
	for(x = 0; x < g_threads; ++x) {
		pthread_create(&call_thd[i], &attr, mtx_sum, (void *)x);
	}

	// wait on threads
	for(x = 0; x < g_threads; ++x) {
		pthread_join(call_thd[i], &status);
	}

	MPI_Barrier(MPI_COMM_WORLD);

	if(mpi_myrank == 0) {
		t2 = GetTimeBase();
		float tmp = (t2-t1) / 1600000;
		printf("Elapsed compute time: %f\n", tmp);
	}

	// I/O
	if(mpi_myrank == 0) {
		t1 = GetTimeBase();
	}
	MPI_Offset offset = (mpi_myrank % g_file_ranks) * g_row_size * g_matrix_size * sizeof(unsigned int);
	MPI_File file;
	MPI_Status iostatus;
	MPI_Datatype localarray;

	/* create a type describing our piece of the array */
	int globalsizes[2] = {g_matrix_size, g_matrix_size};
	int localsizes [2] = {g_row_size, g_matrix_size};
	int starts[2]      = {mpi_myrank * g_row_size, 0};
	int order          = MPI_ORDER_C;
	MPI_Type_create_subarray(2, globalsizes, localsizes, starts, order, MPI_UNSIGNED, &localarray);
	MPI_Type_commit(&localarray);

	// open the file, and set the view
	MPI_File_open(MPI_COMM_WORLD, g_out,
			MPI_MODE_CREATE|MPI_MODE_WRONLY,
			MPI_INFO_NULL, &file);
	MPI_File_set_view(file, 0,  MPI_UNSIGNED, localarray, "native", MPI_INFO_NULL);

	// write to file at specified offset
	MPI_File_write_at(file, offset * mpi_myrank, my_matrix, g_row_size * g_matrix_size, MPI_UNSIGNED, &iostatus);
	MPI_File_close(&file);
	
	MPI_Barrier(MPI_COMM_WORLD);
	if(mpi_myrank == 0) {
		t2 = GetTimeBase();
		float tmp = (t2-t1) / 1600000;
		printf("Elapsed IO time: %f\n", tmp);
	}

	// cleanup routine

	MPI_Type_free(&localarray);

	pthread_attr_destroy(&attr);
	pthread_mutex_destroy(&mutexsum);
	free(call_thd);

	free(my_matrix);
	free(my_transpose);

	for(i = 0; i < mpi_commsize-1; ++i) free(recvbuf[i]);
	free(recvbuf);
	free(sendbuf);
	free(requests);
	free(statuses);

	// END -Perform a barrier and then leave MPI
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Finalize();
	return EXIT_SUCCESS;
}
Exemple #28
0
// this is currently slower than it could be because we write in chunks (data.size()..) with barriers in between - instead we could take care of correct format of matrix on the read-in side and write everything at once, or assume same format of data and only do one barrier
void Storage::SaveDataFloatMPIBin(char* filename, vector<vector<float> > data, int mpiRank, int mpiSize, MPI_Comm comm)
{
	MPI_File fh;
	// assumes specific data distribution for processes

	MPI_File_delete(filename,MPI_INFO_NULL);
	MPI_File_open(comm,filename,MPI_MODE_RDWR|MPI_MODE_CREATE,MPI_INFO_NULL,&fh);
	int globalOffset = 0;

	// (!) Currently assumes same size of all items in data
	int size = 0;
	for(int i=0;i<data.size();i++) // assumes same nr items each process
	{
		size+= data[i].size();
	}

	vector<float> tempData(size);
	int index=0;
	for(int i=0;i<data.size();i++) // assumes same nr items each process
	{
		for(int j=0;j<data[i].size();j++)
		{
			tempData[index] = data[i][j];
			index++;
		}
	}

	vector<int> allSizes(mpiSize);
	MPI_Allgather(&size,1,MPI_INT,&allSizes[0],1,MPI_INT,comm);
	int startPos = 0;
	for(int j=0;j<mpiRank;j++)
		startPos+=allSizes[j];

	//for(int i=0;i<data.size();i++) // assumes same nr items each process
	//{
	//	/*int size = data[i].size(); // each item can be of different size
	//	vector<int> allSizes(mpiSize);
	//	MPI_Allgather(&size,1,MPI_INT,&allSizes[0],1,MPI_INT,comm);
	//	int startPos = 0;
	//	for(int j=0;j<mpiRank;j++)
	//		startPos+=allSizes[j];*/

	//	MPI_Status status;
	//	MPI_File_write_at(fh,(startPos+globalOffset)*sizeof(MPI_FLOAT),&data[i][0],data[i].size(),MPI_FLOAT,&status);
	//	//if(i==0)
	//	//MPI_File_write_at(fh,(startPos+globalStartPos),&data[i][0],data[i].size(),MPI_FLOAT,&status);

	//	for(int j=0;j<mpiSize;j++)
	//		globalOffset+=allSizes[j];
	//	//globalOffset = 0;
	//	//for(int j=mpiRank;j<mpiSize;j++)
	//	//	globalOffset+=allSizes[j];
	//}

	MPI_Status status;
	if(size>0)
		MPI_File_write_at(fh,(startPos+globalOffset)*sizeof(MPI_FLOAT),&tempData[0],size,MPI_FLOAT,&status);//&data[0][0],size,MPI_FLOAT,&status);
		//MPI_File_write_at(fh,(startPos+globalOffset)*sizeof(MPI_FLOAT),&data[0][0],size,MPI_FLOAT,&status);
	
	MPI_File_close(&fh);
}
Exemple #29
0
static int populate_meta_data(PIDX_header_io_id header_io_id, PIDX_block_layout block_layout, int file_number, char* bin_file, int mode)
{
  int block_negative_offset = 0;
  int i = 0, j = 0, k = 0, all_scalars = 0;
  off_t data_offset = 0, base_offset = 0;
  //int total_file_size = 0;

  int64_t total_chunk_size = (header_io_id->idx->chunk_size[0] * header_io_id->idx->chunk_size[1] * header_io_id->idx->chunk_size[2] * header_io_id->idx->chunk_size[3] * header_io_id->idx->chunk_size[4]);// / (64 / header_io_id->idx->compression_bit_rate);


  /*
  for (i = 0; i < header_io_id->idx->variable_count; i++)
  {
    if (header_io_id->idx->variable[i]->values_per_sample != 1)
    {
      all_scalars = 0;
      break;
    }
  }
  */

  int total_header_size = (10 + (10 * header_io_id->idx->blocks_per_file)) * sizeof (uint32_t) * header_io_id->idx->variable_count;
  //memset(headers, 0, total_header_size);

  //int nprocs;
  //MPI_Comm_size(header_io_id->comm, &nprocs);

  for (i = 0; i < header_io_id->idx->blocks_per_file; i++)
  {
    //if (nprocs == 1)
    //  printf("[B] [%d %d] : %d\n", header_io_id->idx->variable[header_io_id->first_index]->global_block_layout->resolution_from, header_io_id->idx->variable[header_io_id->first_index]->global_block_layout->resolution_to, i);
    if (PIDX_blocks_is_block_present((i + (header_io_id->idx->blocks_per_file * file_number)), header_io_id->idx->variable[header_io_id->first_index]->global_block_layout))
    {
        //if (nprocs == 1)
        //  printf("[A] %d\n", i);
      block_negative_offset = PIDX_blocks_find_negative_offset(header_io_id->idx->blocks_per_file, (i + (header_io_id->idx->blocks_per_file * file_number)), header_io_id->idx->variable[header_io_id->first_index]->global_block_layout);


      for (j = header_io_id->first_index; j < header_io_id->last_index; j++)
      //for (j = 0; j < header_io_id->idx->variable_count; j++)
      {
        base_offset = 0;
        if (all_scalars == 0)
        {
          for (k = 0; k < j; k++)
            base_offset = base_offset + ((block_layout->block_count_per_file[file_number]) * (header_io_id->idx->variable[k]->bits_per_value / 8) * total_chunk_size * header_io_id->idx_d->samples_per_block * header_io_id->idx->variable[k]->values_per_sample) / (header_io_id->idx->compression_factor);
            //base_offset = base_offset + ((header_io_id->idx->variable[header_io_id->first_index]->block_count_per_file[file_number]) * (header_io_id->idx->variable[k]->bits_per_value / 8) * total_chunk_size * header_io_id->idx_d->samples_per_block * header_io_id->idx->variable[k]->values_per_sample) / (header_io_id->idx->variable[k]->bits_per_value / header_io_id->idx->compression_bit_rate);
        }
        else
          base_offset =  j * (block_layout->block_count_per_file[file_number]) * (header_io_id->idx->variable[header_io_id->first_index]->bits_per_value / 8) * total_chunk_size * header_io_id->idx_d->samples_per_block * header_io_id->idx->variable[header_io_id->first_index]->values_per_sample / (header_io_id->idx->compression_factor);
          //base_offset =  j * (header_io_id->idx->variable[header_io_id->first_index]->block_count_per_file[file_number]) * (header_io_id->idx->variable[header_io_id->first_index]->bits_per_value / 8) * total_chunk_size * header_io_id->idx_d->samples_per_block * header_io_id->idx->variable[header_io_id->first_index]->values_per_sample / (header_io_id->idx->variable[j]->bits_per_value / header_io_id->idx->compression_bit_rate);

        data_offset = (((i) - block_negative_offset) * header_io_id->idx_d->samples_per_block) * (header_io_id->idx->variable[j]->bits_per_value / 8) * total_chunk_size * header_io_id->idx->variable[j]->values_per_sample  / (header_io_id->idx->compression_factor);

        //printf("BLOCK %d = %d + %d + %d (%d %d)\n", i, (int)base_offset, (int)data_offset, (int)(header_io_id->idx_d->start_fs_block * header_io_id->idx_d->fs_block_size), header_io_id->idx_d->start_fs_block, header_io_id->idx_d->fs_block_size);
        data_offset = base_offset + data_offset + header_io_id->idx_d->start_fs_block * header_io_id->idx_d->fs_block_size;

        //TODO
        //printf("%d %d: %d (%d * %d * %d * %d)\n", i, j, header_io_id->idx_d->samples_per_block * (header_io_id->idx->variable[j]->bits_per_value / 8) * total_chunk_size * header_io_id->idx->variable[j]->values_per_sample, header_io_id->idx_d->samples_per_block, (header_io_id->idx->variable[j]->bits_per_value / 8), total_chunk_size, header_io_id->idx->variable[j]->values_per_sample);
        //if (file_number == 2)
        //if (nprocs == 1)
        //printf("[%d] offset : count = %lld %lld\n", i, (unsigned long long)data_offset, (unsigned long long)(header_io_id->idx_d->samples_per_block * (header_io_id->idx->variable[j]->bits_per_value / 8) * total_chunk_size * header_io_id->idx->variable[j]->values_per_sample));
        headers[12 + ((i + (header_io_id->idx->blocks_per_file * j))*10 )] = htonl(data_offset);
        headers[14 + ((i + (header_io_id->idx->blocks_per_file * j))*10)] = htonl(header_io_id->idx_d->samples_per_block * (header_io_id->idx->variable[j]->bits_per_value / 8) * total_chunk_size * header_io_id->idx->variable[j]->values_per_sample / (header_io_id->idx->compression_factor));

        //total_file_size = data_offset + header_io_id->idx_d->samples_per_block * (header_io_id->idx->variable[j]->bits_per_value / 8) * total_chunk_size * header_io_id->idx->variable[j]->values_per_sample / (header_io_id->idx->compression_factor);
      }
    }
  }
#if 1
  if (mode == 1)
  {

#if PIDX_HAVE_MPI
    if (header_io_id->idx_d->parallel_mode == 1)
    {
      MPI_File fh;
      MPI_Status status;
      int ret = 0;
      ret = MPI_File_open(MPI_COMM_SELF, bin_file, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
      if (ret != MPI_SUCCESS)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_open() failed on %s\n", __FILE__, __LINE__, bin_file);
        return PIDX_err_io;
      }

      /*
      if(total_file_size != 0)
      {
        ret = MPI_File_set_size(fh, total_file_size);
        if(ret != MPI_SUCCESS)
        {
          fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed.\n", __FILE__, __LINE__);
          return PIDX_err_io;
        }
      }
      */

      ret = MPI_File_write_at(fh, 0, headers, total_header_size, MPI_BYTE, &status);
      if (ret != MPI_SUCCESS)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_write_at() failed.\n", __FILE__, __LINE__);
        return PIDX_err_io;
      }

      ret = MPI_File_close(&fh);
      if (ret != MPI_SUCCESS)
      {
        fprintf(stderr, "[%s] [%d] MPI_File_open() failed on %s\n", __FILE__, __LINE__, bin_file);
        return PIDX_err_io;
      }
    }
    else
    {
      int fh = 0;
      fh = open(bin_file, O_WRONLY, 0664);
      //ftruncate(fh, total_file_size);
      ssize_t ret_size = pwrite(fh, headers, total_header_size, 0);
      if (ret_size != total_header_size)
      {
        fprintf(stderr, "[%s] [%d] pwrite() failed on %s\n", __FILE__, __LINE__, bin_file);
        return PIDX_err_io;
      }

      close(fh);
    }
#else
    int fh = 0;
    fh = open(bin_file, O_WRONLY, 0664);
    //ftruncate(fh, total_file_size);
    ssize_t ret_size = pwrite(fh, headers, total_header_size, 0);
    if (ret_size != total_header_size)
    {
      fprintf(stderr, "[%s] [%d] pwrite() failed on %s\n", __FILE__, __LINE__, bin_file);
      return PIDX_err_io;
    }
    close(fh);
#endif

    //int total_header_size = (10 + (10 * header_io_id->idx->blocks_per_file)) * sizeof (uint32_t) * header_io_id->idx->variable_count;
  }
#endif

  return PIDX_success;
}
Exemple #30
0
int main( int argc, char *argv[] )
{
    int itr;
    int operacao;
    char * chave_file;
    char * entrada_file;
    char * saida_file;

    octeto Nb,Nk,Nr;
    octeto bloco[4*8];
    octeto chave[4*8*15];

    int worldsize, rank;
    MPI_Status status;
    MPI_File chave_handle;
    MPI_File entrada_handle;
    MPI_File saida_handle;

    MPI_Offset entrada_bytes;
    unsigned int numero_blocos;
    unsigned int blocos_processo;
    MPI_Offset bloco_byte_inicio;
    MPI_Offset bloco_byte_fim;
    MPI_Offset iterador;


    MPI_Init(&argc,&argv);

    MPI_Comm_size(MPI_COMM_WORLD,&worldsize);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    operacao = INDEFINIDA;
    chave_file = NULL;
    entrada_file = NULL;
    saida_file = NULL;
    for(itr = 1;itr < argc;itr++)
    {
/* Instrucoes de uso */
        if( strcmp(argv[itr],"-a") == 0 || strcmp(argv[itr],"--ajuda") == 0 || 
            strcmp(argv[itr],"-h") == 0 || strcmp(argv[itr],"--help") == 0 )
        {
            if(rank == 0)
            {
                printf(" Uso: mpiexec -n [PROCESSOS] ./rijndael [ARGUMENTO VALOR].\n");
                printf(" Encripta/Decripta um arquivo usando o algoritmo Rijndael(AES) extendido.\n");
                printf("  Argumentos obrigatorios:\n");
                printf("   -op,--operacao: Informa se o objetivo da execucao eh encriptar ou decriptar.\n");
                printf("                    * Os valores possiveis sao: \'encriptar\' e \'decriptar\'.\n");
                printf("   -e,-i,--entrada,--input: Caminho e nome do arquivo a ser criptografado.\n");
                printf("   -s,-o,--saida,--output: Caminho e nome do arquivo resultante do processo de criptografia da entrada.\n");
                printf("   -c,-k,--chave,--key: Caminho e nome do arquivo contendo a chave.\n");
                printf("  O arquivo contendo a chave eh em formato binario de acordo com a seguinte especificacao:\n");
                printf("   - O primeiro byte deve conter o tamanho do bloco (em palavras de 4 bytes).\n");
                printf("      * O bloco pode possuir tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - O segundo byte deve conter o tamanho da chave (em palavras de 4 bytes).\n");
                printf("      * Esta aplicacao aceita chaves com tamanho: 4, 5, 6, 7 ou 8.\n");
                printf("   - Os proximos 4*[tamanho da chave] bytes do arquivo sao os bytes componentes da chave, que\n");
                printf("     devem estar (obrigatoriamente) escritos no formato hexadecimal da linguagem C (0xff).\n");
                printf("   * Eh recomendavel o uso de um editor hexadecimal na construcao do arquivo chave.\n");
            }
            goto finalizando;
        }

/* Operacao a ser realizada */
        else
        if( strcmp(argv[itr],"-op") == 0 || strcmp(argv[itr],"--operacao") == 0 )
        {
            if( itr+1 < argc )
            {
                if( strcmp(argv[itr+1],"encriptar") == 0 )
                {
                    operacao = ENCRIPTAR;
                }
                else
                if( strcmp(argv[itr+1],"decriptar") == 0 )
                {
                    operacao = DECRIPTAR;
                }
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo com a chave */
        else
        if( strcmp(argv[itr],"-c") == 0 || strcmp(argv[itr],"--chave") == 0 || 
            strcmp(argv[itr],"-k") == 0 || strcmp(argv[itr],"--key") == 0 )
        {
            if(itr+1 < argc)
            {
                chave_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de entrada */
        else
        if( strcmp(argv[itr],"-e") == 0 || strcmp(argv[itr],"--entrada") == 0 || 
            strcmp(argv[itr],"-i") == 0 || strcmp(argv[itr],"--input") == 0 )
        {
            if(itr+1 < argc)
            {
                entrada_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }

/* Arquivo de saida */
        else 
        if( strcmp(argv[itr],"-s") == 0 || strcmp(argv[itr],"--saida") == 0 || 
            strcmp(argv[itr],"-o") == 0 || strcmp(argv[itr],"--output") == 0 )
        {
            if(itr+1 < argc)
            {
                saida_file = argv[itr+1];
                itr++;
            }
            else
            {
                goto sempar;
            }
        }
/* Erro desconhecido */
        else
        {
            if(rank == 0)
            {
                printf("Erro nos argumentos passados.\n");
            }
            goto help;
        }
    }
/* Fim da leitura dos argumentos */

    if( operacao == INDEFINIDA || chave_file == NULL || entrada_file == NULL || saida_file == NULL )
    {
        if(rank == 0)
        {
            if( operacao == INDEFINIDA )
                printf("A operacao a ser realizada eh invalida ou nao foi especificada.\n");
            if( chave_file == NULL )
                printf("Esta faltando especificar o arquivo com a chave.\n");
            if( entrada_file == NULL )
                printf("Esta faltando especificar o arquivo de entrada.\n");
            if( saida_file == NULL )
                printf("Esta faltando especificar o arquivo de saida.\n");
        }
        goto help;
    }
/* Fim do tratamento dos argumentos */

    if( MPI_File_open( MPI_COMM_WORLD, chave_file, MPI_MODE_RDONLY, MPI_INFO_NULL, &chave_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nb,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho de um bloco no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nb< 4 || Nb > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de bloco invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,&Nk,1, MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura do tamanho da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }
    if( Nk< 4 || Nk > 8 )
    {
        if( rank == 0 )
        {
            printf("Tamanho de chave invalido no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    if( MPI_File_read(chave_handle,chave,4*Nk,MPI_BYTE,&status) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na leitura da chave no arquivo com a chave (%s).\n",chave_file);
        }
        goto help;
    }

    MPI_File_close( &chave_handle );
    Nr = numero_rodadas(Nb,Nk);
    KeyExpansion(chave,Nb,Nk);

    if( MPI_File_open( MPI_COMM_WORLD, entrada_file, 
            MPI_MODE_RDONLY, 
            MPI_INFO_NULL, &entrada_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na abertura do arquivo de entrada (%s).\n",entrada_file);
        }
        goto help;
    }

    MPI_File_get_size(entrada_handle,&entrada_bytes);


    if( MPI_File_open( MPI_COMM_WORLD, saida_file, 
            MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL, 
            MPI_INFO_NULL, &saida_handle ) != MPI_SUCCESS )
    {
        if( rank == 0 )
        {
            printf("Erro na criacao do arquivo de saida (%s).\n",saida_file);
            printf("Uma possivel causa eh que o arquivo ja exista.\n");
        }
        goto help;
    }

    numero_blocos = ( entrada_bytes / (Nb*4) );
    blocos_processo = numero_blocos / worldsize;

    if( operacao == ENCRIPTAR )
    {
        MPI_File_set_size(saida_handle,(MPI_Offset)( (numero_blocos+1)*(Nb*4) ) );

        bloco_byte_inicio = 4*Nb*blocos_processo*rank;
        bloco_byte_fim = 4*Nb*blocos_processo*(rank+1);


        for( iterador = bloco_byte_inicio ; iterador < bloco_byte_fim ; iterador += (4*Nb) )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            AES_encriptar_bloco(bloco,Nb,chave,Nr);

            if( MPI_File_write_at(saida_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }
        }
        
        iterador = 4*Nb*blocos_processo*worldsize + 4*Nb*rank;
        if( iterador <= numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }
            if( iterador == numero_blocos*4*Nb )
                bloco[ 4*Nb - 1 ] = (octeto)(entrada_bytes - numero_blocos*4*Nb);

            AES_encriptar_bloco(bloco,Nb,chave,Nr);

            if( MPI_File_write_at(saida_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }
        }
        if( rank == 0 )
        {
           // printf("A encriptacao do arquivo foi realizada com sucesso.\n");
        }
    }
    else 
    if( operacao == DECRIPTAR )
    {
        MPI_File_set_size(saida_handle,entrada_bytes);

        bloco_byte_inicio = 4*Nb*blocos_processo*rank;
        bloco_byte_fim = 4*Nb*blocos_processo*(rank+1);


        for( iterador = bloco_byte_inicio ; iterador < bloco_byte_fim ; iterador += (4*Nb) )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            AES_decriptar_bloco(bloco,Nb,chave,Nr);

            if( MPI_File_write_at(saida_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }
        }

        iterador = 4*Nb*blocos_processo*worldsize + 4*Nb*rank;
        if( iterador < numero_blocos*4*Nb )
        {
            if( MPI_File_read_at(entrada_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao ler do arquivo de entrada (%s).\n",entrada_file);
                }
                goto help;
            }

            AES_decriptar_bloco(bloco,Nb,chave,Nr);

            if( MPI_File_write_at(saida_handle,iterador,bloco,(4*Nb),MPI_BYTE,&status) != MPI_SUCCESS )
            {
                if( rank == 0 )
                {
                    printf("Erro ao escrever no arquivo de saida (%s).\n",saida_file);
                }
                goto help;
            }
        }

        MPI_Barrier( MPI_COMM_WORLD ); /*Barreira q impede q alguem leia antes do valor decriptografado ser escrito */

        if( MPI_File_read_at(saida_handle,entrada_bytes-1,bloco,1,MPI_BYTE,&status) != MPI_SUCCESS )
        {
            if( rank == 0 )
            {
                printf("Erro ao realizar leitura no arquivo de saida (%s).\n",saida_file);
            }
            goto help;
        }

        MPI_Barrier( MPI_COMM_WORLD ); /* Barreira q impede q alqum processo trunque o arquivo antes de outro processo ler*/

        MPI_File_set_size(saida_handle,entrada_bytes - 4*Nb + bloco[0]);

        if( rank == 0 )
        {
           // printf("A decriptacao do arquivo foi realizada com sucesso.\n");
        }
    }

    goto finalizando;

sempar:
    if( rank == 0 )
    {
        printf("Sem par correspondente para a opcao %s.\n",argv[itr]);
    }

help:
    if( rank == 0 )
    {
        printf("Use a opcao --help para melhor entendimento do uso da aplicacao.\n");
    }

finalizando:
    MPI_Finalize( );
    return 0;
}