package mpi; import mpi.*; import java.io.Serializable; import java.nio.ByteBuffer; public class MPIReducePlusIndex implements Serializable { private static final int indexOffset = 0; private static final int valueOffset = 4; static final int extent = 12; private ByteBuffer buffer; public MPIReducePlusIndex(int index, double value) { buffer = MPI.newByteBuffer(extent); buffer.putInt(index).putDouble(value); } public MPIReducePlusIndex(){} public int getIndex() { return buffer.getInt(0); } public double getValue() { return buffer.getDouble(4); } public ByteBuffer getBuffer() { return buffer; } private static final String MPI_USER_FUNCTION_MIN_WITH_INDEX_INVALID_DATA_TYPE = "MPI User Function - MinWithIndex: Invalid data type"; private static final String MPI_USER_FUNCTION_MAX_WITH_INDEX_INVALID_DATA_TYPE = "MPI User Function - MaxWithIndex: Invalid data type"; public static mpi.Op getMaxWithIndex() throws MPIException{ return new mpi.Op(new UserFunction() { @Override public void call(Object inVec, Object inOutVec, int count, Datatype datatype) throws MPIException { // Nothing to do here } @Override public void call(ByteBuffer in, ByteBuffer inOut, int count, Datatype datatype) throws MPIException { if (count != extent) { System.out.println( MPI_USER_FUNCTION_MAX_WITH_INDEX_INVALID_DATA_TYPE); MPI.COMM_WORLD.abort(1); } int inOutIndex = inOut.getInt(indexOffset); double inOutValue = inOut.getDouble(valueOffset); double inValue = in.getDouble(valueOffset); if (inOutIndex < 0 || inValue > inOutValue){ inOut.putInt(indexOffset,in.getInt(indexOffset)); inOut.putDouble(valueOffset,inValue); } } }, true); } public static mpi.Op getMinWithIndex() throws MPIException{ return new mpi.Op(new UserFunction() { @Override public void call(Object inVec, Object inOutVec, int count, Datatype datatype) throws MPIException { // Nothing to do here } @Override public void call(ByteBuffer in, ByteBuffer inOut, int count, Datatype datatype) throws MPIException { if (count != extent) { System.out.println( MPI_USER_FUNCTION_MIN_WITH_INDEX_INVALID_DATA_TYPE); MPI.COMM_WORLD.abort(1); } int inOutIndex = inOut.getInt(indexOffset); double inOutValue = inOut.getDouble(valueOffset); double inValue = in.getDouble(valueOffset); if (inOutIndex < 0 || inValue < inOutValue){ inOut.putInt(indexOffset,in.getInt(indexOffset)); inOut.putDouble(valueOffset,inValue); } } }, true); } public enum Op{ MIN_WITH_INDEX, MAX_WITH_INDEX } }