コード例 #1
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// MPIランク別詳細レポート、HWPC詳細レポートを出力。 非排他測定区間も出力
///
///   @param[in] char* fc 出力ファイル名(character文字列)
///   @param[in] legend  HWPC 記号説明の表示(0:表示する、1:表示しない)
///   @param[in] int psort 測定区間の表示順
///                       (0:経過時間順にソート後表示、1:登録順で表示)
///   @param[in] int fc_size  出力ファイル名の文字数
///
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_printdetail_ (char* fc, int& legend, int &psort, int fc_size)
{
	FILE *fp;
	std::string s=std::string(fc,fc_size);
#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_printdetail_> fc=%s, legend=%d, psort=%d, fc_size=%d \n", fc, legend, psort, fc_size);
#endif

	int user_file;
	if (s == "" || fc_size == 0) { // if filename is null, report to stdout
		fp=stdout;
		user_file=0;
	} else {
		fp=fopen(fc,"a");
		if (fp == NULL) {
			fprintf(stderr, "*** warning <f_pm_printdetail_> can not open: %s\n", fc);
			fp=stdout;
			user_file=0;
		} else {
			user_file=1;
		}
	}
	if (psort != 0 && psort != 1) psort = 0;

	PM.printDetail(fp, legend, psort);

	if (user_file == 1) {
		fclose(fp);
	}

	return;
}
コード例 #2
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// プロセスグループ単位でのMPIランク別詳細レポート、HWPC詳細レポート出力
///
///   @param[in] char* fc ラベルとなる character文字列
///   @param[in] p_group  MPI_Group型 groupのgroup handle
///   @param[in] p_comm   MPI_Comm型 groupに対応するcommunicator
///   @param[in] pp_ranks int**型 groupを構成するrank番号配列へのポインタ
///   @param[in] group    int型 プロセスグループ番号
///   @param[in] legend   int型 HWPC 記号説明の表示 (0:表示する、1:表示しない)
///   @param[in] int psort 測定区間の表示順
///                       (0:経過時間順にソート後表示、1:登録順で表示)
///   @param[in] int fc_size  character文字列ラベルの長さ(文字数)
///
///   @note  MPI_Group, MPI_Comm型は呼び出すFortran側では integer 型である
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_printgroup_ (char* fc, MPI_Group p_group, MPI_Comm p_comm, int* pp_ranks, int& group, int& legend, int &psort, int fc_size)


{
	FILE *fp;
	std::string s=std::string(fc,fc_size);
#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_printgroup_> fc=%s, group=%d, legend=%d, psort=%d, fc_size=%d \n", fc, group, legend, psort, fc_size);
#endif

	if (s == "" || fc_size == 0) {
		// filename is null. PMlib report is merged to stdout
		fp=stdout;
	} else {
		fp=fopen(fc,"w+");
		if (fp == NULL) {
			fprintf(stderr, "*** warning <f_pm_printgroup_> can not open: %s\n", fc);
			fp=stdout;
		}
	}
	if (psort != 0 && psort != 1) psort = 0;

	PM.printGroup(fp, p_group, p_comm, pp_ranks, group, legend, psort);

	return;
}
コード例 #3
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// 全プロセスの全測定結果情報をマスタープロセス(0)に集約
///
void f_pm_gather_ (void)
{
#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_gather_> \n");
#endif
	PM.gather();
	return;
}
コード例 #4
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// PMlibの初期化.
///
/// @param[in] init_nWatch 最初に確保する測定区間数。
///
/// @note   測定区間数 m_nWatch は不足すると内部で自動的に追加する
/// @note   Fortran とC++間のインタフェイスでは引数を省略する事はできないため、
///         PMlib C++の引数仕様と異なる事に注意
///
void f_pm_initialize_ (int& init_nWatch)
{
    int num_threads;
    int num_process;
    int my_rank;

#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_initialize_> init_nWatch=%d\n", init_nWatch);
#endif

	PM.initialize(init_nWatch);

#ifdef _PM_WITHOUT_MPI_
	#ifdef _OPENMP
   	char parallel_mode[] = "OpenMP";
	#else
   	char parallel_mode[] = "Serial";
	#endif
    num_process=1;
    my_rank=0;
#else
	#ifdef _OPENMP
   	char parallel_mode[] = "Hybrid";
	#else
   	char parallel_mode[] = "FlatMPI";
	#endif
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num_process);
#endif

#ifdef _OPENMP
	char* c_env = std::getenv("OMP_NUM_THREADS");
	if (c_env == NULL) omp_set_num_threads(1);	// if not defined, set it as 1
	num_threads  = omp_get_max_threads();
	//	PM.num_threads  = omp_get_max_threads();
#else
	num_threads  = 1;
#endif

	PM.setRankInfo(my_rank);
	PM.setParallelMode(parallel_mode, num_threads, num_process);
	return;
}
コード例 #5
0
ファイル: main_kernel.cpp プロジェクト: avr-aics-riken/PMlib
int main (int argc, char *argv[])
{
	int my_id, npes, num_threads;
	int i, j, loop;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
	MPI_Comm_size(MPI_COMM_WORLD, &npes);

#ifdef _OPENMP
	char* c_env = std::getenv("OMP_NUM_THREADS");
	if (c_env == NULL) omp_set_num_threads(1);
	num_threads  = omp_get_max_threads();
#else
	num_threads  = 1;
#endif

	PM.initialize();

	PM.setProperties("First location", PerfMonitor::CALC);
	PM.setProperties("Second location", PerfMonitor::CALC);

	if(my_id == 0) fprintf(stderr, "<main> starting the First location.\n");
	set_array();
	loop=3;
	PM.start("First location");
	for (i=1; i<=loop; i++){
		sub_kernel();
	}
	PM.stop ("First location");

	if(my_id == 0) fprintf(stderr, "<main> starting the Second location.\n");
	PM.start("Second location");
	sub_kernel();
	PM.stop ("Second location");

	PM.gather();
	PM.print(stdout, "", "Mr. Bean");
	PM.printDetail(stdout);

	MPI_Finalize();
	return 0;
}
コード例 #6
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// 測定区間ストップ
///
///   @param[in] label ラベル文字列。測定区間を識別するために用いる。
///   @param[in] fpt 「タスク」あたりの計算量(Flop)または通信量(Byte)
///   @param[in] tic  「タスク」実行回数
///   @param[in] int fc_size  character文字列ラベルの長さ(文字数)
///
///   @note  計算量または通信量をユーザが明示的に指定する場合は、
///          そのボリュームは1区間1回あたりでfpt*ticとして算出される
///   @note  Fortran PMlib インタフェイスでは引数を省略する事はできない。
///          引数値 fpt*tic が非0の場合はその数値が採用され、値が0の場合は
///          HWPC自動計測値が採用される。
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_stop_ (char* fc, double& fpt, unsigned& tic, int fc_size)
{
	std::string s=std::string(fc,fc_size);

#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_stop_> fc=%s, fpt=%8.0lf, tic=%d, fc_size=%d\n", fc, fpt, tic, fc_size);
#endif
	if (s == "") {
		fprintf(stderr, "<f_pm_stop_> ");
		fprintf(stderr, "argument fc is empty(null)\n");
	}
	if (fc_size == 0) {
		fprintf(stderr, "<f_pm_stop_> ");
		fprintf(stderr, "argument fc_size is 0\n");
	}
	PM.stop(s, fpt, tic);
	return;
}
コード例 #7
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// 測定区間スタート
///
///   @param[in] label ラベル文字列。測定区間を識別するために用いる。
///   @param[in] int fc_size  character文字列ラベルの長さ(文字数)
///
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_start_ (char* fc, int fc_size)
{
	std::string s=std::string(fc,fc_size);

#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_start_> fc=%s, fc_size=%d\n", fc, fc_size);
#endif
	if (s == "") {
		fprintf(stderr, "<f_pm_start_> ");
		fprintf(stderr, "argument fc is empty(null)\n");
	}
	if (fc_size == 0) {
		fprintf(stderr, "<f_pm_start_> ");
		fprintf(stderr, "argument fc_size is 0\n");
	}
	PM.start(s);
	return;
}
コード例 #8
0
ファイル: mxm.cpp プロジェクト: mikami3heart/PMlib
int main (int argc, char *argv[])
{
		PM.initialize();
		PM.setProperties("Label-1", PerfMonitor::CALC);
	init2d();
		PM.start("Label-1");
	mxm2d();
		PM.stop ("Label-1");
		PM.print(stdout, "", "Mrs. Kobe", 0);
		PM.printDetail(stdout, 1);
	printf("something was done^^;\n");
	return 0;
}
コード例 #9
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// 測定結果の基本統計レポートを出力
///
///   @param[in] char* fc 出力ファイル名(character文字列)
///   @param[in] int psort 測定区間の表示順
///						(0:経過時間順にソート後表示、1:登録順で表示)
///   @param[in] int fc_size  出力ファイル名の文字数
///
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_print_ (char* fc, int &psort, int fc_size)
{
	FILE *fp;
	std::string s=std::string(fc,fc_size);
#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_print_> fc=%s, psort=%d, fc_size=%d\n", fc, psort, fc_size);
#endif
	std::string h;
	std::string u="Fortran API";
	char hostname[512];
	hostname[0]='\0';
	if (gethostname(hostname, sizeof(hostname)) != 0) {
		fprintf(stderr, "*** warning <f_pm_print_> can not obtain hostname\n");
		h="unknown";
	} else {
		h=hostname;
	}

	int user_file;
	if (s == "" || fc_size == 0) { // if filename is null, report to stdout
		fp=stdout;
		user_file=0;
	} else {
		fp=fopen(fc,"a");
		if (fp == NULL) {
			fprintf(stderr, "*** warning <f_pm_print_> can not open: %s\n", fc);
			fp=stdout;
			user_file=0;
		} else {
			user_file=1;
		}
	}
	if (psort != 0 && psort != 1) psort = 0;

	PM.print(fp, h, u, psort);

	if (user_file == 1) {
		fclose(fp);
	}

	return;
}
コード例 #10
0
ファイル: PerfProgFortran.cpp プロジェクト: syoyo/PMlib
/// PMlib Fortran インタフェイス
/// 測定区間にプロパティを設定.
///
///   @param[in] char* fc ラベルとなる character文字列
///   @param[in] int f_type  測定対象タイプ(0:COMM:通信, 1:CALC:計算)
///   @param[in] int f_exclusive 排他測定フラグ(0:false, 1:true)
///   @param[in] int fc_size  character文字列ラベルの長さ(文字数)
///
///   @note ラベルは測定区間を識別するために用いる。
///   		各labelに対応したキー番号 key は各ラベル毎に内部で自動生成する
///   @note  Fortranコンパイラはfc_size引数を自動的に追加してしまう
///
void f_pm_setproperties_ (char* fc, int& f_type, int& f_exclusive, int fc_size)
{
	//	Note on fortran character 2 C++ string
	//	Although the auto appended fc_size argument value is correct,
	//	fortran character string is not terminated with NUL
	//	A simple conversion such as below is not safe.
	//		std::string s=fc;
	//	So, we do explicit string conversion here...
	std::string s=std::string(fc,fc_size);
	bool exclusive;
    PerfMonitor::Type arg_type; /// 測定対象タイプ from PerfMonitor.h

#ifdef DEBUG_FORT
	fprintf(stderr, "<f_pm_setproperties_> fc=%s, f_type=%d, f_exclusive=%d, fc_size=%d\n", fc, f_type, f_exclusive, fc_size);
#endif
	if (s == "" || fc_size == 0) {
		fprintf(stderr, "<f_pm_setproperties> argument fc is empty(null)\n");
		PM_Exit(0);
	}
	if (f_exclusive == 1) {
		exclusive=true;
	} else if (f_exclusive == 2) {
		exclusive=false;
	} else {
		fprintf(stderr, "<f_pm_setproperties> ");
		fprintf(stderr, "argument f_exclusive is invalid: %u\n", f_exclusive);
		PM_Exit(0);
	}
	//	PM.setProperties(s, f_type, exclusive);
	if (f_type == 0) {
		arg_type = PM.COMM;
	} else if (f_type == 1) {
		arg_type = PM.CALC;
	} else {
		fprintf(stderr, "<f_pm_setproperties> ");
		fprintf(stderr, "argument f_type is invalid: %u\n", f_type);
		PM_Exit(0);
	}
	PM.setProperties(s, arg_type, exclusive);
	return;
}
コード例 #11
0
int main (int argc, char *argv[])
{

	int my_id, num_process, num_threads;
	int i, j, loop;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
	MPI_Comm_size(MPI_COMM_WORLD, &num_process);

	MPI_Group my_group;
	MPI_Comm_group(MPI_COMM_WORLD, &my_group);

#ifdef _OPENMP
	char* c_env = std::getenv("OMP_NUM_THREADS");
	if (c_env == NULL) {
		fprintf (stderr, "undefined OMP_NUM_THREADS is now set as 1\n");
		omp_set_num_threads(1);
	}
	num_threads  = omp_get_max_threads();
#else
	num_threads  = 1;
#endif

	PM.initialize();

	PM.setProperties("1st section", PerfMonitor::CALC);
	PM.setProperties("2nd section", PerfMonitor::CALC);

	if(my_id == 0) {
		fprintf(stderr, "<main> starting the WORLD (default) communicator.\n");
	}

// Create some groups for testing.
	MPI_Group new_group1, new_group2;
	MPI_Comm new_comm1, new_comm2;
	int i_group1, i_group2;
	int new_size1, new_size2;
	int *p1_my_id, *p2_my_id;

// 1st group
	new_size1 = std::max(1,num_process/2);
	p1_my_id = new int[new_size1];
	for (i=0; i<new_size1; i++) { p1_my_id[i] = i; }
	MPI_Group_incl(my_group, new_size1, p1_my_id, &new_group1);
	MPI_Comm_create(MPI_COMM_WORLD, new_group1, &new_comm1);

// 2nd group
	new_size2 = num_process - new_size1;
	p2_my_id = new int[new_size2];
	for (i=0; i<new_size2; i++) { p2_my_id[i] = new_size1 + i; }
	MPI_Group_incl(my_group, new_size2, p2_my_id, &new_group2);
	MPI_Comm_create(MPI_COMM_WORLD, new_group2, &new_comm2);


	set_array();
// using the world communicator (default)
	loop=1;
	PM.start("1st section");
	for (i=1; i<=loop; i++){
		sub_kernel();
	}
	PM.stop ("1st section");

// using the group communicators
	PM.start("2nd section");
	if(my_id<new_size1) {
		stream_copy();
	} else if(my_id<new_size1+new_size2) {
		stream_triad();
	} else {
		;
	}
	PM.stop ("2nd section");


	PM.gather();
	PM.print(stdout, "", "Mr. Bean");
	PM.printDetail(stdout);
	PM.printGroup(stdout, new_group1, new_comm1, p1_my_id, 1);
	PM.printGroup(stdout, new_group2, new_comm2, p2_my_id, 2, 1);

	MPI_Finalize();
	return 0;
}
コード例 #12
0
ファイル: main_split_comm.cpp プロジェクト: syoyo/PMlib
int main (int argc, char *argv[])
{
	int my_id, num_process, num_threads;
	int i, j, k, loop;

	double flop_count, bandwidth_count, dsize;
	double t1, t2;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
	MPI_Comm_size(MPI_COMM_WORLD, &num_process);

#ifdef _OPENMP
	char* c_env = std::getenv("OMP_NUM_THREADS");
	if (c_env == NULL) {
		fprintf (stderr, "undefined OMP_NUM_THREADS is now set as 1\n");
		omp_set_num_threads(1);
	}
	num_threads  = omp_get_max_threads();
#else
	num_threads  = 1;
#endif

	PM.initialize();

	PM.setProperties("section-1", PerfMonitor::CALC);
	PM.setProperties("section-2", PerfMonitor::CALC);


	MPI_Comm new_comm;
	int icolor, key;

	int ncolors = 2;
	icolor = my_id*ncolors / num_process;
	if(my_id == 0) {
		fprintf(stderr, "testing MPI_Comm_split. ncolors=%d\n", ncolors);
	}

	key = my_id;
	MPI_Comm_split(MPI_COMM_WORLD, icolor, key, &new_comm);

	//	int id, size;
	//	MPI_Comm_rank(new_comm, &id);	// new rank id within new_comm
	//	MPI_Comm_size(new_comm, &size);	// the size of new_comm
	//	fprintf(stderr, "\t my_id=%d, icolor=%d, id=%d\n", my_id,icolor,id);


	PM.start("section-1");
	set_array();
	PM.stop ("section-1");

	//	sub_kernel();

	PM.start("section-2");
	if(icolor == 1) {
		stream_copy();
	} else {
		stream_triad();
	}
	PM.stop ("section-2");

	PM.gather();
	PM.print(stdout, "", "");
	PM.printDetail(stdout);
	PM.printComm (stdout, new_comm, icolor, key);
	//	PM.print(stdout, "", "", 1);
	//	PM.printDetail(stdout, 0, 1);
	//	PM.printComm (stdout, new_comm, icolor, key, 0, 1);

	MPI_Finalize();
	return 0;
}