/VTK/Parallel/Core/下的文件:
vtkCommunicator:这个类是用来在多进程环境下发送/接收信息。这个类是一个基类,包含一些进程间信息发送和接收的方法。还包含一些把对象封送为字符串的方法,这些方法应就是用来信息传递用的,到另一端也要解析。(这是用于MPI communicator的,而不是用于内存共享的communicator的)。在这样的信息传递中,所有的系统都必须拥有统一的vtkIdType。这里面有send/receive。还有Broadcast。这个类目前还没有试验过。可以试试
vtkDummycommunicator:这是一个虚设的控制器,用于对于单进程的应用。这是一个虚设的communicator,这用于一些需要controller但是又不用MPI和threads的应用。在这种情况下只有一个进程,没有真的信息传递发生。
vtkFieldDataSerialzer:这个类是用于Field数据的序列化和去序列化的。是vtkObject的一个具体的实例,提供序列化和去序列化,主要用于准备数据的传输,通过MPI或者其他的通行方式。显然这是一个工具类,用于改变Field data的,所以这个应该是没有什么必要测试的。
vtkMultiProcessController:用来在分布式计算环境下控制多个进程。他有一些在多个进程上执行单一或多个方法的方法。触发注册回调(远程方法)(AddRMI(),TriggerRMI())和进程通讯。需要注意的是进程通讯是通过对用户开放的communicator实现的。因此可以通过GetCommunicator()方式获得它,并且通过它完成发送和接收数据。这是鼓励的方式,内部的(RMI)communicator是第二种communicator,称为RMICommunicator。
对于RMI communicator有两种模式实现:(1)Send/Receive 模式和(2)Broadcast(集合)模式。Send/Receive 模式通过二分树的方式,采用后序遍历和从头结点传播RMI 触发到子节点的方式安排进程。一般通过TCP协议完成客户端和服务器的通讯。虽然Send/Receive模式能够在TCP或者MPI上被采用,但是这种方式对于在子进程范围上触发RMIs并不是最佳的。也就是说它采用Broadcast的方式去进行进程通讯。在MPI上下文中,这是一种普通常用的方式。触发RMIs的底层的通讯模式是由"BroadcastTriggerRMI"变量控制的。注意,这两种模式的混合对于RMI通讯不是正确的。在这个vtkMultiProcessController下的所有进程的RMI通讯都要使用相同的模式。
在这个类的头文件中有一些内联函数,用来发送和接收数据。用内联的方式能够提高效率,但是代码膨胀。在实现文件中,有一些增加Trigger的方法,和Broadcast的方法。这个类感觉有可能是数据通讯的地方,但是我上次好像实验了一些地方,不知道是不是没有弄对,等会再试试。而且这个类调用vtkCommunicator这个类完成数据的传输。
vtkMultiProcessStream::这个类用于使用vtkMultiProcessController时在进程中传递数据的流。使用这个类来传递数据一般是因为不知道数据的具体长度。stream操作一般和Push/Pop操作相连。在这个类中,有几个GetRawData方法,获得元数据和设置元数据。这个类更感觉是定义了<<和>>操作符。也就是数据流操作符。这个类更像vtkMultiProcessController使用。
vtkProcess::一个进程能偶被vtkMultiProcessController发起。它是一个抽象类,展示一个进程能够被vtkMultiProcessController发起。具体继承他的类需要实现Execute方法并且保证它设置的value是合适的。
vtkProcessGroup::这个类用于创建组进程。一个vtkProcessGroup通过传递它所依赖的controller或者communicator初始化。能够通过使用这个类去子集化并且重新排序这些进程。最终可以把这个group对象到vtkMultiProcessController的CreateSubController方法下去创建一个定义这组进程的controller。必须使用这个group初始化的controller去控制这个group。
vtkSocketCommunicator::使用socket完成进程通讯。这是具体实现vtkCommunicator的一个类。它支持使用BSD风格的sockets完成进程间的通讯。它支持不同字节序机器的字节的交换。(例如32位和64位,但是它不是完全支持的)。它是一种具体实现方式。
vtkSocketController::这是vtkMultiProcessController的一种具体实现。他在进程中通讯采用Socket的方式。支持一对一的通讯方式。进程0总是与自身对应,进程1与远端进程对象。这个类最好用于端口。这个类用于一个特定的情况下,这个类向上转换的话会出选问题,需要使用CreateCompliantController来进行转话
vtkSubCommunicator::提供在一组进程中进行进程通讯的方法。这个类不直接调用。
vtkSubGroup::对于一个并行VTK应用的成员的子集的可扩展的集合的通讯。这个类提供可扩展的Broadcast,reduce。例如只使用一个vtkMultiProcessController,它不需要MPI。由vtkPKdtree和vtkDistributedDataFilter使用。这个类马上就要弃用了。相比于使用这个类,我们应该使用vtkMultiProcessController中的集合和子组操作。vtkPKdTree这个类确实依赖这个类,所以现在没弃用。
VTK/Parallel/MPI/下的文件:
vtkMPICommunicator::用来创建用户定义的Communicators。这个类就是用来创建用户定义的Communicators。事实上,创建操作发生在初始化的时候(通过MPI_Comm_Create),通过获得参数:一个更基类的Communicator和一组process id。这个新的Communicator将包含这个组内的所有的进程。全局的Communicator(与MPI_COMM_WORLD相同)能够通过类的方法GetWorldCommunicator获得。需要注意的是,这个Communicator不能用在不包含在这个group之中的进程上。这个类的父类是vtkCommunicator。
vtkMPIController::进程通讯使用MPI,这个类是具体的类,使用MPI实现在vtkMultiProcessController定义的抽象的多进程的控制方法。它也提供一些MPI特有的方法。在MPI通讯发生之前,必须在所有的进程上进行初始化。需要立即被调用。在程序的最后必须调用Finalize。用户定制的Communicators由CreateSubController方法支持。注意,用户定义的Communicator的复制是用于内部通讯的(RMIs)。这个Communicator与用户定义的有相同的属性,但是它阻止了两个Communicator间的干扰。
vtkMPIEventLog::这个类用来标记和计时。这个类包装了MPE时间标记方法。它允许用户通过names 和log 创建events。不同的log文件标准通过改变MPE的配置实现。
vtkMPIUtilities::实用函数
VTK/Parallel/MPI4Py/下的文件:
vtkMPI4PyCommunicator::这个类用于建立MPI4Py与vtkMPICommunicator之间的联系。
进行了一些测试。在vtkCommunicator中
int vtkCommunicator::Receive(vtkDataObject* data, int remoteHandle,int tag);
vtkDataObject *vtkCommunicator::ReceiveDataObject(int remoteHandle, int tag);
int vtkCommunicator::ReceiveDataObject(vtkDataObject* data, int remoteHandle,int tag, int dataType);
int vtkCommunicator::ReceiveElementalDataObject(vtkDataObject* data, int remoteHandle, int tag);
int vtkCommunicator::Receive(vtkDataArray* data, int remoteHandle, int tag)
这些函数中加了日志输出,可是发现并没有输出,难道在node190中它没有用这些函数接收数据?还是就没有接收数据啊。在哪接收的数据啊,真心不理解啊。
并且还发现在头结点中用的是vtkMPIMoveData中的模式2,但是子节点用的却是模式1.
而且在vtkMPICommunicator中:
vtkMPICommunicator::BroadcastVoidArray;
vtkMPICommunicator::ReceiveDataInternal;
vtkMPICommunicator::ReceiveVoidArray
这三个也没有执行。
对于vtkCommunicator中,在其int vtkCommunicator::Broadcast(vtkMultiProcessStream& stream, int srcProcessId)上我们得到输出:
PLY file type = 3
190::srcProcessId:0 190::LocalProcessId:1 190::length::41
vtkPVDataInformationKx▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::41
vtkPVDataInformationKx▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::41
vtkPVDataInformationKx▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::52
vtkPVRepresentedDataInformation▒x▒
▒▒▒▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::52
vtkPVRepresentedDataInformation▒x▒
▒▒▒▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::52
vtkPVRepresentedDataInformation▒x▒
▒▒▒▒
190::srcProcessId:0 190::LocalProcessId:1 190::length::52
vtkPVRepresentedDataInformation▒x▒
可以看到,在数据读取之后,给190发送了数据信息和Representation的数据信息。这是有和190传输数据的意思。但是在那之后并没有找到传输数据的地方,很明显,在Broadcast中,我们只是传输了这些命令。
但是在vtkPolyDataMapper之前:
190::srcProcessId:0 190::LocalProcessId:1 190::length::480
▒▒?▒?▒a@n@"z▒▒m▒@▒a@n@Y@▒?b▒▒▒'▒@z
j▒M
▒@>@▒~Z
r@▒?▒?▒?▒?▒?▒?▒?▒?
vtkPolyDataMapper:;Render
vtkPolyDataMapper:;Render
传输了一些数据,这些数据length::480,不像是传递的数据。所以这样看来,所有信息中就是传递了这些。
我们可以知道的是有一些是数据流是在vtkPVSession中由头结点发出的。但并不是所有的都是,至少可以看到的是在vtkPolydataMapper前面那两个不是,但是应该也不是传递数据。