Esempio n. 1
0
int main(int argc, char *argv[]) {
    int my_rank, num_procs;

    const int max_iters = 10000;    /// maximum number of iteration to perform

    /** Simulation parameters parsed from the input datasets */
    int nintci, nintcf;    /// internal cells start and end index
    /// external cells start and end index. The external cells are only ghost cells.
    /// They are accessed only through internal cells
    int nextci, nextcf;
    int **lcc;    /// link cell-to-cell array - stores neighboring information
    int *lcc_local;
    /// Boundary coefficients for each volume cell (South, East, North, West, High, Low)
    double *bs, *be, *bn, *bw, *bl, *bh;
    double *bp;    /// Pole coefficient
    double *su;    /// Source values

    double residual_ratio;    /// the ratio between the reference and the current residual
    double *var;    /// the variation vector -> keeps the result in the end

    /** Additional vectors required for the computation */
    double *cgup, *oc, *cnorm;

    /** Geometry data */
    int points_count;    /// total number of points that define the geometry
    int** points;    /// coordinates of the points that define the cells - size [points_cnt][3]
    int* elems;    /// definition of the cells using their nodes (points) - each cell has 8 points
    int num_elems;

    /** Mapping between local and remote cell indices */
    int* local_global_index;    /// local to global index mapping
    int* global_local_index;    /// global to local index mapping
    int* local_global_index_full;

    /** Lists of cells requires for the communication */
    int neighbors_count = 0;    /// total number of neighbors to communicate with
    int* send_count;    /// number of elements to send to each neighbor (size: neighbors_count)
    /// send lists for the other neighbors(cell ids which should be sent)(size:[#neighbors][#cells]
    int** send_list;
    int* recv_count;    /// how many elements are in the recv lists for each neighbor
    int** recv_list;    /// send lists for the other neighbor (see send_list)

    /** Metis Results */
    int* epart;     /// partition vector for the elements of the mesh
    int* npart;     /// partition vector for the points (nodes) of the mesh
    int objval;    /// resulting edgecut of total communication volume (classical distrib->zeros)

    MPI_Init(&argc, &argv);    /// Start MPI
    SCOREP_USER_REGION_DEFINE(OA_Phase);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);    /// Get current process id
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);    /// get number of processes
    double elapsed_time, elapsed_time_max;
    FILE *pFile;
    if ( argc < 3 ) {
        fprintf(stderr, "Usage: ./gccg <input_file> <output_prefix> <partition_type>\n");
        MPI_Abort(MPI_COMM_WORLD, -1);
    }

    char *file_in = argv[1];
    char *out_prefix = argv[2];
    char *part_type = (argc == 3 ? "classical" : argv[3]);
    char file_vtk_out[50];
    char measure_out[20];
    /********** START INITIALIZATION **********/
    // read-in the input file
    elapsed_time = - MPI_Wtime();
    SCOREP_USER_OA_PHASE_BEGIN(OA_Phase, "OA_Phase", SCOREP_USER_REGION_TYPE_COMMON);
    int init_status = initialization(file_in, part_type, &nintci, &nintcf, &nextci, &nextcf, &lcc,
                                     &bs, &be, &bn, &bw, &bl, &bh, &bp, &su, &points_count, &points,
                                     &elems, &var, &cgup, &oc, &cnorm, &local_global_index,
                                     &global_local_index, &local_global_index_full, &lcc_local,
                                     &neighbors_count, &send_count, &send_list,
                                     &recv_count, &recv_list, &epart, &npart, &objval);
    elapsed_time += MPI_Wtime();
    MPI_Reduce(&elapsed_time, &elapsed_time_max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
    if (my_rank == 0) {
      sprintf(measure_out, "time--%d.txt", num_procs);
      pFile = fopen(measure_out, "a");
      fprintf(pFile, "%s Elapsed max --initialization time-init_status = %d: %f secs\n",
              argv[2], init_status, elapsed_time_max);
    }
    if (init_status != 0 && init_status != 1) {
        fprintf(stderr, "Failed to initialize data!\n");
        MPI_Abort(MPI_COMM_WORLD, my_rank);
    }
    num_elems = nintcf - nintci + 1;
    // test distribution
    /*if (my_rank == 2) {
        sprintf(file_vtk_out, "%s_cgup.vtk", out_prefix);
        test_distribution(file_in, file_vtk_out, local_global_index,
        num_elems, cgup);
    }*/
    // Implement this function in test_functions.c and call it here
    /*if (my_rank == 2) {
      sprintf(file_vtk_out, "%s_commlist.vtk", out_prefix);
      test_communication(file_in, file_vtk_out, local_global_index, num_elems,
       neighbors_count, send_count, send_list, recv_count, recv_list);
    }*/
    /********** END INITIALIZATION **********/

    /********** START COMPUTATIONAL LOOP **********/
    elapsed_time = - MPI_Wtime();
    int total_iters = compute_solution(max_iters, nintci, nintcf, nextcf, lcc, bp, bs, bw, bl, bn,
                                       be, bh, cnorm, var, su, cgup, &residual_ratio,
                                       local_global_index, global_local_index,
                                       lcc_local, neighbors_count,
                                       send_count, send_list, recv_count, recv_list);
    elapsed_time += MPI_Wtime();
    MPI_Reduce(&elapsed_time, &elapsed_time_max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
    if (my_rank == 0) {
      pFile = fopen(measure_out, "a");
      fprintf(pFile, "%s Elapsed max --computation time-init_status = %d: %f secs\n",
              argv[2], init_status, elapsed_time_max);
    }
    /********** END COMPUTATIONAL LOOP **********/

    /********** START FINALIZATION **********/
    elapsed_time = - MPI_Wtime();
    finalization(file_in, out_prefix, total_iters, residual_ratio, nintci, nintcf, points_count,
                 points, elems, var, cgup, su, local_global_index_full, init_status);
    elapsed_time += MPI_Wtime();
    MPI_Reduce(&elapsed_time, &elapsed_time_max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
    if (my_rank == 0) {
      pFile = fopen(measure_out, "a");
      fprintf(pFile, "%s Elapsed max --finalization time-init_status = %d: %f secs\n",
              argv[2], init_status, elapsed_time_max);
    }
    SCOREP_USER_OA_PHASE_END(OA_Phase);
    /********** END FINALIZATION **********/
    free(var);
    free(cgup);
    free(su);
    free(bp);
    free(bh);
    free(bl);
    free(bw);
    free(bn);
    free(be);
    free(bs);
    free(lcc_local);
    if (my_rank == 0) {
    free(cnorm);
    free(oc);
    free(elems);
    free(local_global_index);
    int i;
    for (i = 0; i < nintcf + 1; i++) {
        free(lcc[i]);
    }
    free(lcc);
    for (i = 0; i < points_count; i++) {
        free(points[i]);
    }
    free(points);
    }
    MPI_Finalize();    /// Cleanup MPI
    return 0;
}
Esempio n. 2
0
int main(int argc, char* argv[])
{
	read_defines(argc, argv);
	// Счетчик шагов по времени
	long int time_counter = 0;
	// Счетчик времени исполнения вычислительной части программы
	clock_t task_time;

	// Инициализация коммуникаций, перевод глобальных параметров в локальные процессора,
	// выделение памяти, загрузка начальных/сохраненных данных
	initialization(&time_counter, argc, argv);

	// Тест
	//print_hosts_configuration();
	save_data_plots(0);

	task_time = clock();

	/*!
	* Цикл шагов по времени (каждая итерация - новый слой по времени):
	* -# Проводятся расчеты давлений P и насыщенностей S на следующем временном слое
	* -# Каждые (def.print_screen) раз на экран выводится информация о временном слое
	* -# Каждые save_plots раз данные выгружаются в память хоста и
	*    сохраняются в файлы графиков (**), в файл сохраняется состояние задачи (***) 
	*/
	for (time_counter++; time_counter <= def.timeX / (def.dt); time_counter++)
	{
		if ((time_counter % (def.print_screen) == 0) && (def.rank) == 0) // (2)
		{
			printf("t=%.3f\n", time_counter * (def.dt) /def.upscale_t);
			fflush(stdout);
		}

		time_step_function(time_counter * (def.dt)); // (1)

		if ((time_counter % (def.save_plots)) == 0) // (3)
		{
			// Следующие 2 функции вызываются строго в таком порядке,
			// т.к. save использует данные, загруженные save_data_plots
			save_data_plots(time_counter * (def.dt) /def.upscale_t); // (**)
			//save(time_counter); // (***)
		}
	}

	// Ждем пока все процессоры закончат расчеты
	barrier();
	// Вывод информации о времени работы программы в секундах
	task_time = clock() - task_time;
	if (!(def.rank))
	{
		printf("Task time in seconds:\t%.2f\n", (double) task_time / CLOCKS_PER_SEC);
	}

	// Завершение работы и освобождение памяти
	finalization();
	printf("\n...THE END...\n");

	// При запуске в Windows после работы программы оставлять окно консоли
#ifdef _WIN32
	printf("\nPress <Enter> to exit...\n");
	fflush(stdout);
	getchar();
#endif
	return 0;
}
Esempio n. 3
0
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
{
#else
int main(int argc, char** argv) {
#endif

	SDL_Surface *screen_sfc;
	F1SpiritApp *game;
	KEYBOARDSTATE *k;

	int time, act_time;
	SDL_Event event;
	bool quit = false;
	bool need_to_redraw = true;

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application started\n");
#endif
#ifdef HAVE_GLES
	fullscreen = true;
#endif
	screen_sfc = initialization((fullscreen ? SDL_FULLSCREEN : 0));

	if (screen_sfc == 0)
		return 0;

	k = new KEYBOARDSTATE();

	game = new F1SpiritApp();

	#if 0//ndef HAVE_GLES
	// why recreating the context ???
	if (fullscreen) {
	#ifdef HAVE_GLES
		EGL_Close();
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0));
		EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
	#else
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
	#endif
		SDL_WM_SetCaption(application_name, 0);
		SDL_ShowCursor(SDL_DISABLE);
		reload_textures++;

	#ifndef HAVE_GLES
		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	#endif
	} 
	#endif

	time = init_time = SDL_GetTicks();
	
	IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG);

	while (!quit) {
		while ( SDL_PollEvent( &event ) ) {
			switch ( event.type ) {
					/* Keyboard event */

				case SDL_KEYDOWN:
#ifdef __APPLE__

					if (event.key.keysym.sym == SDLK_q) {
						SDLMod modifiers;
						modifiers = SDL_GetModState();

						if ((modifiers &KMOD_META) != 0) {
							quit = true;
						}
					}

#else
					if (event.key.keysym.sym == SDLK_F12) {
						quit = true;
					} 

#endif
					if (event.key.keysym.sym == SDLK_F10) {
						game->save_configuration("f1spirit.cfg");
						game->load_configuration("f1spirit.cfg");
					} 

#ifdef _WIN32
					if (event.key.keysym.sym == SDLK_F4) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0)
							quit = true;
					} 

#endif
#ifdef __APPLE__
					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_META) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;

							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);

							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
						}
					}

#else
					if (event.key.keysym.sym == SDLK_RETURN) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;
							#ifndef HAVE_GLES

							#ifdef HAVE_GLES
							EGL_Close();
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							#else
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							#endif

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							
							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							#ifndef HAVE_GLES
							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
							SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
							#endif
							#endif
						}
					}

#endif

					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* toggle FPS mode: */
							if (show_fps)
								show_fps = false;
							else
								show_fps = true;
						} 
					} 

					/* Keyboard event */
					SDL_keysym *ks;

					ks = new SDL_keysym();

					*ks = event.key.keysym;

					k->keyevents.Add(ks);

					break;

					/* SDL_QUIT event (window close) */

				case SDL_QUIT:
					quit = true;

					break;
			} 
		} 

		act_time = SDL_GetTicks();

		if (act_time - time >= REDRAWING_PERIOD) 
		{
			int max_frame_step = 10;
			/*
			   frames_per_sec_tmp+=1;
			   if ((act_time-init_time)>=1000) {
			    frames_per_sec=frames_per_sec_tmp;
			    frames_per_sec_tmp=0;
			    init_time=act_time;
			   } // if
			*/
			// On PANDORA, let's target 25 fps...
			int min_frame=1;
			#ifdef PANDORA
			min_frame=2;
			#endif

			do {
				time += REDRAWING_PERIOD;

				if ((act_time - time) > 10*REDRAWING_PERIOD)
					time = act_time;

				/* cycle */
				k->cycle();

				if (!game->cycle(k))
					quit = true;

				need_to_redraw = true;

				k->keyevents.Delete();

				act_time = SDL_GetTicks();

				max_frame_step--;
				min_frame--;
			} while (((act_time - time >= REDRAWING_PERIOD) && (max_frame_step > 0)) || (min_frame > 0));

		} 

		/* Redraw */
		if (need_to_redraw) {
			game->draw();
			need_to_redraw = false;
			frames_per_sec_tmp += 1;
		} 

		if ((act_time - init_time) >= 1000) {
			frames_per_sec = frames_per_sec_tmp;
			frames_per_sec_tmp = 0;
			init_time = act_time;
		} 

		#ifndef PANDORA
		SDL_Delay(1);
		#endif

	} 


	delete k;

	k = 0;

	delete game;

	game = 0;

	Stop_playback();

	finalization();

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application finished\n");

	close_debug_messages();

#endif

	return 0;
} /* main */
Esempio n. 4
0
int main(int argc, char *argv[]) {
    int my_rank, num_procs;
    const int max_iters = 10000;    // maximum number of iteration to perform

    /** Simulation parameters parsed from the input datasets */
    int nintci, nintcf;    // internal cells start and end index
    // external cells start and end index. The external cells are only ghost cells.
    // They are accessed only through internal cells
    int nextci, nextcf;
    int **lcc;    // link cell-to-cell array - stores neighboring information
    // Boundary coefficients for each volume cell (South, East, North, West, High, Low)
    double *bs, *be, *bn, *bw, *bl, *bh;
    double *bp;    // Pole coefficient
    double *su;    // Source values
    double residual_ratio;    // the ratio between the reference and the current residual
    double *var;    // the variation vector -> keeps the result in the end

    /* Additional vectors required for the computation */
    double *cgup, *oc, *cnorm;

    /* Geometry data */
    int points_count;    // total number of points that define the geometry
    int** points;    // coordinates of the points that define the cells - size [points_cnt][3]
    int* elems;    // definition of the cells using their nodes (points) - each cell has 8 points
    int num_elems_local;    // number of elemens in each processor

    /* Mapping between local and remote cell indices */
    int* local_global_index;    // local to global index mapping
    int* global_local_index;    // global to local index mapping

    /* Lists of cells requires for the communication */
    int neighbors_count = 0;    // total number of neighbors to communicate with
    int* send_count;    // number of elements to send to each neighbor (size: neighbors_count)
    /// send lists for the other neighbors(cell ids which should be sent)(size:[#neighbors][#cells]
    int** send_list;
    int* recv_count;    // how many elements are in the recv lists for each neighbor
    int** recv_list;    // send lists for the other neighbor (see send_list)

    /* Metis Results */
    int* epart;     // partition vector for the elements of the mesh
    int* npart;     // partition vector for the points (nodes) of the mesh
    int* objval;    /// resulting edgecut of total communication volume (classical distrib->zeros)

    MPI_Init(&argc, &argv);    // Start MPI
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);    // Get current process id
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);    // get number of processes

    if ( argc < 3 ) {
        fprintf(stderr, "Usage: ./gccg <input_file> <output_prefix> <partition_type>\n");
        MPI_Abort(MPI_COMM_WORLD, -1);
    }

    char *file_in = argv[1];
    char *out_prefix = argv[2];
    char *part_type = (argc == 3 ? "classical" : argv[3]);

    /********** START INITIALIZATION **********/
    // read-in the input file
    int init_status = initialization(file_in, part_type, &nintci, &nintcf, &nextci, &nextcf, &lcc,
                                     &bs, &be, &bn, &bw, &bl, &bh, &bp, &su, &points_count, &points,
                                     &elems, &var, &cgup, &oc, &cnorm, &local_global_index,
                                     &global_local_index, &neighbors_count, &send_count, &send_list,
                                     &recv_count, &recv_list, &epart, &npart,
                                     &objval, &num_elems_local);

    if ( init_status != 0 ) {
        fprintf(stderr, "Failed to initialize data!\n");
        MPI_Abort(MPI_COMM_WORLD, my_rank);
    }

    // Implement test function to test the results from initialization
    /* char file_vtk_out[100];
    sprintf(file_vtk_out, "%s.vtk", out_prefix);
    sprintf(file_vtk_out_com, "%scom.vtk", out_prefix);
    if ( my_rank == 0 ) {
        test_distribution( file_in, file_vtk_out, local_global_index, 
                           num_elems_local, cgup, epart, npart, objval ); 
        test_communication( file_in, file_vtk_out, local_global_index, num_elems_local,
                            neighbors_count, send_count, send_list, recv_count, recv_list );
    }*/

    /********** END INITIALIZATION **********/


    /********** START COMPUTATIONAL LOOP **********/
    int total_iters = compute_solution(max_iters, nintci, nintcf, nextcf, lcc, bp, bs, bw, bl, bn,
                                       be, bh, cnorm, var, su, cgup, &residual_ratio,
                                       local_global_index, global_local_index, neighbors_count,
                                       send_count, send_list, recv_count, recv_list,
                                       num_elems_local, epart);
    /********** END COMPUTATIONAL LOOP **********/

    /********** START FINALIZATION **********/
    finalization(file_in, out_prefix, total_iters, residual_ratio, nintci, nintcf, points_count,
                 points, elems, var, cgup, su,  local_global_index, num_elems_local);
    /********** END FINALIZATION **********/

    free(cnorm);
    free(oc);
    free(var);
    free(cgup);
    free(su);
    free(bp);
    free(bh);
    free(bl);
    free(bw);
    free(bn);
    free(be);
    free(bs);

    MPI_Finalize();    /// Cleanup MPI

    return 0;
}
Esempio n. 5
0
int main(int argc, char *argv[]) {
    int my_rank, num_procs, i;

    const int max_iters = 10000;    /// maximum number of iteration to perform

    /** Simulation parameters parsed from the input datasets */
    int nintci, nintcf;    /// internal cells start and end index
    /// external cells start and end index. The external cells are only ghost cells.
    /// They are accessed only through internal cells
    int nextci, nextcf;
    int **lcc;    /// link cell-to-cell array - stores neighboring information
    /// Boundary coefficients for each volume cell (South, East, North, West, High, Low)
    double *bs, *be, *bn, *bw, *bh, *bl;
    double *bp;    /// Pole coefficient
    double *su;    /// Source values

    double residual_ratio;    /// the ratio between the reference and the current residual
    double *var;    /// the variation vector -> keeps the result in the end

    /** Additional vectors required for the computation */
    double *cgup, *oc, *cnorm;

    /** Geometry data */
    int points_count;    /// total number of points that define the geometry
    int** points;    /// coordinates of the points that define the cells - size [points_cnt][3]
    int* elems;    /// definition of the cells using their nodes (points) - each cell has 8 points

    /** Mapping between local and remote cell indices */
    int* local_global_index;    /// local to global index mapping
    int* global_local_index;    /// global to local index mapping

    int** l2g_g;


    /** Lists for neighbouring information */
    int nghb_cnt = 0;    /// total number of neighbors of the current process
    int *nghb_to_rank;  /// mapping of the neighbour index to the corresponding process rank
    int *send_cnt;    /// number of cells to be sent to each neighbour (size: nghb_cnt)
    int **send_lst;    /// lists of cells to be sent to each neighbour (size: nghb_cnt x send_cnt[*])
    int *recv_cnt;    /// number of cells to be received from each neighbour (size: nghb_cnt)
    int **recv_lst;    /// lists of cells to be received from each neighbour (size: nghb_cnt x recv_cnt[*])
    double start_time, end_time;
  

    MPI_Init(&argc, &argv);    /// Start MPI
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);    /// get current process id
    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);    /// get number of processes

    int int_cells_per_proc[num_procs];

    /** process call arguments **/
    if ( argc < 4 ) {
        fprintf(stderr, "Usage: ./gccg <input_file> <partition_type> <algorithm_type>\n");
        MPI_Abort(MPI_COMM_WORLD, -1);
    }

    char *file_in = argv[1];
    char *part_type = argv[2];
    if ( strcmp( part_type, "classic" ) && strcmp( part_type, "dual" )
            && strcmp( part_type, "nodal" ) ) {
        printf(
                " Wrong partition type selected. Valid values are classic, nodal and dual \n" );
        MPI_Abort(MPI_COMM_WORLD, -1);
    }
    char *read_type = argv[3];
    if ( strcmp( read_type, "oneread" ) && strcmp( read_type, "allread" ) ) {
        printf(
                " Wrong read-in algorithm selected. Valid values are oneread and allread. \n" );
        MPI_Abort(MPI_COMM_WORLD, -1);
    }
    if(my_rank==0) {


        /********** START INITIALIZATION **********/
        // read-in the input file
        start_time = MPI_Wtime();
        int init_status = initialization(file_in, part_type, read_type, num_procs, my_rank,
                                         &nintci, &nintcf, &nextci, &nextcf,
                                         &lcc, &bs, &be, &bn, &bw, &bl, &bh, &bp, &su,
                                         &points_count, &points, &elems, &var, &cgup, &oc, &cnorm,
                                         &local_global_index, &l2g_g, int_cells_per_proc);
        end_time = MPI_Wtime();
        printf("Initialization ET (secs): %f\n", end_time-start_time);
        /** LOCAL DATA FROM HERE ON **/
        // at this point, all initialized vectors should contain only the locally needed data
        // and all variables representing the number of elements, cells, points, etc. should
        // reflect the local setup, e.g. nintcf-nintci+1 is the local number of internal cells
        if ( init_status != 0 ) {
            fprintf(stderr, "Failed to initialize data!\n");
            MPI_Abort(MPI_COMM_WORLD, my_rank);
        }


        /********** END INITIALIZATION **********/

        /********** START COMPUTATIONAL LOOP **********/
        start_time = MPI_Wtime();
        int total_iters = compute_solution(num_procs, my_rank, max_iters, nintci, nintcf, nextcf,
                        lcc, bp, bs, bw, bl, bn, be, bh,
                         cnorm, var, su, cgup, &residual_ratio,
                         local_global_index, global_local_index, nghb_cnt,
                         nghb_to_rank, send_cnt, send_lst, recv_cnt, recv_lst,
                         file_in, points_count, points, elems, part_type, read_type,
                         l2g_g, int_cells_per_proc);
        end_time = MPI_Wtime();
        printf("Computation ET (secs): %f\n", end_time-start_time);
        /********** END COMPUTATIONAL LOOP **********/

        /********** START FINALIZATION **********/
        finalization(file_in, num_procs, my_rank, total_iters, residual_ratio, nintci, nintcf, var);
        /********** END FINALIZATION **********/

        // cleanup allocated memory
        free(cnorm);
        free(var);
        free(cgup);
        free(su);
        free(bp);
        free(bh);
        free(bl);
        free(bw);
        free(bn);
        free(be);
        free(bs);
        free(elems);

        for ( i = 0; i < nintcf + 1; i++ ) {
            free(lcc[i]);
        }
        free(lcc);

        for ( i = 0; i < points_count; i++ ) {
            free(points[i]);
        }
        free(points);

    }

    MPI_Finalize();    /// cleanup MPI

    return 0;
}