Visual Studio で「in-class initializer のあるメンバーは const である必要があります」というエラーが出てしまい悩まされたが、クラスメンバのスタティック変数の初期化の書き方に問題があったようでした。
・staticメンバ変数はクラス宣言の外(ソースファイル)で初期化する。
・先頭に(const な場合はそれも含めて)型名を付ける。初期化子で記述も可能。
中の下の上の真ん中あたり:【C++】static constなメンバの初期化
Theoride Technology:実践C++入門講座 第28回目 staticメンバ、および、クラス外でメンバを定義する
秋山ブログ:C++で静的メンバ変数の配列を初期化する
C言語 ctype.h 空白文字 isspace isalpha isdigit isalnum ispunct isgraph isprint iscntrl
文字を判定する ANSI C ライブラリ関数
※isspaceは、Cロケールでは0x09~0x0d('\t','\n','\v','\f','\r')も含む
<参考>
・C言語講座:文字を調べる関数群
| 0x7f,0x00~0x08,0x0e~0x1f | 0x09~0x0d | 0x20 | 0x21~0x7e | ||
| iscntrl | isprint | ||||
| isspace | isgraph | ||||
| ispunct | isalnum | ||||
| isdigit | isalpha | ||||
※isspaceは、Cロケールでは0x09~0x0d('\t','\n','\v','\f','\r')も含む
<参考>
・C言語講座:文字を調べる関数群
C言語 C++ 値 アドレス 参照 ポインタ 演算子 メンバ関数 関数ポインタ const
★変数
type x → typeの値を格納する値型変数(引数であれば、値がコピーされて代入される)
type* x → typeのアドレスを格納するポインタ型変数(引数であれば、アドレスがコピーされて代入される)
type& x → 値の複製はせずに同一のアドレスを指す参照型変数、C++のみ。アドレスを初期化で格納した後は、アドレスの変更はできないが値の変更はできる。引数値、戻り値とした場合、値型変数では値の複製が自動実行されるが、参照型変数では値の複製は自動実行されない。
★演算
& → アドレス演算子。変数のアドレスを示す。(主として値を格納する変数に対して使用)
* → 間接演算子。参照先の値を示す。(主としてアドレスを格納する変数に対して使用)
通常変数に対する「&」とポインタ変数に対する「*」がペアになって使用されると考えてよい。変数の値を操作するため、関数の引数としてコピーではなくオリジナルを渡したいときは「&」をつけてポインタ渡しを行い、関数内では「*」を付けて値参照するというものだ。
★構造体メンバ変数の参照方法
値→「.」(ドット演算子)
アドレス→「->」(アロー演算子)
配列や構造体では以下の関係が成り立つ。
array[0]⇔*array
struct->member⇔(*struct).member
★メンバの関数ポインタ
ポインタデータ型 (クラス名::*ポインタ変数名)();
※データ型は関数の戻り値に対応させる
これは難しい。下記のサイトに情報があった。
マルペケつくろーどっとコム:->、*、&、[]演算子って奥深い
★メンバ関数のconst修飾子
〇メンバ変数のデータ(値 or ポインタ)の書き換えができなくなる
→ポインタ型の前constは値、後constはアドレスの書換禁止なので、ポインタ型で戻り値がある場合、後constとは意味が重複する。ポインタ型で前constを付けた戻り値にすれば書換できなくなる。
→結果的にメンバ関数内でメンバ変数を書き換えないという意味。
下記のサイトの説明がわかりやすかった。
ドクロモエ:【C++】const の扱いが複雑すぎる
Flat Leon Works:【C++】メンバ関数には必要に応じてconstをつけよう
type x → typeの値を格納する値型変数(引数であれば、値がコピーされて代入される)
type* x → typeのアドレスを格納するポインタ型変数(引数であれば、アドレスがコピーされて代入される)
type& x → 値の複製はせずに同一のアドレスを指す参照型変数、C++のみ。アドレスを初期化で格納した後は、アドレスの変更はできないが値の変更はできる。引数値、戻り値とした場合、値型変数では値の複製が自動実行されるが、参照型変数では値の複製は自動実行されない。
★演算
& → アドレス演算子。変数のアドレスを示す。(主として値を格納する変数に対して使用)
* → 間接演算子。参照先の値を示す。(主としてアドレスを格納する変数に対して使用)
通常変数に対する「&」とポインタ変数に対する「*」がペアになって使用されると考えてよい。変数の値を操作するため、関数の引数としてコピーではなくオリジナルを渡したいときは「&」をつけてポインタ渡しを行い、関数内では「*」を付けて値参照するというものだ。
★構造体メンバ変数の参照方法
値→「.」(ドット演算子)
アドレス→「->」(アロー演算子)
配列や構造体では以下の関係が成り立つ。
array[0]⇔*array
struct->member⇔(*struct).member
★メンバの関数ポインタ
ポインタデータ型 (クラス名::*ポインタ変数名)();
※データ型は関数の戻り値に対応させる
これは難しい。下記のサイトに情報があった。
マルペケつくろーどっとコム:->、*、&、[]演算子って奥深い
★メンバ関数のconst修飾子
〇メンバ変数のデータ(値 or ポインタ)の書き換えができなくなる
→ポインタ型の前constは値、後constはアドレスの書換禁止なので、ポインタ型で戻り値がある場合、後constとは意味が重複する。ポインタ型で前constを付けた戻り値にすれば書換できなくなる。
→結果的にメンバ関数内でメンバ変数を書き換えないという意味。
下記のサイトの説明がわかりやすかった。
ドクロモエ:【C++】const の扱いが複雑すぎる
Flat Leon Works:【C++】メンバ関数には必要に応じてconstをつけよう
エラー E1696 ソース ファイルを開けません Windows SDK
エラー E1696 ソース ファイルを開けません
Visual Studio での上記エラーメッセージが、標準ライブラリヘッダファイルについて全部出てしまうような場合は、Windows SDK バージョンを確認し、プロジェクト毎に[構成プロパティ]→[全般]→[Windows SDK バージョン]で設定し直す。
PG日誌 (takap-tech.com):VC++でどのWindowsSDKを選択するべきか
stackoverflow:How do I specify which Windows SDK version qmake shall target?
Visual Studio での上記エラーメッセージが、標準ライブラリヘッダファイルについて全部出てしまうような場合は、Windows SDK バージョンを確認し、プロジェクト毎に[構成プロパティ]→[全般]→[Windows SDK バージョン]で設定し直す。
PG日誌 (takap-tech.com):VC++でどのWindowsSDKを選択するべきか
stackoverflow:How do I specify which Windows SDK version qmake shall target?
MPI 構造体 データ 送受信 派生データ型
MPI(Message Passing Interface)で構造体を送受信したいときは、MPI_Type_struct関数、MPI_Type_commit関数でMPIデータ型を定義してから送受信する。終了時にはMPI_Type_free関数でMPIデータ型をメモリ解放する。
int MPI_Type_struct(int count, const int *array_of_blocklengths, const MPI_Aint *array_of_displacements, const MPI_Datatype *array_of_types, MPI_Datatype *newtype)
count:メンバの個数
array_of_blocklength:各メンバの要素数を示す配列へのポインタ
array_of_displacements:各メンバのメモリオフセットを示す配列へのポインタ
array_of_types:各メンバのMPIデータ型を示す配列へのポインタ
new_type:MPIデータ型を表す変数へのポインタ
int MPI_Type_commit(MPI_Datatype *datatype)
datatype:MPIデータ型を表す変数へのポインタ
送受信する構造体メンバのメモリオフセットを知るためにはoffsetofマクロを使う。
#include <stddef.h>
#ifndef offsetof
#define offsetof(type, member) ((size_t)&((type*)0)->member)
#endif
int MPI_Type_free(MPI_Datatype *datatype)
datatype:MPIデータ型を表す変数へのポインタ
<参考>
・理化学研究所:MPIコミュニケータとデータタイプ
・理化学研究所:並列プログラミング入門 MPI版
・同志社大学工学部知的システムデザイン研究室:並列処理の導入2 MPIプログラムのチューニング
・C言語入門講座:構造体メンバーの位置を取得する
・noocyte のプログラミング研究室:4.構造体に関するマクロ
・標準Cライブラリの実装:stddef.h
・MSDN:データ型の範囲
int MPI_Type_struct(int count, const int *array_of_blocklengths, const MPI_Aint *array_of_displacements, const MPI_Datatype *array_of_types, MPI_Datatype *newtype)
count:メンバの個数
array_of_blocklength:各メンバの要素数を示す配列へのポインタ
array_of_displacements:各メンバのメモリオフセットを示す配列へのポインタ
array_of_types:各メンバのMPIデータ型を示す配列へのポインタ
new_type:MPIデータ型を表す変数へのポインタ
int MPI_Type_commit(MPI_Datatype *datatype)
datatype:MPIデータ型を表す変数へのポインタ
送受信する構造体メンバのメモリオフセットを知るためにはoffsetofマクロを使う。
#include <stddef.h>
#ifndef offsetof
#define offsetof(type, member) ((size_t)&((type*)0)->member)
#endif
int MPI_Type_free(MPI_Datatype *datatype)
datatype:MPIデータ型を表す変数へのポインタ
<参考>
・理化学研究所:MPIコミュニケータとデータタイプ
・理化学研究所:並列プログラミング入門 MPI版
・同志社大学工学部知的システムデザイン研究室:並列処理の導入2 MPIプログラムのチューニング
・C言語入門講座:構造体メンバーの位置を取得する
・noocyte のプログラミング研究室:4.構造体に関するマクロ
・標準Cライブラリの実装:stddef.h
・MSDN:データ型の範囲
リダクション演算 C/C++ OpenMP MPI Gather/Scatter ブロードキャスト マルチキャスト
OpenMPのリダクション演算は、C/C++ では Fortran と対応機能が異なるので注意。最大値と最小値には対応していない。(参考文献のpp.17)
<参考文献>
南里豪志、渡部善隆:OpenMP入門(2)、九州大学情報基盤センター広報、Vol.2, No.1, pp.1-40(2002.03)
MPIでデータ集約をする際、reduction 演算をせずに単に集めるなら MPI_Allgather と MPI_Gather が使える。MPI_Allgather は MPI_Gather を全プロセスで呼出した結果と同じになるが、バタフライのアルゴリズムで通信することで高速になるように工夫されている。(東京工業大学 廣瀬研究室:MPIリファレンス 3. 集団通信)MPI_Gather も MPI_Allgather もデータの個数は1プロセスのデータ集約前を指定する。データの個数が各プロセスで異なる場合は MPI_Gatherv と MPI_Allgatherv を使う。基本的にMPIの場合、送信バッファと受信バッファは必ずアドレスが異なっていなければならない。
MPIでデータ集約をする際、reduction 演算をするならば MPI_Allreduce と MPI_reduce が使える。位置を含めて最大値(MPI_MAXLOC)や最小値(MPI_MINLOC)を求める場合はデータ型にMPI_DOUBLE_INTを使う。(MPI_UNSIGNEDはあるがMPI_DOUBLE_UNSIGNEDはないようである。)ユーザー定義の reduction 演算をするならば、演算に使うデータ型(構造体)を MPI_Type_struct で定義、演算内容を MPI_Op_create で登録、といったことが必要である。
<参考URL>
理化学研究所 情報基盤センター 青山幸也:並列プログラミング入門 MPI版 2012年6月1日版(pp.34-39)
MPI_Gather とは逆の MPI_Scatter の各プロセッサの受信側バッファには先頭から詰めて値が書き込まれる。
プロセス総数と自己プロセスは MPI_Comm_size と MPI_Comm_rank で取得される。
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPIでブロードキャストでなくマルチキャストを使いたい場合には、MPI_Comm_split で、MPI_COMM_WORLD(全体)のコミュケータを color 値で分けられたコミュケータ群に分割する。MPI_COMM_WORLD(全体)のコミュケータが消滅するわけではない。MPI_Comm_group 等のコミュケータから作られるグループの操作をする関数もあるらしい。
<参考URL>
辻田祐一:コミュニケータとデータタイプ(→PDF)
<参考文献>
南里豪志、渡部善隆:OpenMP入門(2)、九州大学情報基盤センター広報、Vol.2, No.1, pp.1-40(2002.03)
MPIでデータ集約をする際、reduction 演算をせずに単に集めるなら MPI_Allgather と MPI_Gather が使える。MPI_Allgather は MPI_Gather を全プロセスで呼出した結果と同じになるが、バタフライのアルゴリズムで通信することで高速になるように工夫されている。(東京工業大学 廣瀬研究室:MPIリファレンス 3. 集団通信)MPI_Gather も MPI_Allgather もデータの個数は1プロセスのデータ集約前を指定する。データの個数が各プロセスで異なる場合は MPI_Gatherv と MPI_Allgatherv を使う。基本的にMPIの場合、送信バッファと受信バッファは必ずアドレスが異なっていなければならない。
MPIでデータ集約をする際、reduction 演算をするならば MPI_Allreduce と MPI_reduce が使える。位置を含めて最大値(MPI_MAXLOC)や最小値(MPI_MINLOC)を求める場合はデータ型にMPI_DOUBLE_INTを使う。(MPI_UNSIGNEDはあるがMPI_DOUBLE_UNSIGNEDはないようである。)ユーザー定義の reduction 演算をするならば、演算に使うデータ型(構造体)を MPI_Type_struct で定義、演算内容を MPI_Op_create で登録、といったことが必要である。
<参考URL>
理化学研究所 情報基盤センター 青山幸也:並列プログラミング入門 MPI版 2012年6月1日版(pp.34-39)
MPI_Gather とは逆の MPI_Scatter の各プロセッサの受信側バッファには先頭から詰めて値が書き込まれる。
プロセス総数と自己プロセスは MPI_Comm_size と MPI_Comm_rank で取得される。
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPIでブロードキャストでなくマルチキャストを使いたい場合には、MPI_Comm_split で、MPI_COMM_WORLD(全体)のコミュケータを color 値で分けられたコミュケータ群に分割する。MPI_COMM_WORLD(全体)のコミュケータが消滅するわけではない。MPI_Comm_group 等のコミュケータから作られるグループの操作をする関数もあるらしい。
<参考URL>
辻田祐一:コミュニケータとデータタイプ(→PDF)
MPI Visual Studio C++ 2017 Express MS-MPI
Microsoft Visual Studio(Express 2017 for Windows Desktop のオンラインインストーラー)で、MPI(Message Passing Interface)を利用するにはライブラリをインストールする必要がある。
●手順1.MS-MPI(Release Notes)のインストール
○msmpisdk.msi(include files, lib files)、msmpisetup.exe(mpiexec)の両方をインストール。
●手順2.Visual Studio の設定
○[プロジェクトのプロパティ]→[構成プロパティ]→[C/C++]→[追加のインクルード ディレクトリ]→$(MSMPI_INC)を追加
○[プロジェクトのプロパティ]→[構成プロパティ]→[リンカー]→[追加のライブラリ ディレクトリ]→$(MSMPI_LIB64)または$(MSMPI_LIB32)を追加
●手順3.ソースファイル内で記述
#include <mpi.h> //#define MPI_INCLUDED
#pragma comment(lib, "msmpi.lib")
<参考>
●Atsushi M. Ito's page:Visual Studio 2013におけるMS-MPI v6の利用
●Atsushi M. Ito's page:Visual Studio 2015におけるMS-MPIのデバッグ実行
●手順1.MS-MPI(Release Notes)のインストール
○msmpisdk.msi(include files, lib files)、msmpisetup.exe(mpiexec)の両方をインストール。
●手順2.Visual Studio の設定
○[プロジェクトのプロパティ]→[構成プロパティ]→[C/C++]→[追加のインクルード ディレクトリ]→$(MSMPI_INC)を追加
○[プロジェクトのプロパティ]→[構成プロパティ]→[リンカー]→[追加のライブラリ ディレクトリ]→$(MSMPI_LIB64)または$(MSMPI_LIB32)を追加
●手順3.ソースファイル内で記述
#include <mpi.h> //#define MPI_INCLUDED
#pragma comment(lib, "msmpi.lib")
<参考>
●Atsushi M. Ito's page:Visual Studio 2013におけるMS-MPI v6の利用
●Atsushi M. Ito's page:Visual Studio 2015におけるMS-MPIのデバッグ実行