Hello Atsugua,

You can only send contiguous data, i.e. arrays of basic datatypes (byte, char, short, boolean, int, long, float and double) or direct buffers. If you need to send complex data, then you must serialize into an array or a direct buffer. This is made using using the mpi.Struct class, which represents the MPI_STRUCT datatype.

A user-defined struct must be a subclass of Struct and it must have three parts: 1. A number of data fields defined using the add[Type]() methods, that return the corresponding offsets according to the size of the type. The offsets must be stored because they will be necessary to access data. 2. A subclass of Struct.Data with get/put methods to access data. These methods will need the previously stored offsets. 3. The implementation of the method newData() in order to tell the library how to create Data objects.

Another question is the String class. It is not supported because it is a variable sized object. When it is necessary sending strings you must use char arrays.

I attached a similar example to what you want.
Instead of defining two strings you have an int and a string.

Regards,
Oscar

El 09/10/14 16:27, Atsugua Ada escribió:
Hello, I am using Open-MPI 1.8.3 for Java. I would like to know how to create a derived datatype that enables the sending of an array of complex data (objects, strings, etc.) to each processor. In fact, I want to create an array of string or objects and sending a part of this array to each proccess.

E.g., I created the next class:

|/class  Data{
    String  data1;
    String  data2;

    public  Data(String  d1,  String  d2)
    {
         this.data1=  d1;
         this.data2=  d2;
    }
}/|
|and then a array of Data objects is created|
|
|/ Data[] myData= new Data[4]; myData[0] = new Data("d1", "this is a test");
      ....
      myData[3]  =  new  Data("the third data",  "this is another test");/||
|How can I create the datatype to send, e.g., myData[0] and [1] to proc#1 and 
the remaining to the proc#2?|
|Thanks.|


_______________________________________________
users mailing list
us...@open-mpi.org
Subscription: http://www.open-mpi.org/mailman/listinfo.cgi/users
Link to this post: 
http://www.open-mpi.org/community/lists/users/2014/10/25480.php

import mpi.*;
import java.nio.*;
import static mpi.MPI.slice;

public class DerivedData
{
private static class MyStruct extends Struct
{
    private static final int MAX_LENGTH = 30;

    // This section defines the offsets of the fields.
    private int key    = addInt(),
                length = addInt(), // value length
                value  = addChar(MAX_LENGTH);

    // This method tells the super class how to create a data object.
    @Override protected Data newData()
    {
        return new Data();
    }

    // A Data object is a reference to a buffer section.
    // It permits read (puts) and write (gets) on the buffer
    private class Data extends Struct.Data
    {
        public int getKey()
        {
            return getInt(key);
        }

        public void putKey(int k)
        {
            putInt(key, k);
        }

        public String getValue()
        {
            int len = getInt(length); // Gets the value length.
            StringBuilder sb = new StringBuilder(len);

            // Deserialization
            for(int i = 0; i < len; i++)
                sb.append(getChar(value, i));

            return sb.toString();
        }

        public void putValue(String d)
        {
            int len = d.length();

            if(len > MAX_LENGTH)
                throw new AssertionError("Max length exceeded!");

            putInt(length, len); // Puts the value length on the buffer.

            // Serialization
            for(int i = 0; i < len; i++)
                putChar(value, i, d.charAt(i));
        }
    } // Data
} // MyStruct

public static void main(String args[]) throws MPIException
{
    MPI.Init(args);
    MPI.COMM_WORLD.setErrhandler(MPI.ERRORS_RETURN);
    int rank = MPI.COMM_WORLD.getRank();
    int size = MPI.COMM_WORLD.getSize();

    if(size != 3)
        throw new MPIException("I need 3 processes.");

    MyStruct myStruct = new MyStruct();

    if(rank == 0)
    {
        int length = 4;
        ByteBuffer buf = MPI.newByteBuffer(myStruct.getExtent() * length);
        System.out.println("Process 0:");

        for(int i = 0; i < length; i++)
        {
            MyStruct.Data d = myStruct.getData(buf, i);
            d.putKey(i);
            d.putValue("Value "+ i);
            System.out.println(d.getKey() +" : "+ d.getValue());
        }

        MPI.COMM_WORLD.send(buf, 2, myStruct.getType(), 1, 0);
        int off = 2 * myStruct.getExtent();
        MPI.COMM_WORLD.send(slice(buf, off), 2, myStruct.getType(), 2, 0);
    }
    else
    {
        int length = 2;
        ByteBuffer buf = MPI.newByteBuffer(myStruct.getExtent() * length);
        MPI.COMM_WORLD.recv(buf, length, myStruct.getType(), 0, 0);

        StringBuilder sb = new StringBuilder();
        sb.append("Process "+ rank +":\n");

        for(int i = 0; i < length; i++)
        {
            MyStruct.Data d = myStruct.getData(buf, i);
            sb.append(d.getKey() +" : "+ d.getValue() +"\n");
        }

        System.out.print(sb);
    }

    MPI.Finalize();
}

} // DerivedData

Reply via email to