2

私は並列プログラミングが初めてで、Javaでやりたいと思っています。MPI 経由でより複雑なオブジェクトを送受信できるかどうか疑問に思っています。MPJエクスプレスを使用しています。ただし、オブジェクトを送信するたびに、ClassCastException が発生します。

MPI.Init(args);
myrank = MPI.COMM_WORLD.Rank();
numprocs = MPI.COMM_WORLD.Size();
Vector<CustomClass> chr = new Vector<CustomClass>();
if (myrank == 0 ) { //am I the master?
    for (int i = 1; i < numprocs; i++) {
      MPI.COMM_WORLD.Send(chr, 0, chr.size(), MPI.OBJECT, i, 99); //Here's where the 
                                                                  exception occurs
    }
}
else {             
    Vector<BasicRegion> chr_received = new Vector<BasicRegion>();
    MPI.COMM_WORLD.Recv(chr_received, 0, 1, MPI.OBJECT, 0, 99 );
}

例外:

mpi.MPIException: mpi.MPIException: java.lang.ClassCastException: java.util.Vector は [Ljava.lang.Object; にキャストできません。

私の質問は次のとおりです: - MPJ Express でより複雑なオブジェクトを送受信することは可能ですか? - もしそうなら: 私は何を間違っていますか?

4

3 に答える 3

4

私も MPJ Express は初めてですが、囲んでいるオブジェクトはプリミティブ型 (何かの配列) である必要があるようです。(OpenMPI での C/C++ 実装の場合と同様)。

この種のコードは私にとってうまくいきました:

    Node t[] = new Node[4];
        ...
        count[0] = t.length;
        MPI.COMM_WORLD.Send(count, 0, 1, MPI.INT, 1, 98);
        MPI.COMM_WORLD.Send(t, 0, t.length, MPI.OBJECT, 1, 99);
    } else if( myRank == 1 ) {
        int count[] = new int[1];
        MPI.COMM_WORLD.Recv( count, 0, 1, MPI.INT, 0, 98);
        Status mps = MPI.COMM_WORLD.Recv( t, 0, count[0], MPI.OBJECT, 0, 99 );
        ...

そしてもちろん、Serializable インターフェイスを実装するカスタム クラスが必要です。

于 2013-01-27T10:53:54.900 に答える
2

送信する前にシリアル化したい。

import mpi.*;

import java.io.*;
import java.nio.ByteBuffer;

public class MPITest
{
    public static void main(String[] args)
    {
        MPI.Init(args);
        int me = MPI.COMM_WORLD.Rank();
        int tasks = MPI.COMM_WORLD.Size();

        MPI.COMM_WORLD.Barrier();

        if(me == 0)
        {
            Cat cat = new Cat("Tom", 15);
            cat.Speak();

            ByteBuffer byteBuff = ByteBuffer.allocateDirect(2000 + MPI.SEND_OVERHEAD);
            MPI.Buffer_attach(byteBuff);

            try
            {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutput out = null;
                out = new ObjectOutputStream(bos);
                out.writeObject(cat);
                byte[] bytes = bos.toByteArray();

                System.out.println("Serialized to " + bytes.length);

                MPI.COMM_WORLD.Isend(bytes, 0, bytes.length, MPI.BYTE, 1, 0);
            }
            catch(IOException ex)
            {

            }
        }
        else
        {
            byte[] bytes = new byte[2000];
            Cat recv = null;
            MPI.COMM_WORLD.Recv(bytes, 0, 2000, MPI.BYTE, MPI.ANY_SOURCE, 0);

            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInput in = null;
            try
            {
                in = new ObjectInputStream(bis);
                Object obj = in.readObject();
                recv = (Cat)obj;

                recv.Speak();
            }
            catch(IOException ex)
            {

            }
            catch(ClassNotFoundException cnf)
            {

            }
        }

        MPI.COMM_WORLD.Barrier();
        MPI.Finalize();
    }
} 

これは機能しますが、シリアル化ルーチンが送信する余分なゴミを避けるために、外部化を使用して手動で実行することをお勧めします。

HTH ブライアン

于 2014-03-06T18:02:20.080 に答える