[mpj] 19/22: Imported Upstream version 0.42+dfsg
Andreas Tille
tille at debian.org
Wed May 11 06:46:57 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository mpj.
commit 3ad7d725fef79247be4747d7e9e97753e993e356
Author: Andreas Tille <tille at debian.org>
Date: Wed May 11 08:41:30 2016 +0200
Imported Upstream version 0.42+dfsg
---
CHANGELOG | 333 ++
debian/copyright => LICENSE.txt | 57 +-
README | 115 +
THIRDPARTYNOTICES.txt | 15 +
bin/mpjboot | 10 +
bin/mpjclean | 9 +
bin/mpjdaemon | 46 +
bin/mpjhalt | 8 +
bin/mpjinfo | 9 +
bin/mpjrun.sh | 97 +
bin/mpjstatus | 9 +
bin/runmpj.sh | 57 +
build.xml | 333 ++
conf/local2.conf | 8 +
conf/mpj16.conf | 22 +
conf/mpj2.conf | 8 +
conf/mpj32.conf | 38 +
conf/mpj4.conf | 10 +
conf/mpj64.conf | 70 +
conf/mpj8.conf | 14 +
conf/wrapper.conf | 109 +
debian/README.Debian | 40 -
debian/changelog | 48 -
debian/compat | 1 -
debian/control | 28 -
debian/libmpj-java.jlibs | 1 -
debian/patches/series | 1 -
debian/patches/use_debian_packaged_jars.patch | 145 -
debian/rules | 12 -
debian/source/format | 1 -
debian/watch | 3 -
doc/APICHANGES.txt | 55 +
doc/images/mpj-section.png | Bin 0 -> 7782 bytes
doc/images/mpj-section.svg | 2731 ++++++++++
doc/images/mpj-static.png | Bin 0 -> 4738 bytes
doc/images/mpj-static.svg | 2590 +++++++++
doc/javadocs/allclasses-frame.html | 35 +
doc/javadocs/allclasses-noframe.html | 35 +
doc/javadocs/constant-values.html | 187 +
doc/javadocs/deprecated-list.html | 111 +
doc/javadocs/help-doc.html | 208 +
doc/javadocs/index-all.html | 1039 ++++
doc/javadocs/index.html | 64 +
doc/javadocs/mpi/CartParms.html | 252 +
doc/javadocs/mpi/Cartcomm.html | 515 ++
doc/javadocs/mpi/Comm.html | 2364 +++++++++
doc/javadocs/mpi/Datatype.html | 783 +++
doc/javadocs/mpi/Errhandler.html | 184 +
doc/javadocs/mpi/GraphParms.html | 273 +
doc/javadocs/mpi/Graphcomm.html | 397 ++
doc/javadocs/mpi/Group.html | 748 +++
doc/javadocs/mpi/Intercomm.html | 335 ++
doc/javadocs/mpi/Intracomm.html | 1474 ++++++
doc/javadocs/mpi/MPI.html | 1375 +++++
doc/javadocs/mpi/MPIException.html | 253 +
doc/javadocs/mpi/Op.html | 356 ++
doc/javadocs/mpi/Prequest.html | 281 +
doc/javadocs/mpi/Request.html | 639 +++
doc/javadocs/mpi/ShiftParms.html | 239 +
doc/javadocs/mpi/Status.html | 354 ++
doc/javadocs/mpi/User_function.html | 283 +
doc/javadocs/mpi/package-frame.html | 36 +
doc/javadocs/mpi/package-summary.html | 197 +
doc/javadocs/mpi/package-tree.html | 154 +
doc/javadocs/overview-tree.html | 158 +
doc/javadocs/package-list | 1 +
doc/javadocs/resources/background.gif | Bin 0 -> 2313 bytes
doc/javadocs/resources/tab.gif | Bin 0 -> 291 bytes
doc/javadocs/resources/titlebar.gif | Bin 0 -> 10701 bytes
doc/javadocs/resources/titlebar_end.gif | Bin 0 -> 849 bytes
doc/javadocs/stylesheet.css | 474 ++
src/mpi/Band.java | 37 +
src/mpi/BandByte.java | 56 +
src/mpi/BandChar.java | 56 +
src/mpi/BandInt.java | 56 +
src/mpi/BandLong.java | 56 +
src/mpi/BandShort.java | 56 +
src/mpi/BandType.java.in | 55 +
src/mpi/BandWorker.java | 75 +
src/mpi/BasicType.java | 230 +
src/mpi/Bor.java | 49 +
src/mpi/BorByte.java | 70 +
src/mpi/BorChar.java | 70 +
src/mpi/BorInt.java | 70 +
src/mpi/BorLong.java | 70 +
src/mpi/BorShort.java | 70 +
src/mpi/BorType.java.in | 69 +
src/mpi/BorWorker.java | 80 +
src/mpi/Bxor.java | 48 +
src/mpi/BxorByte.java | 69 +
src/mpi/BxorChar.java | 69 +
src/mpi/BxorInt.java | 69 +
src/mpi/BxorLong.java | 69 +
src/mpi/BxorShort.java | 69 +
src/mpi/BxorType.java.in | 68 +
src/mpi/BxorWorker.java | 79 +
src/mpi/CartParms.java | 52 +
src/mpi/Cartcomm.java | 595 +++
src/mpi/Comm.java | 2469 +++++++++
src/mpi/Contiguous.java | 241 +
src/mpi/Datatype.java | 444 ++
src/mpi/Errhandler.java | 55 +
src/mpi/Freeable.java | 42 +
src/mpi/GatherPackerBoolean.java | 85 +
src/mpi/GatherPackerByte.java | 85 +
src/mpi/GatherPackerChar.java | 85 +
src/mpi/GatherPackerDouble.java | 85 +
src/mpi/GatherPackerFactory.java | 95 +
src/mpi/GatherPackerFloat.java | 85 +
src/mpi/GatherPackerInt.java | 85 +
src/mpi/GatherPackerLong.java | 85 +
src/mpi/GatherPackerObject.java | 85 +
src/mpi/GatherPackerShort.java | 85 +
src/mpi/GatherPackerType.java.in | 84 +
src/mpi/GenericPacker.java | 95 +
src/mpi/GraphParms.java | 44 +
src/mpi/Graphcomm.java | 155 +
src/mpi/Group.java | 464 ++
src/mpi/Indexed.java | 299 ++
src/mpi/Intercomm.java | 166 +
src/mpi/Intracomm.java | 1077 ++++
src/mpi/IntracommImpl.java | 506 ++
src/mpi/Land.java | 49 +
src/mpi/LandBoolean.java | 72 +
src/mpi/LandType.java.in | 71 +
src/mpi/LandWorker.java | 79 +
src/mpi/Lor.java | 49 +
src/mpi/LorBoolean.java | 71 +
src/mpi/LorType.java.in | 70 +
src/mpi/LorWorker.java | 79 +
src/mpi/Lxor.java | 47 +
src/mpi/LxorBoolean.java | 70 +
src/mpi/LxorType.java.in | 69 +
src/mpi/LxorWorker.java | 78 +
src/mpi/MPI.java | 468 ++
src/mpi/MPIException.java | 57 +
src/mpi/Max.java | 49 +
src/mpi/MaxByte.java | 69 +
src/mpi/MaxChar.java | 69 +
src/mpi/MaxDouble.java | 69 +
src/mpi/MaxFloat.java | 69 +
src/mpi/MaxInt.java | 69 +
src/mpi/MaxLong.java | 69 +
src/mpi/MaxShort.java | 69 +
src/mpi/MaxType.java.in | 68 +
src/mpi/MaxWorker.java | 80 +
src/mpi/Maxloc.java | 180 +
src/mpi/MaxlocType.java.in | 84 +
src/mpi/Min.java | 49 +
src/mpi/MinByte.java | 71 +
src/mpi/MinChar.java | 71 +
src/mpi/MinDouble.java | 71 +
src/mpi/MinFloat.java | 71 +
src/mpi/MinInt.java | 71 +
src/mpi/MinLong.java | 71 +
src/mpi/MinShort.java | 71 +
src/mpi/MinType.java.in | 70 +
src/mpi/MinWorker.java | 79 +
src/mpi/Minloc.java | 176 +
src/mpi/MinlocType.java.in | 83 +
src/mpi/MultistridedPacker.java | 77 +
src/mpi/MultistridedPackerBoolean.java | 182 +
src/mpi/MultistridedPackerByte.java | 182 +
src/mpi/MultistridedPackerChar.java | 182 +
src/mpi/MultistridedPackerDouble.java | 182 +
src/mpi/MultistridedPackerFactory.java | 95 +
src/mpi/MultistridedPackerFloat.java | 182 +
src/mpi/MultistridedPackerInt.java | 182 +
src/mpi/MultistridedPackerLong.java | 182 +
src/mpi/MultistridedPackerObject.java | 182 +
src/mpi/MultistridedPackerShort.java | 182 +
src/mpi/MultistridedPackerType.java.in | 181 +
src/mpi/NativeIntracomm.java | 1369 +++++
src/mpi/Op.java | 106 +
src/mpi/OpWorker.java | 42 +
src/mpi/Packer.java | 77 +
src/mpi/Prequest.java | 138 +
src/mpi/ProcTree.java | 116 +
src/mpi/Prod.java | 50 +
src/mpi/ProdByte.java | 68 +
src/mpi/ProdChar.java | 68 +
src/mpi/ProdDouble.java | 68 +
src/mpi/ProdFloat.java | 68 +
src/mpi/ProdInt.java | 68 +
src/mpi/ProdLong.java | 68 +
src/mpi/ProdShort.java | 68 +
src/mpi/ProdType.java.in | 67 +
src/mpi/ProdWorker.java | 78 +
src/mpi/PureIntracomm.java | 2097 ++++++++
src/mpi/Request.java | 551 ++
src/mpi/ShiftParms.java | 46 +
src/mpi/SimplePacker.java | 51 +
src/mpi/SimplePackerBoolean.java | 116 +
src/mpi/SimplePackerByte.java | 116 +
src/mpi/SimplePackerChar.java | 116 +
src/mpi/SimplePackerDouble.java | 116 +
src/mpi/SimplePackerFactory.java | 93 +
src/mpi/SimplePackerFloat.java | 116 +
src/mpi/SimplePackerInt.java | 116 +
src/mpi/SimplePackerLong.java | 116 +
src/mpi/SimplePackerObject.java | 116 +
src/mpi/SimplePackerShort.java | 116 +
src/mpi/SimplePackerType.java.in | 115 +
src/mpi/Status.java | 188 +
src/mpi/Struct.java | 544 ++
src/mpi/Sum.java | 48 +
src/mpi/SumByte.java | 69 +
src/mpi/SumChar.java | 69 +
src/mpi/SumDouble.java | 69 +
src/mpi/SumFloat.java | 69 +
src/mpi/SumInt.java | 69 +
src/mpi/SumLong.java | 69 +
src/mpi/SumShort.java | 69 +
src/mpi/SumType.java.in | 68 +
src/mpi/SumWorker.java | 78 +
src/mpi/User_function.java | 64 +
src/mpi/Vector.java | 338 ++
src/mpi/clean.pl | 63 +
src/mpi/generate.pl | 170 +
src/mpjbuf/Buddy1Buffer.java | 45 +
src/mpjbuf/Buddy1BufferFactory.java | 317 ++
src/mpjbuf/Buddy1FreeList.java | 69 +
src/mpjbuf/Buddy1RegionFreeList.java | 126 +
src/mpjbuf/Buddy2Buffer.java | 56 +
src/mpjbuf/Buddy2BufferFactory.java | 588 +++
src/mpjbuf/Buddy2FreeList.java | 96 +
src/mpjbuf/Buddy2Region.java | 67 +
src/mpjbuf/Buffer.java | 5480 ++++++++++++++++++++
src/mpjbuf/Buffer.java.in | 2101 ++++++++
src/mpjbuf/BufferConstants.java | 35 +
src/mpjbuf/BufferException.java | 58 +
src/mpjbuf/BufferFactory.java | 121 +
src/mpjbuf/BufferOverflowException.java | 39 +
src/mpjbuf/BufferUnderflowException.java | 53 +
src/mpjbuf/CustomMath.java | 212 +
src/mpjbuf/CustomObjectInputStream.java | 56 +
src/mpjbuf/DynamicBufferException.java | 48 +
src/mpjbuf/IllegalArgumentException.java | 53 +
src/mpjbuf/NIOBuffer.java | 859 +++
src/mpjbuf/NIOBuffer.java.in | 553 ++
src/mpjbuf/RawBuffer.java | 205 +
src/mpjbuf/RawBuffer.java.in | 96 +
src/mpjbuf/SectionSizeMismatchException.java | 52 +
src/mpjbuf/Type.java | 136 +
src/mpjbuf/TypeMismatchException.java | 52 +
src/mpjbuf/WrongStateException.java | 53 +
src/mpjbuf/clean.pl | 11 +
src/mpjbuf/generate.pl | 61 +
src/mpjdev/Comm.java | 118 +
src/mpjdev/CompletionHandler.java | 46 +
src/mpjdev/Constants.java | 66 +
src/mpjdev/Group.java | 183 +
src/mpjdev/MPJDev.java | 119 +
src/mpjdev/MPJDevException.java | 46 +
src/mpjdev/MPJException.java | 34 +
src/mpjdev/Request.java | 308 ++
src/mpjdev/Status.java | 103 +
src/mpjdev/javampjdev/Comm.java | 1238 +++++
src/mpjdev/javampjdev/Group.java | 732 +++
src/mpjdev/javampjdev/MPJDev.java | 143 +
src/mpjdev/natmpjdev/Comm.java | 502 ++
src/mpjdev/natmpjdev/Group.java | 234 +
src/mpjdev/natmpjdev/Intercomm.java | 60 +
src/mpjdev/natmpjdev/Intracomm.java | 925 ++++
src/mpjdev/natmpjdev/MPJDev.java | 97 +
src/mpjdev/natmpjdev/NativeRecvRequest.java | 125 +
src/mpjdev/natmpjdev/NativeRequest.java | 74 +
src/mpjdev/natmpjdev/NativeSendRequest.java | 90 +
src/mpjdev/natmpjdev/lib/CMakeLists.txt | 25 +
src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.c | 976 ++++
src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.h | 189 +
src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.c | 437 ++
src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.h | 137 +
.../natmpjdev/lib/mpjdev_natmpjdev_Intercomm.c | 68 +
.../natmpjdev/lib/mpjdev_natmpjdev_Intercomm.h | 21 +
.../natmpjdev/lib/mpjdev_natmpjdev_Intracomm.c | 650 +++
.../natmpjdev/lib/mpjdev_natmpjdev_Intracomm.h | 134 +
.../lib/mpjdev_natmpjdev_NativeRecvRequest.c | 283 +
.../lib/mpjdev_natmpjdev_NativeRecvRequest.h | 37 +
.../lib/mpjdev_natmpjdev_NativeSendRequest.c | 153 +
.../lib/mpjdev_natmpjdev_NativeSendRequest.h | 37 +
src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_shared.h | 113 +
src/runtime/common/IOHelper.java | 430 ++
src/runtime/common/MPJProcessTicket.java | 480 ++
src/runtime/common/MPJRuntimeException.java | 56 +
src/runtime/common/MPJUtil.java | 165 +
src/runtime/common/MPJXml.java | 259 +
src/runtime/common/RTConstants.java | 66 +
src/runtime/daemon/ConnectionManager.java | 83 +
src/runtime/daemon/HybridStarter.java | 313 ++
src/runtime/daemon/JarClassLoader.java | 140 +
src/runtime/daemon/MPJDaemon.java | 209 +
src/runtime/daemon/MultithreadStarter.java | 129 +
src/runtime/daemon/OutputHandler.java | 89 +
src/runtime/daemon/PortManager.java | 98 +
src/runtime/daemon/PortManagerThread.java | 114 +
src/runtime/daemon/PortRequesterThread.java | 88 +
src/runtime/daemon/ProcessArgumentsManager.java | 486 ++
src/runtime/daemon/ProcessLauncher.java | 268 +
src/runtime/daemon/Wrapper.java | 142 +
src/runtime/daemonmanager/BootThread.java | 123 +
src/runtime/daemonmanager/CLOptions.java | 270 +
src/runtime/daemonmanager/CleanUpThread.java | 69 +
src/runtime/daemonmanager/DMConstants.java | 80 +
src/runtime/daemonmanager/DMMessages.java | 70 +
src/runtime/daemonmanager/DMThread.java | 45 +
src/runtime/daemonmanager/DMThreadUtil.java | 103 +
src/runtime/daemonmanager/DaemonUtil.java | 126 +
src/runtime/daemonmanager/HaltThread.java | 74 +
src/runtime/daemonmanager/MPJBoot.java | 58 +
src/runtime/daemonmanager/MPJCleanup.java | 55 +
src/runtime/daemonmanager/MPJDaemonManager.java | 83 +
src/runtime/daemonmanager/MPJHalt.java | 56 +
src/runtime/daemonmanager/MPJProcessInfo.java | 18 +
src/runtime/daemonmanager/MPJStatus.java | 55 +
src/runtime/daemonmanager/ProcessInfoThread.java | 33 +
src/runtime/daemonmanager/StatusThread.java | 62 +
src/runtime/daemonmanager/WinBoot.java | 64 +
src/runtime/daemonmanager/WinHalt.java | 30 +
src/runtime/starter/IOMessagesThread.java | 90 +
src/runtime/starter/MPJRun.java | 885 ++++
src/runtime/starter/MulticoreDaemon.java | 338 ++
src/runtime/starter/MulticoreStarter.java | 355 ++
src/xdev/Device.java | 270 +
src/xdev/ProcessID.java | 104 +
src/xdev/XDevException.java | 58 +
src/xdev/hybdev/HYBDevice.java | 1092 ++++
src/xdev/hybdev/HYBRecvRequest.java | 105 +
src/xdev/hybdev/HYBRequest.java | 163 +
src/xdev/mxdev/MXDevice.java | 534 ++
src/xdev/mxdev/MXProcessID.java | 53 +
src/xdev/mxdev/MXRecvRequest.java | 116 +
src/xdev/mxdev/MXRequest.java | 98 +
src/xdev/mxdev/MXSendRequest.java | 81 +
src/xdev/mxdev/lib/mxdev_const.h | 28 +
src/xdev/mxdev/lib/xdev_mxdev_MXDevice.c | 1341 +++++
src/xdev/mxdev/lib/xdev_mxdev_MXDevice.h | 115 +
src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.c | 297 ++
src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.h | 38 +
src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.c | 206 +
src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.h | 38 +
src/xdev/niodev/ConfigReader.java | 243 +
src/xdev/niodev/NIODevice.java | 4091 +++++++++++++++
src/xdev/niodev/NIORecvRequest.java | 168 +
src/xdev/niodev/NIORequest.java | 162 +
src/xdev/niodev/NIOSendRequest.java | 117 +
src/xdev/niodev/ProcTree.java | 115 +
src/xdev/smpdev/ConfigReader.java | 244 +
src/xdev/smpdev/SMPDevProcess.java | 59 +
src/xdev/smpdev/SMPDevice.java | 372 ++
src/xdev/smpdev/SMPDeviceImpl.java | 1047 ++++
src/xdev/smpdev/SMPRecvRequest.java | 71 +
src/xdev/smpdev/SMPRequest.java | 316 ++
src/xdev/smpdev/SMPSendRequest.java | 112 +
src/xdev/smpdev/init_smp.java | 43 +
355 files changed, 82568 insertions(+), 315 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..cf50b7e
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,333 @@
+Version 0.42
+------------
+
+1. This release mainly introduces updated runtime system for MPJ Express to
+ support parallel job execution by multiple users. Following are major changes
+ to support parallel job execution in MPJ Express.
+ a. Addition of multi-threaded Job launcher in MPJ Daemon. Whenever a
+ process request posted to MPJ Daemon it launches a new thread to execute it.
+
+ b. Java NIO Sockets are replaced with Java I/O Sockets in both MPJ Daemon
+ and MPJRun code.
+
+ c. Separate channels are introduced for I/O messages delivery to each job
+ executer.
+
+ d. Optimized mechanism for port allocation to processes for inter-process
+ communication while distributing job on cluster. Read/Write ports are
+ now assigned dynamically.
+
+ e. Dynamically allocated ports are now written in mpjdev.conf file and
+ NIODevice reads both ports from mpjdev.conf
+
+ f. XML based process ticket has been introduced to send processes information
+ between MPJRun and MPJDaemon.
+
+2. This release also introduces support for using MPJ Express on non-shared
+ file system.
+
+3. In this release dependency of "Java Service Wrapper Project" has been removed
+ and a new mechanism to launch daemons has been introduced. To support this new
+ mechanism some useful scripts has also been added in MPJ Express.
+ * mpjboot <machines_files>: To start MPJ daemons
+ * mpjhalt <machines_files>: To stop MPJ daemons
+ * mpjstatus <machines_files>: To check current status of MPJ daemons
+ * mpjinfo <machines_files>: To get information about Java process
+ * mpjclean <machines_files>: To kill MPJ daemons
+ * mpjdaemon.sh <query> <hostnames>: To perform operations on MPJ daemons manually
+ like boot, halt, status
+ * mpjdaemon.bat <query>: Windows version of mpjdaemon.
+
+4. Changes in individual files and addition of new file:
+ (+ indicates addition of a new file or directory)
+ $MPJ_HOME/
+ build.xml - Added support for compiling $MPJ_HOME/src/common and daemonmanager
+ README-win.txt
+ README
+ CHANGELOG - This file
+ LICENSE.txt - License for Java Service Wrapper Project removed
+ THIRDPARTYLICENSES - modified to add Apache License
+ +THIRDPARTYNOTICES - Apache License Notice for each Apache project used
+ $MPJ_HOME/bin/
+ mpjboot.sh - modified to start daemons using new mechanism. Dependency of
+ Java Service Wrapper Project removed
+ mpjhalt.sh - modified to stop daemons using new mechanism.
+ mpjdaemon.bat - modified to handle daemon operations on Windows OS
+ +mpjstatus.sh
+ +mpjclean.sh
+ +mpjinfo.sh
+ +mpjdaemon.sh
+ -wrapper.exe
+ -daemon_linux_ppc_64
+ -daemon_linux_x86_32
+ -daemon_linux_x86_64
+ -daemon_macosx
+ -daemon_macosx_ppc_32
+ -daemon_solaris_sparc_32
+ -daemon_solaris_sparc_64
+ -mpjdaemon_linux_ppc_64
+ -mpjdaemon_linux_x86_32
+ -mpjdaemon_linux_x86_64
+ -mpjdaemon_macosx
+ -mpjdaemon_macosx_ppc_32
+ -mpjdaemon_solaris_sparc_32
+ -mpjdaemon_solaris_sparc_64
+ -starter.sh
+ -starter.bat
+ -installmpjd-windows.bat
+ -uninstallmpjd-windows.bat
+
+ $MPJ_HOME/conf/
+ wrapper.conf - modified to add Logfile parameters for MPJRun and MPJDaemon.
+ App parameter for PortManager also added
+
+ $MPJ_HOME/lib/
+ +commons-cli-1.2.jar
+ +commons-codec-1.8.jar
+ +commons-io-2.4.jar
+
+ $MPJ_HOME/doc/
+ linuxguide.pdf
+ windowsguide.pdf
+
+ $MPJ_HOME/src/runtime/
+ +common (new directory)
+ +IOHelper.java
+ +MPJProcessTicket.java
+ +MPJUtil.java
+ +MPJXml.java
+ +RTConstants.java
+ MPJRuntimeException.java - moved from /runtime/ Package to /common/
+
+ +daemonmanager (new directory)
+ +BootThread.java
+ +CleanUpThread.java
+ +CLOptions.java
+ +DaemonUtil.java
+ +DMConstants.java
+ +DMMessages.java
+ +DMThread.java
+ +DMThreadUtil.java
+ +HaltThread.java
+ +MPJBoot.java
+ +MPJCleanup.java
+ +MPJDaemonManager.java
+ +MPJHalt.java
+ +MPJProcessInfo.java
+ +MPJStatus.java
+ +ProcessInfoThread.java
+ +StatusThread.java
+ +WinBoot.java
+ +WinHalt.java
+
+ /daemon
+ MPJDaemon.java - modified to work with new runtime system
+ +ConnectionManager
+ +OutputHandler
+ +PortManager
+ +PortManagerThread
+ +PortRequesterThread
+ +ProcessArgumentsManager
+ +ProcessLauncher
+ -HybridDaemon.java
+ -WrapperSimpleApp.java
+ -MPJProcessStream.java
+
+ /starter
+ MPJRun.java - modified to work with new runtime system
+ +IOMessageThread.java
+ -PortScan.java
+
+
+Version 0.41
+------------
+
+1. This release mainly introduces support for using a Native MPI Implementation
+ from MPJ Express. We call this native device.
+
+2. This release also introduces support for MPJ Express Profiler. The Profiler
+ generates profiles and traces of MPJ Express applications. Currently the
+ Profiler does not support native device.
+
+3. Major changes: $MPJ_HOME/src/mpjdev is now abstract and provides two implementations
+ i) javampjdev and ii) natmpjdev. Intracomm is now a wrapper class that either
+ uses PureIntracomm (for pure Java devices) or NativeIntracomm (for native decive).
+
+4. libnatmpjdev.so is a C JNI wrapper library to call native MPI library.
+ The source code is placed in $MPJ_HOME/src/mpjdev/natmpjdev/lib
+
+5. Some bug fixes in runtime.
+
+6. Changes in individual files and addition of new file:
+ (+ indicates addition of a new file or directory)
+ $MPJ_HOME/
+ build.xml - Added support for compiling $MPJ_HOME/src/mpjdev/natmpjdev and javampjdev
+ README-win.txt
+ README
+ CHANGELOG - This file
+ $MPJ_HOME/test/
+ +nativetest (new directory)
+ +compile.sh
+ +runtest.sh
+ +compile.bat
+ +runtest.bat
+ mpi - Added main() method in testcases
+ mpjdev - Added main() method in Buffer testcases
+ $MPJ_HOME/bin/
+ mpjrun.sh - modified to detect -dev native, if found then calls
+ mpirun instead of invoking $MPJ_HOME/lib/starter.jar
+ $MPJ_HOME/doc/
+ linuxguide.pdf
+ windowsguide.pdf
+ RunningandDebuggingMPJExpressWithEclipse.pdf (Renamed)
+ +MPJExpressProfilerUserGuide.pdf
+
+ $MPJ_HOME/src/runtime/
+ /starter/MPJRun.java (version 0.41)
+ $MPJ_HOME/mpjbuf/
+ NIOBuffer.java.in - Now using allocateDirect()
+ Buffer.java.in - Added a new method public int getCapacity()
+ used in mpjdev.natmpjdev.Comm.recv() as count
+ $MPJ_HOME/mpi/
+ MPI
+ Comm
+ Intracomm
+ +IntracommImpl
+ +NativeIntracomm
+ +PureIntracomm
+ Datatype
+ Group
+ Request
+ Intercomm
+ Op - a new field opCode is introduced. This helps distinguish MPJ Express
+ Operators from Native MPI_Operators
+ Max - Initializing this.opCode = mpjdev.Constants.MAX_CODE
+ Min - Initializing this.opCode = mpjdev.Constants.MIN_CODE
+ Sum - Initializing this.opCode = mpjdev.Constants.SUM_CODE
+ Prod - Initializing this.opCode = mpjdev.Constants.PROD_CODE
+ Land - Initializing this.opCode = mpjdev.Constants.LAND_CODE
+ Band - Initializing this.opCode = mpjdev.Constants.BAND_CODE
+ Lor - Initializing this.opCode = mpjdev.Constants.LOR_CODE
+ Bor - Initializing this.opCode = mpjdev.Constants.BOR_CODE
+ Lxor - Initializing this.opCode = mpjdev.Constants.LXOR_CODE
+ Bxor - Initializing this.opCode = mpjdev.Constants.BXOR_CODE
+
+ $MPJ_HOME/mpjdev/
+ Comm - Abstracted
+ +Constants - Contains Macros and Flags
+ Group - Abstracted
+ MPJDev - Abstracted
+ MPJDevException - Provided a comments section telling that currently it throws
+ xdevEception so need to think about it for natmpjdev since
+ natmpjdev doesn't implement xdev.
+ Request - Modified to check if native device then donot call dev.peek() method
+ Status - source is now initialized as -1 to support native device completion handler,
+ if its set (which means > -1) then the operation is complete
+
+ +javampjdev/
+ +Comm - For Pure Java
+ +Group - For Pure Java
+ +MPJDev - For Pure Java
+ +natmpjdev/
+ +Comm - For native device
+ +Group - For native device
+ +Intercomm - For native device
+ +Intracomm - For native device
+ +MPJDev - For native device
+ +NativeRequest - For native device
+ +NativeRecvRequest - For native device
+ +NativeSendRequest - For native device
+
+ +lib/
+ +CMakeLists.txt - For CMake
+ +mpjdev_natmpjdev_Comm.c
+ +mpjdev_natmpjdev_Comm.h
+ +mpjdev_natmpjdev_Group.c
+ +mpjdev_natmpjdev_Group.h
+ +mpjdev_natmpjdev_Intercomm.c
+ +mpjdev_natmpjdev_Intercomm.h
+ +mpjdev_natmpjdev_Intracomm.c
+ +mpjdev_natmpjdev_Intracomm.h
+ +mpjdev_natmpjdev_NativeRecvRequest.c
+ +mpjdev_natmpjdev_NativeRecvRequest.h
+ +mpjdev_natmpjdev_NativeSendRequest.c
+ +mpjdev_natmpjdev_NativeSendRequest.h
+ +mpjdev_natmpjdev_shared.h
+
+Version 0.40
+------------
+
+1. This release mainly introduces support for MPJ Express Debugger in MPJ
+ Express Project. MPJ Express Debugger is an Eclipse based plugin.
+
+2. MPJ Express Debugger support added in MPJ Express Runtime. WriteFile
+ method is added in MPJRun.java to write configuration file in user
+ directory for working of MPJ Express Debugger.
+
+Version 0.39
+------------
+
+1. This release mainly introduces a new MPJ Express device 'hybdev' that
+ supports hybrid parallelism on cluster of multicore machines. The device,
+ hybdev, transparently achieves hybrid parallelism. It does not require
+ code rewriting effort for new and existing MPJ Express applications. It
+ is developed by Ansar Javed and Mohsan Jameel.
+
+2. In xdev.Device.java an overloaded abstract method 'iprove' is added
+ public abstract mpjdev.Status iprobe (ProcessID srcID, ProcessID dstID,
+ int tag, int context);
+ It is used by hybdev to probe messages in network device.
+
+3. In xdev.Device interface an abstract method 'iprobeAndFetch' is added
+ public abstract mpjdev.Status iprobeAndFetch (ProcessID srcID,
+ ProcessID dstID, int tag, int context, mpjbuf.Buffer buf);
+ It is required for Hybrid device to provide support for wildcard messages.
+
+4. ProcTree.java is added in xdev/niodev package, previously it was imported
+ from MPI layer.
+
+5. Add and remove methods of ArrQueue and RecvQueue in niodev are updated.
+ The message addition and removal process in the queues is based on the
+ message key
+ Now key consists of Source, Destination, tag, context.
+
+6. Hybrid device support is added in runtime classes i.e. MPJDaemon and MPJRun.
+ Two new Java classes are added in runtime as well.
+ a. HybridDaemon
+ b. HybridStarter
+
+Version 0.38
+------------
+
+1. Fixed a bug in the mpjrun module that appends null as the host name
+ in the configuration file. Thanks to Pete Christopher for
+ identifying this bug. 14/1/2011
+
+Version 0.37
+------------
+
+1. Added the executing and debugging tutorial of MPJ Express applications
+ using Eclipse IDE. 14/5/2010
+2. Modified the runtime to get rid of the shared directory requirement
+ between the starter (head node) and daemons (running on compute nodes).
+ This paper is coded by Rizwan Hanif and Amjad Aziz. 6/1/2011
+3. Fixed a bug that causes daemons to crash on Windows boxes. 4/1/2011
+
+Version 0.36
+------------
+
+1. Fixed the mpjboot error for Mac OS X reported by Ed Baskerville. The
+ mpjboot script used x86 binaries on Mac OS X, which obviously was incorrect.
+ 18/3/2010
+2. The MPJ Express runtime could not start more than 100 processes.
+ Guillermo Lopez Taboada identified and proposed and a fix for this.
+ 18/3/2010
+3. Fixed the bug which broke test cases when executed with odd number of
+ processes. Many thanks to Guillermo Lopez Taboada for discovering
+ this bug. 18/3/2010
+4. Made changes to the MPJ Express runtime system and got rid of a couple
+ of internal classes.
+5. On some clusters, users complained that MPJ Express took abnormally
+ long amount of time to bootstrap. We have fixed this bug in this release.
+ 1/4/2010
+6. Got rid of the Jetty dependency. 9/4/2010
diff --git a/debian/copyright b/LICENSE.txt
similarity index 56%
rename from debian/copyright
rename to LICENSE.txt
index a497538..3427316 100644
--- a/debian/copyright
+++ b/LICENSE.txt
@@ -1,35 +1,18 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: MPJ Express
-Upstream-Contact: mpj-user at lists.reading.ac.uk
-Source: http://sourceforge.net/projects/mpjexpress/files/
-Files-Excluded:
- bin/daemon*
- bin/*.bat
- bin/*.exe
- *.dll
- *macosx*
- *solaris*
- *.pdf
- libwrapper*
- lib/*
- test/
- THIRDPARTYLICENSES.txt
- README-win.txt
+1. The license statement
+
+ The MIT License
-Files: *
-Copyright: 2004 - 2007 Distributed Systems Group, University of Portsmouth,
- Aamir Shafi <aamir.shafi at seecs.edu.pk>
- Bryan Carpenter <bryan.carpenter at port.ac.uk>
- Mark Baker <mark.baker at computer.org>
- Guillermo Lopez Taboada <taboada at udc.es>
-License: MIT
+ Copyright (c) 2005 - 2014
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2014)
+ 3. Bryan Carpenter (2005 - 2014)
+ 4. Mark Baker (2005 - 2011)
+
+ The bulk of code in this distribution was developed by the Distributed Systems
+ Group at the University of Portsmouth. Some sections of the code like
+ the buffering API and derived datatypes include contributions developed at
+ the Community Grids Lab at Indiana University.
-License: MIT
- The bulk of code in this distribution was developed by the Distributed Systems
- Group at the University of Portsmouth. Some sections of the code like
- the buffering API and derived datatypes include contributions developed at
- the Community Grids Lab at Indiana University.
- .
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
@@ -37,10 +20,10 @@ License: MIT
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
- .
+
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- .
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
@@ -49,6 +32,10 @@ License: MIT
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-Files: debian/*
-Copyright: © 2012 Andreas Tille <tille at debian.org>
-License: MIT
+2. MPJ uses following third party software developed by Apache:
+ a. commons-cli-1.2
+ b. commons-codec-1.8
+ c. commons-io-2.4
+ The license for these projects can be seen at
+ $MPJ_HOME/THIRDPARTYLICENSES file and notice can be seen at
+ $MPJ_HOME/THIRDPARTYNOTICES file.
diff --git a/README b/README
new file mode 100644
index 0000000..390047c
--- /dev/null
+++ b/README
@@ -0,0 +1,115 @@
+QuickStart Guide: Running MPJ Express on UNIX/Linux/Mac platform
+ Last Updated: Wed May 07 12:44:20 PKT 2014
+ Version 0.42
+
+Introduction
+============
+
+MPJ Express is a reference implementation of the mpiJava 1.2 API, which
+is an MPI-like API for Java defined by the Java Grande forum.
+
+MPJ Express can be configured in two ways:
+
+1. Multicore Configuration: This configuration is used by developers who want
+ to execute their parallel Java applications on multicore or shared
+ memory machines (laptops and desktops).
+
+2. Cluster Configuration: This configuration is used by developers who want to
+ execute their parallel Java applications on distributed memory platforms
+ including clusters and network of computers. There are four options in the
+ cluster configuration.
+
+ i) niodev - uses Java NIO Sockets
+ ii) mxdev - uses Myrinet eXpress (MX) library for Myrinet networks
+ iii) hybdev - for clusters of multicore processors
+ iv) native - uses a native MPI library (like MPICH, MVAPICH, Open MPI)
+
+
+This document contains steps to help you execute your first MPJ Express program
+on UNIX/Linux/Mac platforms. Windows users should consult README-win.txt.
+
+Pre-requisites
+==============
+
+1. Java 1.6 (stable) or higher (Mandatory)
+2. Apache ant 1.6.2 or higher (Optional)
+3. Perl (Optional)
+4. Native MPI library (Optional): Native MPI library such as MPICH, MVAPICH
+ or Open MPI is required for running MPJ Express in cluster configuration
+ with native device.
+5. CMake (Optional): CMake is used for generating Makefile to compile native
+ JNI C code
+
+Running MPJ Express Programs in the Multicore Configuration
+===========================================================
+
+1. Download MPJ Express and unpack it.
+2. Set MPJ_HOME and PATH environmental variables:
+ export MPJ_HOME=/path/to/mpj/
+ export PATH=$PATH:$MPJ_HOME/bin
+ (These above two lines can be added to ~/.bashrc)
+3. Write your MPJ Express program (HelloWorld.java) and save it.
+4. Compile: javac -cp .:$MPJ_HOME/lib/mpj.jar HelloWorld.java
+5. Execute: mpjrun.sh -np 4 HelloWorld
+
+Running MPJ Express Programs in the Cluster Configuration
+=========================================================
+
+1. Assuming you have completed step 1 to 4 of the Multicore Configuration.
+2. Write a machines file (name it "machines") stating host names or IP
+ addresses of all machines involved in the parallel execution.
+3. Execution:
+-- For niodev, hybdev and mxdev
+ i) Start daemons: mpjboot machines
+ ii) Execute: mpjrun.sh -np 4 -dev niodev HelloWorld
+ -- For -dev <device> here device can be niodev,
+ hybdev or mxdev
+ iii) Stop daemons: mpjhalt machines
+-- For native deive
+ i) Compile JNI wrapper library:
+ a) Make sure cmake (2.6 or above) is installed on the system
+ b) Make sure a native MPI library is installed on the system
+ and working. To install MPICH for example go to
+ http://www.mpich.org/downloads/ and download the native MPI
+ library, install and make sure that its working.
+ c) Create build directory: cd $MPJ_HOME/src/natmpjdev/lib;
+ mkdir build
+ d) Generate Makefile using cmake: cmake ..
+ e) make: make
+ f) install: make install
+ ii) Execute: mpjrun.sh -np 4 -dev native HelloWorld
+
+For detials read the linuxguide.pdf that can be found in $MPJ_HOME/doc
+
+Known Issues
+============
+
+1. One of the known issues of MPJ Express in cluster configuration is incorrect
+ working directroy. This issue is reported on cluster build using Rocks
+ clusters. MPJRun module of MPJ Express reads the current directory i.e. user
+ directory using System.getProperty("user.dir") It should retrun same path as
+ Unix 'pwd' command. But it is not giving same result. As a manual work
+ around for this issue is to use -wdir switch in mpjrun command and giving
+ path to the current directory where HelloWorld is placed i.e.
+ mpjrun.sh -np 4 -dev niodev -wdir /export/home/aamir/projects/mpj-user/ HelloWorld
+
+Additional Documentation
+========================
+
+For more details, see $MPJ_HOME/doc/linuxguide.pdf
+
+Contact and Support
+===================
+
+In case you run into issues please consult $MPJ_HOME/doc/linuxguide.pdf. If
+your query/problem is still not resolved, contact us by emailing:
+
+1. MPJ Express mailing list: https://lists.sourceforge.net/lists/listinfo/mpjexpress-users
+2. Aamir Shafi (aamir.shafi at seecs.edu.pk)
+3. Mohsan Jameel (mohsan.jameel at seecs.edu.pk)
+4. Bryan Carpenter (bryan.carpenter at port.ac.uk)
+5. Muhammad Ansar Javed (muhammad.ansar at seecs.edu.pk)
+6. Bibrak Qamar (bibrak.qamar at seecs.edu.pk)
+7. Aleem Akhtar (09bicseaasif at seecs.edu.pk)
+
+
diff --git a/THIRDPARTYNOTICES.txt b/THIRDPARTYNOTICES.txt
new file mode 100644
index 0000000..4331861
--- /dev/null
+++ b/THIRDPARTYNOTICES.txt
@@ -0,0 +1,15 @@
+ =========================================================================
+ == NOTICE file for use with the Apache License, Version 2.0 ==
+ =========================================================================
+
+Apache Commons CLI
+Copyright 2001-2009 The Apache Software Foundation
+
+Apache Commons Codec
+Copyright 2003-2014 The Apache Software Foundation
+
+Apache Commons IO
+Copyright 2012-2014 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
\ No newline at end of file
diff --git a/bin/mpjboot b/bin/mpjboot
new file mode 100755
index 0000000..0ce0cef
--- /dev/null
+++ b/bin/mpjboot
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: mpjboot <machines_file>";
+ exit 127
+fi
+
+port=`grep wrapper.app.parameter.2 $MPJ_HOME/conf/wrapper.conf |cut -d = -f2`
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar -boot -p $port -m "$@"
diff --git a/bin/mpjclean b/bin/mpjclean
new file mode 100755
index 0000000..170bad2
--- /dev/null
+++ b/bin/mpjclean
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: mpjclean <machines_file>";
+ exit 127
+fi
+
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar -clean -m "$@"
diff --git a/bin/mpjdaemon b/bin/mpjdaemon
new file mode 100755
index 0000000..b121f01
--- /dev/null
+++ b/bin/mpjdaemon
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+if [ $# -eq 0 ];
+ then
+ echo "Usage: mpjdaemon <query> <hostnames>";
+ echo "query=<-boot>: Start MPJ Express daemons";
+ echo "query=<-halt>: Stop MPJ Express daemons";
+ echo "query=<-status>: Display status of MPJ Express daemons";
+ echo "query=<-info>: Display all Java process";
+ echo "query=<-clean>: Clean all Java process";
+ echo "hostname: Default Localhost";
+ echo "";
+ echo "example: mpjdaemon -boot host1 host2";
+ echo "";
+ exit 127
+else
+ if [ $1 != "-boot" ] && [ $1 != "-halt" ] && [ $1 != "-status" ] && [ $1 != "-clean" ] && [ $1 != "-info" ] ;
+ then
+ echo "Usage: mpjdaemon <query> <hostnames>";
+ echo "query=<-boot>: Start MPJ Express daemons";
+ echo "query=<-halt>: Stop MPJ Express daemons";
+ echo "query=<-status>: Display status of MPJ Express daemons";
+ echo "query=<-info>: Display all Java process";
+ echo "query=<-clean>: Clean all Java process";
+ echo "hostname: Default Localhost";
+ echo "";
+ echo "example: mpjdaemon -boot host1 host2";
+ echo "";
+ exit 127
+
+ else
+ query="$1"
+ shift;
+ fi
+fi
+
+if [ $# -eq 0 ];
+ then
+ hostnames='localhost'
+else
+ hostnames="$@"
+fi
+
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar $query -hosts $hostnames
+
diff --git a/bin/mpjhalt b/bin/mpjhalt
new file mode 100755
index 0000000..f7c7ed1
--- /dev/null
+++ b/bin/mpjhalt
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: mpjhalt <machines_file>";
+ exit 127
+fi
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar -halt -m "$@"
diff --git a/bin/mpjinfo b/bin/mpjinfo
new file mode 100755
index 0000000..abb4abd
--- /dev/null
+++ b/bin/mpjinfo
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: mpjinfo <machines_file>";
+ exit 127
+fi
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar -info -m "$@"
+
diff --git a/bin/mpjrun.sh b/bin/mpjrun.sh
new file mode 100755
index 0000000..6d55fd8
--- /dev/null
+++ b/bin/mpjrun.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+allArguments="$@"
+
+#First check if its native?
+IS_NATIVE="false"
+for i in $@; do
+ if [ "$i" == "native" ]; then
+ IS_NATIVE="true"
+ fi
+done
+
+if [ "$IS_NATIVE" == "false" ]; then
+ # use javampjdev
+ java -jar $MPJ_HOME/lib/starter.jar "$@"
+
+else
+ # use natmpjdev
+echo "MPJ Express (0.41) is started in cluster configuration with native device"
+MACHINESFILE=""
+CP=$MPJ_HOME/lib/mpj.jar
+for i in $@; do
+#echo "i = $i"
+ case $i in
+ -np)
+ # assign number of processes np value to variable NP
+
+ shift;
+ NP="$1"
+ #echo "-np = $NP"
+ shift;
+ ;;
+ -dev)
+ # assign device dev value to variable DEV
+ shift;
+ DEV="$1"
+ #echo "-dev = $DEV"
+ shift;
+ ;;
+ -machinesfile)
+ # assign machinesfile value to variable MACHINESFILE
+ shift;
+ MACHINESFILE="$1"
+ #echo "-machinesfile = $MACHINESFILE"
+ shift;
+ ;;
+ -wdir)
+ # assign working directory path value to variable WDIR
+ shift;
+ WDIR="$1"
+ #echo "-wdir = $WDIR"
+ shift;
+ ;;
+ -cp)
+ # assign classpath value to variable CP
+ shift;
+ CP=$CP:"$1"
+ #echo "-wdir = $WDIR"
+ shift;
+ ;;
+ -Djava.library.path=*)
+ # assign JVM argument -Djava.library.path value to variable DJAVA_LIBRARY_PATH
+ oldIFS=$IFS
+ export IFS="="
+ line="$1"
+ for path in $line; do
+ # echo "$path"
+ DJAVA_LIBRARY_PATH="$path"
+ done
+ IFS=$oldIF
+ #DJAVA_LIBRARY_PATH="$path"
+ #echo "-Djava.library.path = $DJAVA_LIBRARY_PATH"
+ shift;
+ ;;
+
+ esac
+done
+
+
+CLASS_NAME=$1
+shift;
+APP_ARGUMENTS=$@
+
+DJAVA_LIBRARY_PATH=$DJAVA_LIBRARY_PATH:"$MPJ_HOME/lib"
+
+MPIRUN_ARGS=" -np $NP";
+if [ "$MACHINESFILE" == "" ]; then
+ MPIRUN_ARGS="$MPIRUN_ARGS";
+else
+ MPIRUN_ARGS="$MPIRUN_ARGS -machinefile $MACHINESFILE";
+fi
+
+COMMAND_TO_RUN="mpirun $MPIRUN_ARGS java -cp $CP:. -Djava.library.path=$DJAVA_LIBRARY_PATH $CLASS_NAME 0 0 $DEV $APP_ARGUMENTS"
+#run the command
+$COMMAND_TO_RUN
+
+fi
+
diff --git a/bin/mpjstatus b/bin/mpjstatus
new file mode 100755
index 0000000..43caf7c
--- /dev/null
+++ b/bin/mpjstatus
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: mpjstatus <machines_file>";
+ exit 127
+fi
+
+java -jar $MPJ_HOME/lib/daemonmanager.jar -status -m "$@"
+
diff --git a/bin/runmpj.sh b/bin/runmpj.sh
new file mode 100755
index 0000000..662e2ac
--- /dev/null
+++ b/bin/runmpj.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#set -x
+
+if [ $# -ne 2 ]; then
+ echo "Usage: runmpj.sh <conf_file> <jar_file>[OR]<class_file>";
+ echo " For e.g. runmpj.sh ../conf/mpj2.conf ../lib/test.jar";
+ echo " For e.g. runmpj.sh mpj.conf hello.World";
+ exit 127
+fi
+
+conf=$1
+lines=`cat $conf | egrep -v "#" | egrep "@"`
+dir=`pwd`
+name=$2
+count=0
+
+backslash2slash() {
+ echo $1 | sed 's/\\/\//g'
+}
+
+CLASSPATH_SEPARATOR=":"
+case "`uname`" in
+ CYGWIN*)
+ MPJ_HOME=`backslash2slash $MPJ_HOME`
+ CLASSPATH=`backslash2slash $CLASSPATH`
+
+ CLASSPATH_SEPARATOR=";"
+ ;;
+esac
+
+
+for i in `echo $lines`; do
+
+ host=`echo $i | cut -d "@" -f 1`
+ rank=`echo $i | cut -d "@" -f 3`
+
+ case "$name" in
+ *.jar )
+
+ ssh $host "cd $dir; export MPJ_HOME=$MPJ_HOME ; \
+ java -cp \"$MPJ_HOME/lib/mpj.jar${CLASSPATH_SEPARATOR}$CLASSPATH\" \
+ -jar $name $count $conf niodev;" &
+
+ ;;
+
+ * )
+
+echo $MPJ_HOME
+ ssh $host "cd $dir; export MPJ_HOME=$MPJ_HOME ; \
+ java -cp \"$MPJ_HOME/lib/mpj.jar${CLASSPATH_SEPARATOR}$CLASSPATH\" \
+ $name $count $conf niodev;" &
+ ;;
+ esac
+
+ count=`expr $count + 1`
+
+done
diff --git a/build.xml b/build.xml
new file mode 100755
index 0000000..aac27c0
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,333 @@
+<?xml version="1.0"?>
+
+<project name="mpi" default="all" basedir=".">
+ <property name="mpi.dir" value="src/mpi"/>
+ <property name="doc.dir" value="doc"/>
+ <property name="mpjdev.dir" value="src/mpjdev"/>
+ <property name="mpjdev.javampjdev.dir" value="src/mpjdev/javampjdev"/>
+ <property name="mpjdev.natmpjdev.dir" value="src/mpjdev/natmpjdev"/>
+ <property name="mpjbuf.dir" value="src/mpjbuf"/>
+ <property name="xdev.dir" value="src/xdev/"/>
+ <property name="niodev.dir" value="src/xdev/niodev"/>
+ <property name="smpdev.dir" value="src/xdev/smpdev"/>
+ <property name="hybdev.dir" value="src/xdev/hybdev"/>
+ <property name="lib.dir" value="lib/"/>
+ <property name="src.dir" value="src"/>
+ <property name="mx.native.dir" value="src/xdev/mxdev/lib"/>
+
+ <!-- cannot access ${java.home} ..? -->
+ <!-- <property name="java_home"
+ value="C:\Program Files\Java\jdk1.6.0"/> -->
+ <property environment="env"/>
+ <property name="mx_home" value="${env.MX_HOME}"/>
+ <property name="java_home" value="${env.JAVA_HOME}"/>
+
+ <!-- <property name="mx_home" value="/usr/local/mx"/>
+ <property environment="env"/> -->
+
+ <!-- If Batik toolkit is installed, define environment variable
+ BATIK_HOME to regenerate documentation PNG files from SVG
+ <property environment="env"/> -->
+ <property name="batik.dir" value="${env.BATIK_HOME}"/>
+
+ <!-- If Perl is not available in specified location, generation
+ of Java files from templates will be skipped. -->
+
+ <property name="perl.executable" value="/usr/bin/perl"/>
+
+ <!--
+ <property name="perl.executable" value="c:/Perl/bin/perl.exe"/>
+ -->
+ <!--
+ <property name="perl.executable" value="/cygwin/bin/perl.exe"/>
+ -->
+
+
+ <target name="havePerl">
+ <available property="perl.present" file="${perl.executable}"/>
+ </target>
+
+ <macrodef name="perl">
+
+ <attribute name="dir"/>
+ <attribute name="script"/>
+
+ <sequential>
+ <exec dir="@{dir}" executable="${perl.executable}">
+ <arg value="@{script}" />
+ </exec>
+ </sequential>
+ </macrodef>
+
+ <target name="perlAvailability" depends="havePerl"
+ unless="perl.present">
+ <echo>NOTE: Perl executable not found in expected location.</echo>
+ <echo> Java files will NOT be regenerated from templates.</echo>
+ </target>
+
+ <target name="generateJava" depends="perlAvailability"
+ if="perl.present">
+ <perl dir="src/mpi" script="generate.pl"/>
+ <perl dir="src/mpjbuf" script="generate.pl"/>
+ </target>
+
+ <target name="cleanJava" depends="perlAvailability"
+ if="perl.present">
+ <perl dir="src/mpjbuf" script="clean.pl"/>
+ <perl dir="src/mpi" script="clean.pl"/>
+ </target>
+
+
+ <target name="compile" description="compiles mpj code"
+ depends="generateJava">
+
+ <javac srcdir="${src.dir}"
+ classpath="lib/wrapper.jar:lib/org.mortbay.jetty.jar:lib/log4j-1.2.11.jar:lib/commons-cli-1.2.jar:lib\commons-codec-1.8.jar:lib\commons-io-2.4.jar"
+ sourcepath="${src.dir}"
+ debug="true"
+ />
+ </target>
+
+ <target name="jars" description="builds jar files ..">
+
+ <jar destfile="${lib.dir}/mpj.jar" basedir="src"
+ includes="mpi/*.class mpjbuf/*.class mpjdev/*.class mpjdev/javampjdev/*.class xdev/*.class mpjdev/natmpjdev/*.class
+ xdev/niodev/*.class xdev/mxdev/*.class xdev/hybdev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/mpiExp.jar" basedir="src"
+ includes="mpi/MPIException.class,mpjdev/MPJDevException.class,mpjdev/Request.class,mpjdev/Request$WaitanyQue.class,mpjdev/Status.class,mpjdev/CompletionHandler.class, mpjdev/Constants.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+ <!-- includes="mpi/MPIException.class,mpjdev/MPJDevException.class,mpjdev/Status.class,mpjdev/Group.class,mpjdev/MPJDev.class,mpjdev/Request.class,mpjdev/Comm.class,mpjdev/Request$WaitanyQue.class,mpjdev/Comm$1.class"> -->
+ <jar destfile="${lib.dir}/mpi.jar" basedir="src"
+ includes="mpi/*.class" excludes="mpi/MPIException.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/mpjbuf.jar" basedir="src"
+ includes="mpjbuf/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/mpjdev.jar" basedir="src"
+ includes="mpjdev/*.class mpjdev/javampjdev/*.class mpjdev/natmpjdev/*.class" excludes="mpjdev/MPJDevException.class,mpjdev/Request.class,mpjdev/Request$WaitanyQue.class,mpjdev/Status.class,mpjdev/CompletionHandler.class, mpjdev/Constants.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <!--
+ includes="mpjdev/*.class" excludes="mpjdev/MPJDevException.class,mpjdev/Status.class,mpjdev/Group.class,mpjdev/MPJDev.class,mpjdev/Request.class,mpjdev/Comm.class,mpjdev/Request$WaitanyQue.class,mpjdev/Comm$1.class">
+ -->
+
+ <jar destfile="${lib.dir}/xdev.jar" basedir="src"
+ includes="xdev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/niodev.jar" basedir="src"
+ includes="xdev/niodev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/mxdev.jar" basedir="src"
+ includes="xdev/mxdev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/smpdev.jar" basedir="src"
+ includes="xdev/smpdev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/hybdev.jar" basedir="src"
+ includes="xdev/hybdev/*.class">
+ <manifest>
+ <attribute name="Class-path" value="log4j-1.2.11.jar"/>
+ </manifest>
+ </jar>
+
+
+
+<jar destfile="${lib.dir}/daemon.jar" basedir="src"
+ includes="runtime/daemon/*.class">
+ <manifest>
+ <attribute name="Main-class"
+ value="runtime.daemon.MPJDaemon" />
+ <attribute name="Class-path"
+ value="log4j-1.2.11.jar commons-codec-1.8.jar commons-io-2.4.jar runtimecommon.jar "/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/loader1.jar" basedir="src"
+ includes="runtime/daemon/*.class runtime/*.class">
+ <manifest>
+ <attribute name="Main-class"
+ value="runtime.daemon.Wrapper" />
+ <!-- <attribute name="Class-path"
+ value="wrapper.jar log4j-1.2.11.jar mpj.jar"/> -->
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/loader2.jar" basedir="src"
+ includes="runtime/daemon/*.class runtime/*.class">
+ <manifest>
+ <attribute name="Main-class"
+ value="runtime.daemon.ThreadedWrapper" />
+ <!-- <attribute name="Class-path"
+ value="wrapper.jar log4j-1.2.11.jar mpj.jar"/> -->
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/starter.jar" basedir="src"
+ includes="runtime/starter/*.class" >
+ <manifest>
+ <attribute name="Main-class" value="runtime.starter.MPJRun" />
+ <attribute name="Class-path"
+ value="org.mortbay.jetty.jar log4j-1.2.11.jar runtimecommon.jar"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${lib.dir}/daemonmanager.jar" basedir="src"
+ includes="runtime/daemonmanager/*.class">
+ <manifest>
+ <attribute name="Main-class" value="runtime.daemonmanager.MPJDaemonManager" />
+ <attribute name="Class-path"
+ value="commons-cli-1.2.jar runtimecommon.jar"/>
+ </manifest>
+ </jar>
+ <jar destfile="${lib.dir}/runtimecommon.jar" basedir="src"
+ includes="runtime/common/*.class">
+ <manifest>
+ <attribute name="Class-path"
+ value="commons-cli-1.2.jar commons-codec-1.8.jar"/>
+ </manifest>
+ </jar>
+
+
+ </target>
+
+ <target name="mxlib" description="generates native MX code">
+
+ <javah destdir="${mx.native.dir}" force="yes"
+ classpath="${src.dir}">
+ <class name="xdev.mxdev.MXDevice"/>
+ <class name="xdev.mxdev.MXSendRequest"/>
+ <class name="xdev.mxdev.MXRecvRequest"/>
+ </javah>
+ <exec dir="${mx.native.dir}" executable="gcc">
+ <arg value="xdev_mxdev_MXSendRequest.c"/>
+ <arg value="xdev_mxdev_MXRecvRequest.c"/>
+ <arg value="xdev_mxdev_MXDevice.c"/>
+ <arg value="-o"/>
+ <arg value="libmxdev.so"/>
+ <arg value="-shared"/>
+ <arg value="-I"/>
+ <arg value="."/>
+ <arg value="-I"/>
+ <arg value="${java_home}/include"/>
+ <arg value="-I"/>
+ <arg value="${java_home}/include/linux"/>
+ <arg value="-I"/>
+ <arg value="${mx_home}/include"/>
+ <arg value="-L"/>
+ <arg value="${mx_home}/lib"/>
+ <arg value="-lmyriexpress"/>
+ </exec>
+
+ <move file="${mx.native.dir}/libmxdev.so" todir="${lib.dir}"/>
+ <!--
+ <delete>
+ <fileset dir="${mx.native.dir}" includes="*.h"/>
+ </delete>
+ -->
+ </target>
+
+ <target name="clean"> <!-- depends="cleanJava"> -->
+ <delete>
+ <fileset dir="${mpi.dir}" includes="**/*.class"/>
+ <fileset dir="${mpjdev.dir}" includes="**/*.class"/>
+ <fileset dir="${xdev.dir}" includes="**/*.class"/>
+ <fileset dir="${mpjbuf.dir}" includes="**/*.class"/>
+ <fileset dir="src/runtime" includes="**/*.class"/>
+ <fileset dir="src/runtime" includes="*.class"/>
+ </delete>
+ </target>
+
+ <target name="veryclean" depends="clean"/> <!-- ,cleanJava"/> -->
+
+ <!-- Processing SVG images to PNG (for documentation) -->
+
+ <target name="haveBatik">
+ <available property="batik.present"
+ file="${batik.dir}/batik-rasterizer.jar"/>
+ </target>
+
+ <macrodef name="rasterize">
+
+ <attribute name="dir"/>
+ <attribute name="name"/>
+
+ <sequential>
+ <java jar="${batik.dir}/batik-rasterizer.jar"
+ fork="true" failonerror="true">
+
+ <arg value="@{dir}/@{name}.svg"/>
+ </java>
+ </sequential>
+ </macrodef>
+
+ <target name="figures" depends="haveBatik" if="batik.present">
+ <rasterize dir="${doc.dir}/images" name="mpj-section"/>
+ <rasterize dir="${doc.dir}/images" name="mpj-static"/>
+ </target>
+
+ <target name="java-docs" depends="figures">
+ <javadoc
+ destdir="${doc.dir}/javadocs"
+ classpath="${lib.dir}/org.mortbay.jetty.jar:${lib.dir}/javax.servlet.jar:${lib.dir}/wrapper.jar:${lib.dir}/log4j-1.2.11.jar;${lib.dir}/commons-cli-1.2.jar">
+ <fileset dir="${mpi.dir}" defaultexcludes="yes">
+ <include name="**/Cartcomm.java"/>
+ <include name="**/CartParms.java"/>
+ <include name="**/Comm.java"/>
+ <include name="**/Datatype.java"/>
+ <include name="**/Errhandler.java"/>
+ <include name="**/Graphcomm.java"/>
+ <include name="**/GraphParms.java"/>
+ <include name="**/Group.java"/>
+ <include name="**/Intercomm.java"/>
+ <include name="**/Intracomm.java"/>
+ <include name="**/MPI.java"/>
+ <include name="**/MPIException.java"/>
+ <include name="**/Op.java"/>
+ <include name="**/Prequest.java"/>
+ <include name="**/Request.java"/>
+ <include name="**/ShiftParms.java"/>
+ <include name="**/Status.java"/>
+ <include name="**/User_function.java"/>
+ </fileset>
+ </javadoc>
+ </target>
+
+ <target name="all" depends="compile,jars,clean"
+ description="All"/>
+
+</project>
diff --git a/conf/local2.conf b/conf/local2.conf
new file mode 100755
index 0000000..1e55c27
--- /dev/null
+++ b/conf/local2.conf
@@ -0,0 +1,8 @@
+#<<---Number of hosts--->>
+2
+#<<---Limit of Protocol Switch --->>
+131072
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+localhost at 20000@20001 at 0@8000
+localhost at 20002@20003 at 1@8002
diff --git a/conf/mpj16.conf b/conf/mpj16.conf
new file mode 100755
index 0000000..e4e43a4
--- /dev/null
+++ b/conf/mpj16.conf
@@ -0,0 +1,22 @@
+#<<---Number of hosts--->>
+16
+#<<---Limit of Protocol Switch --->>
+131073
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp00.starbug.dsg.port.ac.uk at 20000@20001 at 0@8000
+comp01.starbug.dsg.port.ac.uk at 20000@20001 at 1@8000
+comp02.starbug.dsg.port.ac.uk at 20000@20001 at 2@8000
+comp03.starbug.dsg.port.ac.uk at 20000@20001 at 3@8000
+comp04.starbug.dsg.port.ac.uk at 20000@20001 at 4@8000
+comp05.starbug.dsg.port.ac.uk at 20000@20001 at 5@8000
+comp06.starbug.dsg.port.ac.uk at 20000@20001 at 6@8000
+comp07.starbug.dsg.port.ac.uk at 20000@20001 at 7@8000
+comp00.starbug.dsg.port.ac.uk at 20002@20003 at 8@8000
+comp01.starbug.dsg.port.ac.uk at 20002@20003 at 9@8000
+comp02.starbug.dsg.port.ac.uk at 20002@20003 at 10@8000
+comp03.starbug.dsg.port.ac.uk at 20002@20003 at 11@8000
+comp04.starbug.dsg.port.ac.uk at 20002@20003 at 12@8000
+comp05.starbug.dsg.port.ac.uk at 20002@20003 at 13@8000
+comp06.starbug.dsg.port.ac.uk at 20002@20003 at 14@8000
+comp07.starbug.dsg.port.ac.uk at 20002@20003 at 15@8000
diff --git a/conf/mpj2.conf b/conf/mpj2.conf
new file mode 100755
index 0000000..96d1590
--- /dev/null
+++ b/conf/mpj2.conf
@@ -0,0 +1,8 @@
+#<<---Number of hosts--->>
+2
+#<<---Limit of Protocol Switch --->>
+131072
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp06.starbug.dsg.port.ac.uk at 30000@30001 at 0@8000
+comp07.starbug.dsg.port.ac.uk at 30000@30001 at 1@8000
diff --git a/conf/mpj32.conf b/conf/mpj32.conf
new file mode 100755
index 0000000..6d25f8f
--- /dev/null
+++ b/conf/mpj32.conf
@@ -0,0 +1,38 @@
+#<<---Number of hosts--->>
+32
+#<<---Limit of Protocol Switch --->>
+131073
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp00.starbug.dsg.port.ac.uk at 20000@20001 at 0@8000
+comp01.starbug.dsg.port.ac.uk at 20000@20001 at 1@8000
+comp02.starbug.dsg.port.ac.uk at 20000@20001 at 2@8000
+comp03.starbug.dsg.port.ac.uk at 20000@20001 at 3@8000
+comp04.starbug.dsg.port.ac.uk at 20000@20001 at 4@8000
+comp05.starbug.dsg.port.ac.uk at 20000@20001 at 5@8000
+comp06.starbug.dsg.port.ac.uk at 20000@20001 at 6@8000
+comp07.starbug.dsg.port.ac.uk at 20000@20001 at 7@8000
+comp00.starbug.dsg.port.ac.uk at 20002@20003 at 8@8002
+comp01.starbug.dsg.port.ac.uk at 20002@20003 at 9@8002
+comp02.starbug.dsg.port.ac.uk at 20002@20003 at 10@8002
+comp03.starbug.dsg.port.ac.uk at 20002@20003 at 11@8002
+comp04.starbug.dsg.port.ac.uk at 20002@20003 at 12@8002
+comp05.starbug.dsg.port.ac.uk at 20002@20003 at 13@8002
+comp06.starbug.dsg.port.ac.uk at 20002@20003 at 14@8002
+comp07.starbug.dsg.port.ac.uk at 20002@20003 at 15@8002
+comp00.starbug.dsg.port.ac.uk at 20004@20005 at 16@8004
+comp01.starbug.dsg.port.ac.uk at 20004@20005 at 17@8004
+comp02.starbug.dsg.port.ac.uk at 20004@20005 at 18@8004
+comp03.starbug.dsg.port.ac.uk at 20004@20005 at 19@8004
+comp04.starbug.dsg.port.ac.uk at 20004@20005 at 20@8004
+comp05.starbug.dsg.port.ac.uk at 20004@20005 at 21@8004
+comp06.starbug.dsg.port.ac.uk at 20004@20005 at 22@8004
+comp07.starbug.dsg.port.ac.uk at 20004@20005 at 23@8004
+comp00.starbug.dsg.port.ac.uk at 20006@20007 at 24@8006
+comp01.starbug.dsg.port.ac.uk at 20006@20007 at 25@8006
+comp02.starbug.dsg.port.ac.uk at 20006@20007 at 26@8006
+comp03.starbug.dsg.port.ac.uk at 20006@20007 at 27@8006
+comp04.starbug.dsg.port.ac.uk at 20006@20007 at 28@8006
+comp05.starbug.dsg.port.ac.uk at 20006@20007 at 29@8006
+comp06.starbug.dsg.port.ac.uk at 20006@20007 at 30@8006
+comp07.starbug.dsg.port.ac.uk at 20006@20007 at 31@8006
diff --git a/conf/mpj4.conf b/conf/mpj4.conf
new file mode 100755
index 0000000..8963c48
--- /dev/null
+++ b/conf/mpj4.conf
@@ -0,0 +1,10 @@
+#<<---Number of hosts--->>
+4
+#<<---Limit of Protocol Switch --->>
+131073
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp01.starbug.dsg.port.ac.uk at 20000@20001 at 0@8000
+comp02.starbug.dsg.port.ac.uk at 20000@20001 at 1@8000
+comp03.starbug.dsg.port.ac.uk at 20000@20001 at 2@8000
+comp04.starbug.dsg.port.ac.uk at 20000@20001 at 3@8000
diff --git a/conf/mpj64.conf b/conf/mpj64.conf
new file mode 100755
index 0000000..2f88d86
--- /dev/null
+++ b/conf/mpj64.conf
@@ -0,0 +1,70 @@
+#<<---Number of hosts--->>
+64
+#<<---Limit of Protocol Switch --->>
+131073
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp00.starbug.dsg.port.ac.uk at 20000@20001 at 0@8000
+comp01.starbug.dsg.port.ac.uk at 20000@20001 at 1@8000
+comp02.starbug.dsg.port.ac.uk at 20000@20001 at 2@8000
+comp03.starbug.dsg.port.ac.uk at 20000@20001 at 3@8000
+comp04.starbug.dsg.port.ac.uk at 20000@20001 at 4@8000
+comp05.starbug.dsg.port.ac.uk at 20000@20001 at 5@8000
+comp06.starbug.dsg.port.ac.uk at 20000@20001 at 6@8000
+comp07.starbug.dsg.port.ac.uk at 20000@20001 at 7@8000
+comp00.starbug.dsg.port.ac.uk at 20002@20003 at 8@8002
+comp01.starbug.dsg.port.ac.uk at 20002@20003 at 9@8002
+comp02.starbug.dsg.port.ac.uk at 20002@20003 at 10@8002
+comp03.starbug.dsg.port.ac.uk at 20002@20003 at 11@8002
+comp04.starbug.dsg.port.ac.uk at 20002@20003 at 12@8002
+comp05.starbug.dsg.port.ac.uk at 20002@20003 at 13@8002
+comp06.starbug.dsg.port.ac.uk at 20002@20003 at 14@8002
+comp07.starbug.dsg.port.ac.uk at 20002@20003 at 15@8002
+comp00.starbug.dsg.port.ac.uk at 20004@20005 at 16@8004
+comp01.starbug.dsg.port.ac.uk at 20004@20005 at 17@8004
+comp02.starbug.dsg.port.ac.uk at 20004@20005 at 18@8004
+comp03.starbug.dsg.port.ac.uk at 20004@20005 at 19@8004
+comp04.starbug.dsg.port.ac.uk at 20004@20005 at 20@8004
+comp05.starbug.dsg.port.ac.uk at 20004@20005 at 21@8004
+comp06.starbug.dsg.port.ac.uk at 20004@20005 at 22@8004
+comp07.starbug.dsg.port.ac.uk at 20004@20005 at 23@8004
+comp00.starbug.dsg.port.ac.uk at 20006@20007 at 24@8006
+comp01.starbug.dsg.port.ac.uk at 20006@20007 at 25@8006
+comp02.starbug.dsg.port.ac.uk at 20006@20007 at 26@8006
+comp03.starbug.dsg.port.ac.uk at 20006@20007 at 27@8006
+comp04.starbug.dsg.port.ac.uk at 20006@20007 at 28@8006
+comp05.starbug.dsg.port.ac.uk at 20006@20007 at 29@8006
+comp06.starbug.dsg.port.ac.uk at 20006@20007 at 30@8006
+comp07.starbug.dsg.port.ac.uk at 20006@20007 at 31@8006
+comp00.starbug.dsg.port.ac.uk at 20008@20009 at 32@8008
+comp01.starbug.dsg.port.ac.uk at 20008@20009 at 33@8008
+comp02.starbug.dsg.port.ac.uk at 20008@20009 at 34@8008
+comp03.starbug.dsg.port.ac.uk at 20008@20009 at 35@8008
+comp04.starbug.dsg.port.ac.uk at 20008@20009 at 36@8008
+comp05.starbug.dsg.port.ac.uk at 20008@20009 at 37@8008
+comp06.starbug.dsg.port.ac.uk at 20008@20009 at 38@8008
+comp07.starbug.dsg.port.ac.uk at 20008@20009 at 39@8008
+comp00.starbug.dsg.port.ac.uk at 20010@200011 at 40@8010
+comp01.starbug.dsg.port.ac.uk at 20010@200011 at 41@8010
+comp02.starbug.dsg.port.ac.uk at 20010@200011 at 42@8010
+comp03.starbug.dsg.port.ac.uk at 20010@200011 at 43@8010
+comp04.starbug.dsg.port.ac.uk at 20010@200011 at 44@8010
+comp05.starbug.dsg.port.ac.uk at 20010@200011 at 45@8010
+comp06.starbug.dsg.port.ac.uk at 20010@200011 at 46@8010
+comp07.starbug.dsg.port.ac.uk at 20010@200011 at 47@8010
+comp00.starbug.dsg.port.ac.uk at 20012@200013 at 48@8012
+comp01.starbug.dsg.port.ac.uk at 20012@200013 at 49@8012
+comp02.starbug.dsg.port.ac.uk at 20012@200013 at 50@8012
+comp03.starbug.dsg.port.ac.uk at 20012@200013 at 51@8012
+comp04.starbug.dsg.port.ac.uk at 20012@200013 at 52@8012
+comp05.starbug.dsg.port.ac.uk at 20012@200013 at 53@8012
+comp06.starbug.dsg.port.ac.uk at 20012@200013 at 54@8012
+comp07.starbug.dsg.port.ac.uk at 20012@200013 at 55@8012
+comp00.starbug.dsg.port.ac.uk at 20014@200015 at 56@8014
+comp01.starbug.dsg.port.ac.uk at 20014@200015 at 57@8014
+comp02.starbug.dsg.port.ac.uk at 20014@200015 at 58@8014
+comp03.starbug.dsg.port.ac.uk at 20014@200015 at 59@8014
+comp04.starbug.dsg.port.ac.uk at 20014@200015 at 60@8014
+comp05.starbug.dsg.port.ac.uk at 20014@200015 at 61@8014
+comp06.starbug.dsg.port.ac.uk at 20014@200015 at 62@8014
+comp07.starbug.dsg.port.ac.uk at 20014@200015 at 63@8014
diff --git a/conf/mpj8.conf b/conf/mpj8.conf
new file mode 100755
index 0000000..d3fdafd
--- /dev/null
+++ b/conf/mpj8.conf
@@ -0,0 +1,14 @@
+#<<---Number of hosts--->>
+8
+#<<---Limit of Protocol Switch --->>
+131072
+#<<---Processes--->>
+#IP/FULLY_QUALIFIED_HOSTNAME at READ_PORT@WRITE_PORT at RANK@DEBUG_PORT
+comp00.starbug.dsg.port.ac.uk at 20000@20001 at 0@8000
+comp01.starbug.dsg.port.ac.uk at 20000@20001 at 1@8000
+comp02.starbug.dsg.port.ac.uk at 20000@20001 at 2@8000
+comp03.starbug.dsg.port.ac.uk at 20000@20001 at 3@8000
+comp04.starbug.dsg.port.ac.uk at 20000@20001 at 4@8000
+comp05.starbug.dsg.port.ac.uk at 20000@20001 at 5@8000
+comp06.starbug.dsg.port.ac.uk at 20000@20001 at 6@8000
+comp07.starbug.dsg.port.ac.uk at 20000@20001 at 7@8000
diff --git a/conf/wrapper.conf b/conf/wrapper.conf
new file mode 100644
index 0000000..a478b54
--- /dev/null
+++ b/conf/wrapper.conf
@@ -0,0 +1,109 @@
+#********************************************************************
+# MPJ Daemon Properties#
+#********************************************************************
+# Java Application
+wrapper.java.command=java
+
+# Java Main class. This class must implement the WrapperListener interface
+# or guarantee that the WrapperManager class is initialized. Helper
+# classes are provided to do this for you. See the Integration section
+# of the documentation for details.
+wrapper.java.mainclass=runtime.daemon.WrapperSimpleApp
+
+# Java Classpath (include wrapper.jar) Add class path elements as
+# needed starting from 1
+wrapper.java.classpath.1=../lib/daemon.jar
+wrapper.java.classpath.2=../lib/wrapper.jar
+
+#Java Library Path (location of Wrapper.DLL or libwrapper.so)
+wrapper.java.library.path.1=../lib
+#wrapper.native_library=wrapper
+
+# Java Additional Parameters
+#wrapper.java.additional.1=-Xdebug
+#wrapper.java.additional.2=-Xrunjdwp:transport=dt_socket,address=9000,server=y,suspend=n
+
+# Initial Java Heap Size (in MB)
+#wrapper.java.initmemory=3
+
+# Maximum Java Heap Size (in MB)
+#wrapper.java.maxmemory=64
+
+# Application parameters. Add parameters as needed starting from 1
+#wrapper.app.parameter.1=
+wrapper.app.parameter.1=runtime.daemon.MPJDaemon
+#port number for the daemon.
+wrapper.app.parameter.2=10000
+#Socket Server Port Number.
+wrapper.app.parameter.3=15000
+
+#********************************************************************
+# Wrapper Logging Properties
+#********************************************************************
+# Log Level for Daemon log file output. (See docs for log levels)
+wrapper.logfile.loglevel.mpjdaemon=OFF
+
+# Log Level for MPJRun log file output. (See docs for log levels)
+wrapper.logfile.loglevel.mpjrun=OFF
+
+
+# Format of output for the console. (See docs for formats)
+wrapper.console.format=PM
+
+# Log Level for console output. (See docs for log levels)
+wrapper.console.loglevel=NONE
+
+# Log file to use for wrapper output logging.
+wrapper.logfile=../logs/wrapper.log
+
+# Format of output for the log file. (See docs for formats)
+wrapper.logfile.format=LPTM
+
+# Log Level for log file output. (See docs for log levels)
+wrapper.logfile.loglevel=NONE
+
+# Maximum size that the log file will be allowed to grow to before
+# the log is rolled. Size is specified in bytes. The default value
+# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
+# 'm' (mb) suffix. For example: 10m = 10 megabytes.
+wrapper.logfile.maxsize=0
+
+# Maximum number of rolled log files which will be allowed before old
+# files are deleted. The default value of 0 implies no limit.
+wrapper.logfile.maxfiles=0
+
+# Log Level for sys/event log output. (See docs for log levels)
+wrapper.syslog.loglevel=NONE
+
+#********************************************************************
+# Wrapper Windows Properties
+#********************************************************************
+# Title to use when running as a console
+wrapper.console.title=MPJ Daemon
+
+#********************************************************************
+# Wrapper Windows NT/2000/XP Service Properties
+#********************************************************************
+# WARNING - Do not modify any of these properties when an application
+# using this configuration file has been installed as a service.
+# Please uninstall the service before modifying this section. The
+# service can then be reinstalled.
+
+# Name of the service
+wrapper.ntservice.name=mpjdaemon
+
+# Display name of the service
+wrapper.ntservice.displayname=MPJ Daemon
+
+# Description of the service
+wrapper.ntservice.description=MPJ Daemon
+
+# Service dependencies. Add dependencies as needed starting from 1
+wrapper.ntservice.dependency.1=
+
+# Mode in which the service is installed. AUTO_START or DEMAND_START
+wrapper.ntservice.starttype=AUTO_START
+
+# Allow the service to interact with the desktop.
+wrapper.ntservice.interactive=false
+
diff --git a/debian/README.Debian b/debian/README.Debian
deleted file mode 100644
index 14f720a..0000000
--- a/debian/README.Debian
+++ /dev/null
@@ -1,40 +0,0 @@
-libmpj-java for Debian
-======================
-
-Documentation
--------------
-
-The original tarball contained some PDF files without source. So these
-were stripped from the source to not cause conflicts with DFSG. Feel
-free to download and read these files at
-
- http://mpj-express.org/guides.html
-
-
-Other parts of the library
---------------------------
-
-The mpj-express project builds several different jar files.
-
-This actual package was to build mpj.jar exclusively as a prerequisite
-for the beast-mcmc package. Because the chances to test the other
-builded JARs are not very good they are not shipped with the binary
-package.
-
-Please feel free to suggest inclusion of other JARs if you have some
-use case.
-
-
-Test suite
-----------
-
-The original tarball contained a complex test suite. However large
-parts of this suite did not contained any licensing statement. This
-test suite is even downloadable separately at
-
- http://www2.epcc.ed.ac.uk/computing/research_activities/java_grande/mpj.html
-
-If you consider using the test suite and want to include it into the
-packaging please clarify the license with the authors.
-
- -- Andreas Tille <tille at debian.org> Sat, 21 Jan 2012 15:15:57 +0100
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 1c9c171..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,48 +0,0 @@
-mpj (0.42+dfsg-2) unstable; urgency=medium
-
- * Team upload.
- * Fixed the build failure caused by the update of commons-codec
- * Standards-Version updated to 3.9.6 (no changes)
-
- -- Emmanuel Bourg <ebourg at apache.org> Mon, 29 Jun 2015 16:48:07 +0200
-
-mpj (0.42+dfsg-1) unstable; urgency=medium
-
- * New upstream version (adapted patch)
- * Adapted d/watch, droped d/get-orig-source
- * New Build-Depends: libcommons-cli-java, libcommons-codec-java,
- libcommons-io-java
- * cme fix dpkg-control
-
- -- Andreas Tille <tille at debian.org> Thu, 24 Jul 2014 13:43:16 +0200
-
-mpj (0.38+dfsg-2) unstable; urgency=low
-
- * Upload to unstable
- Closes: #720566
- * debian/control:
- - cme fix dpkg-control
- - debhelper 9
- - anonscm in Vcs fields
-
- -- Andreas Tille <tille at debian.org> Fri, 23 Aug 2013 14:23:48 +0200
-
-mpj (0.38+dfsg-1) experimental; urgency=low
-
- * debian/copyright:
- - DEP5
- - Add Files-Excluded to document what was removed from original source
- * debian/control:
- - Standards-Version: 3.9.4 (no changes needed)
- - Architecture: all
- * debian/{control,rules}: use default java implementation
- (thanks for the patch to James Page <james.page at ubuntu.com>)
- Closes: #684159
-
- -- Andreas Tille <tille at debian.org> Mon, 17 Dec 2012 14:10:59 +0100
-
-mpj (0.38~dfsg-1) unstable; urgency=low
-
- * Initial release (Closes: #656790)
-
- -- Andreas Tille <tille at debian.org> Sat, 21 Jan 2012 15:15:57 +0100
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 2e6dba8..0000000
--- a/debian/control
+++ /dev/null
@@ -1,28 +0,0 @@
-Source: mpj
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: java
-Priority: optional
-Build-Depends: debhelper (>= 9),
- javahelper,
- default-jdk (>= 1:1.6),
- ant,
- liblog4j1.2-java,
- libservice-wrapper-java,
- libcommons-cli-java,
- libcommons-codec-java,
- libcommons-io-java
-Standards-Version: 3.9.6
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/libmpj-java/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/libmpj-java/trunk/
-Homepage: http://mpj-express.org/
-
-Package: libmpj-java
-Architecture: all
-Depends: ${misc:Depends},
- ${java:Depends}
-Recommends: ${java:Recommends}
-Description: Java library for parallel applications for multicore processors and clusters
- MPJ Express is a Java message passing library that allows application
- developers to write and execute parallel applications for multicore
- processors and compute clusters/clouds.
diff --git a/debian/libmpj-java.jlibs b/debian/libmpj-java.jlibs
deleted file mode 100644
index ce9b8fd..0000000
--- a/debian/libmpj-java.jlibs
+++ /dev/null
@@ -1 +0,0 @@
-lib/mpj.jar
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index a19efd6..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
-use_debian_packaged_jars.patch
diff --git a/debian/patches/use_debian_packaged_jars.patch b/debian/patches/use_debian_packaged_jars.patch
deleted file mode 100644
index fab7951..0000000
--- a/debian/patches/use_debian_packaged_jars.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-Author: Andreas Tille <tille at debian.org>
-Last-Update: Thu, 24 Jul 2014 13:53:02 +0200
-Description: Use Debian packaged libraries
- - Set classpath to those Debian JARs which are used
- - Remove jetty from classpath which is actually not used and thus there
- is no need to worry about its copyright explicitely
-
---- a/build.xml
-+++ b/build.xml
-@@ -82,7 +82,7 @@
- depends="generateJava">
-
- <javac srcdir="${src.dir}"
-- classpath="lib/wrapper.jar:lib/org.mortbay.jetty.jar:lib/log4j-1.2.11.jar:lib/commons-cli-1.2.jar:lib\commons-codec-1.8.jar:lib\commons-io-2.4.jar"
-+ classpath="/usr/share/java/wrapper.jar:/usr/share/java/log4j-1.2.jar:/usr/share/java/commons-cli.jar:/usr/share/java/commons-codec.jar:/usr/share/java/commons-io.jar"
- sourcepath="${src.dir}"
- debug="true"
- />
-@@ -94,35 +94,35 @@
- includes="mpi/*.class mpjbuf/*.class mpjdev/*.class mpjdev/javampjdev/*.class xdev/*.class mpjdev/natmpjdev/*.class
- xdev/niodev/*.class xdev/mxdev/*.class xdev/hybdev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/mpiExp.jar" basedir="src"
- includes="mpi/MPIException.class,mpjdev/MPJDevException.class,mpjdev/Request.class,mpjdev/Request$WaitanyQue.class,mpjdev/Status.class,mpjdev/CompletionHandler.class, mpjdev/Constants.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
- <!-- includes="mpi/MPIException.class,mpjdev/MPJDevException.class,mpjdev/Status.class,mpjdev/Group.class,mpjdev/MPJDev.class,mpjdev/Request.class,mpjdev/Comm.class,mpjdev/Request$WaitanyQue.class,mpjdev/Comm$1.class"> -->
- <jar destfile="${lib.dir}/mpi.jar" basedir="src"
- includes="mpi/*.class" excludes="mpi/MPIException.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/mpjbuf.jar" basedir="src"
- includes="mpjbuf/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/mpjdev.jar" basedir="src"
- includes="mpjdev/*.class mpjdev/javampjdev/*.class mpjdev/natmpjdev/*.class" excludes="mpjdev/MPJDevException.class,mpjdev/Request.class,mpjdev/Request$WaitanyQue.class,mpjdev/Status.class,mpjdev/CompletionHandler.class, mpjdev/Constants.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
-@@ -133,35 +133,35 @@
- <jar destfile="${lib.dir}/xdev.jar" basedir="src"
- includes="xdev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/niodev.jar" basedir="src"
- includes="xdev/niodev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/mxdev.jar" basedir="src"
- includes="xdev/mxdev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/smpdev.jar" basedir="src"
- includes="xdev/smpdev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
- <jar destfile="${lib.dir}/hybdev.jar" basedir="src"
- includes="xdev/hybdev/*.class">
- <manifest>
-- <attribute name="Class-path" value="log4j-1.2.11.jar"/>
-+ <attribute name="Class-path" value="log4j-1.2.jar"/>
- </manifest>
- </jar>
-
-@@ -173,7 +173,7 @@
- <attribute name="Main-class"
- value="runtime.daemon.MPJDaemon" />
- <attribute name="Class-path"
-- value="log4j-1.2.11.jar commons-codec-1.8.jar commons-io-2.4.jar runtimecommon.jar "/>
-+ value="log4j-1.2.jar commons-codec.jar commons-io.jar runtimecommon.jar "/>
- </manifest>
- </jar>
-
-@@ -183,7 +183,7 @@
- <attribute name="Main-class"
- value="runtime.daemon.Wrapper" />
- <!-- <attribute name="Class-path"
-- value="wrapper.jar log4j-1.2.11.jar mpj.jar"/> -->
-+ value="wrapper.jar log4j-1.2.jar mpj.jar"/> -->
- </manifest>
- </jar>
-
-@@ -193,7 +193,7 @@
- <attribute name="Main-class"
- value="runtime.daemon.ThreadedWrapper" />
- <!-- <attribute name="Class-path"
-- value="wrapper.jar log4j-1.2.11.jar mpj.jar"/> -->
-+ value="wrapper.jar log4j-1.2.jar mpj.jar"/> -->
- </manifest>
- </jar>
-
-@@ -202,7 +202,7 @@
- <manifest>
- <attribute name="Main-class" value="runtime.starter.MPJRun" />
- <attribute name="Class-path"
-- value="org.mortbay.jetty.jar log4j-1.2.11.jar runtimecommon.jar"/>
-+ value="log4j-1.2.jar runtimecommon.jar"/>
- </manifest>
- </jar>
-
-@@ -303,7 +303,7 @@
- <target name="java-docs" depends="figures">
- <javadoc
- destdir="${doc.dir}/javadocs"
-- classpath="${lib.dir}/org.mortbay.jetty.jar:${lib.dir}/javax.servlet.jar:${lib.dir}/wrapper.jar:${lib.dir}/log4j-1.2.11.jar;${lib.dir}/commons-cli-1.2.jar">
-+ classpath="${lib.dir}/javax.servlet.jar:${lib.dir}/wrapper.jar:${lib.dir}/log4j-1.2.jar;${lib.dir}/commons-cli.jar">
- <fileset dir="${mpi.dir}" defaultexcludes="yes">
- <include name="**/Cartcomm.java"/>
- <include name="**/CartParms.java"/>
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index b02b2bb..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/make -f
-
-JAVA_HOME=/usr/lib/jvm/default-java
-
-%:
- dh $@ --with javahelper
-
-override_dh_auto_build:
- dh_auto_build -- -Dant.build.javac.source=1.5 -Dant.build.javac.target=1.5
-
-get-orig-source:
- uscan --verbose --force-download --repack --compress xz
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index b81fb36..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,3 +0,0 @@
-version=3
-opts="uversionmangle=s/_/./g;s/$/+dfsg/" \
- http://sf.net/mpjexpress/mpj-v(.+)\.zip
diff --git a/doc/APICHANGES.txt b/doc/APICHANGES.txt
new file mode 100644
index 0000000..224df07
--- /dev/null
+++ b/doc/APICHANGES.txt
@@ -0,0 +1,55 @@
+Scope
+-----
+This document lists methods whose API has been changed from mpiJava-1.2.5. It
+could be important if you want to port your Java MPI applications from mpiJava
+to MPJExpress.
+
+Please also read 'Known problems & limitations' to make sure that MPJExpress provides
+the feature your application is relying on.
+
+List of methods with their API's changed
+----------------------------------------
+
+1. MPI.Buffer_attach( ... )
+mpiJava: static public void Buffer_attach(byte[] buffer)
+ throws MPIException
+MPJExpress: public static void Buffer_attach(ByteBuffer userBuffer)
+ throws MPIException
+
+2. MPI.Buffer_detach( ... )
+mpiJava: static public byte[] Buffer_detach() throws MPIException
+MPJExpress: public static void Buffer_detach() throws MPIException
+
+3. Comm.Pack( ... ) [ note the penultimate argument ]
+mpiJava:
+ public int Pack(Object inbuf,
+ int offset,
+ int incount,
+ Datatype datatype,
+ byte[] outbuf,
+ int position) throws MPIException
+MPJExpress:
+ public int Pack(Object inbuf,
+ int offset,
+ int incount,
+ Datatype datatype,
+ mpjbuf.Buffer outbuf,
+ int position) throws MPIException
+
+4. Comm.Unpack( ... ) [ note the penultimate argument ]
+mpiJava:
+ public int Unpack(byte[] inbuf,
+ int position,
+ Object outbuf,
+ int offset,
+ int outcount,
+ Datatype datatype) throws MPIException
+
+MPJExpress:
+ public int Unpack(mpjbuf.Buffer inbuf,
+ int position,
+ Object outbuf,
+ int offset,
+ int outcount,
+ Datatype datatype) throws MPIException
+
diff --git a/doc/images/mpj-section.png b/doc/images/mpj-section.png
new file mode 100755
index 0000000..ede53cd
Binary files /dev/null and b/doc/images/mpj-section.png differ
diff --git a/doc/images/mpj-section.svg b/doc/images/mpj-section.svg
new file mode 100755
index 0000000..f7abd16
--- /dev/null
+++ b/doc/images/mpj-section.svg
@@ -0,0 +1,2731 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 10.0, SVG Export Plug-In . SVG Version: 3.0.0 Build 76) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
+ <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg
+ xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" i:viewOrigin="52.5 685" i:rulerOrigin="0 0" i:pageBounds="0 792 612 0"
+ xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ width="550" height="240" viewBox="0 0 517.527 240" overflow="visible" enable-background="new 0 0 517.527 240"
+ xml:space="preserve">
+ <metadata>
+ <variableSets xmlns="http://ns.adobe.com/Variables/1.0/">
+ <variableSet varSetName="binding1" locked="none">
+ <variables></variables>
+ <v:sampleDataSets xmlns="http://ns.adobe.com/GenericCustomNamespace/1.0/" xmlns:v="http://ns.adobe.com/Variables/1.0/">
+ </v:sampleDataSets>
+ </variableSet>
+ </variableSets>
+ <sfw xmlns="&ns_sfw;">
+ <slices></slices>
+ <sliceSourceBounds x="52.5" y="445" width="517.527" height="240" bottomLeftOrigin="true"></sliceSourceBounds>
+ </sfw>
+ </metadata>
+ <switch>
+ <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
+ <i:pgfRef xlink:href="#adobe_illustrator_pgf">
+ </i:pgfRef>
+ </foreignObject>
+ <g i:extraneous="self">
+ <g id="Layer_1" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M217.5,203.625h-72v-19.25h72V203.625z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M318.25,203.75h-29v-19.5h29.5"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" stroke-dasharray="5 4" d="M321.5,184h85.25"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" stroke-dasharray="5 4" d="M404.5,204h-86.25"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M0.5,240V3"/>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M34.5,33"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Section header</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_1_" />
+ </foreignObject>
+ <text id="XMLID_1_" transform="matrix(1 0 0 1 34.5 33)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Section header</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M257.5,32"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Section data</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_2_" />
+ </foreignObject>
+ <text id="XMLID_2_" transform="matrix(1 0 0 1 257.5 32)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Section data</tspan></text>
+ </switch>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M28.5,29H14.666"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M10.582,31.05c2.859,0.999,4.717,1.919,7.011,2.983V23.944
+ c-0.821,0.451-4.152,1.985-7.011,2.983c-3.06,1.069-5.835,1.801-7.634,2.062C4.747,29.25,7.521,29.981,10.582,31.05z"/>
+ </g>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M120.5,29.05h13.443"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M137.911,27c-2.778-0.999-4.584-1.919-6.812-2.983v10.089
+ c0.797-0.451,4.034-1.985,6.812-2.983c2.974-1.069,5.669-1.801,7.418-2.062C143.581,28.8,140.885,28.068,137.911,27z"/>
+ </g>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M15.5,177"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Element type, T</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_3_" />
+ </foreignObject>
+ <text id="XMLID_3_" transform="matrix(0 -1 1 0 15.5 177)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Element type, T</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M112.5,159"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Length of section, n</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_4_" />
+ </foreignObject>
+ <text id="XMLID_4_" transform="matrix(0 -1 1 0 112.5 159)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Length of section, n</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M32.5,176"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'Arial-ItalicMT'" font-size="12">
+ <p><span>unused</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_5_" />
+ </foreignObject>
+ <text id="XMLID_5_" transform="matrix(0 -1 1 0 32.5 176)"><tspan x="0" y="0" font-family="'Arial-ItalicMT'" font-size="12">unused</tspan></text>
+ </switch>
+ <path i:knockout="Off" fill="#DEDEDE" stroke="#000000" d="M19.516,203.875H1.484v-19.75h18.031V203.875z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M73.516,203.875H55.484v-19.75h18.031V203.875z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M55.516,203.875H37.484v-19.75h18.031V203.875z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M37.516,203.875H19.484v-19.75h18.031V203.875z"/>
+ <path i:knockout="Off" fill="#DEDEDE" stroke="#000000" d="M145.5,203.625h-72v-19.25h72V203.625z"/>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M66.5,176"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'Arial-ItalicMT'" font-size="12">
+ <p><span>unused</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_6_" />
+ </foreignObject>
+ <text id="XMLID_6_" transform="matrix(0 -1 1 0 66.5 176)"><tspan x="0" y="0" font-family="'Arial-ItalicMT'" font-size="12">unused</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M48.5,176"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'Arial-ItalicMT'" font-size="12">
+ <p><span>unused</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_7_" />
+ </foreignObject>
+ <text id="XMLID_7_" transform="matrix(0 -1 1 0 48.5 176)"><tspan x="0" y="0" font-family="'Arial-ItalicMT'" font-size="12">unused</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M127.5,179"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'Myriad-Roman'" font-size="60">
+ <p><span>}</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_8_" />
+ </foreignObject>
+ <text id="XMLID_8_" transform="matrix(0 -1 1 0 127.5 179)"><tspan x="0" y="0" font-family="'Myriad-Roman'" font-size="60">}</tspan></text>
+ </switch>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M289.5,203.625h-72v-19.25h72V203.625z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M406.75,184.25h29v19.5h-29.5"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M145.5,237V0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M435.5,237V0"/>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M331.5,29l88.207-0.022"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M424.166,26.928c-3.121-0.999-5.15-1.919-7.653-2.983v10.089
+ c0.896-0.451,4.532-1.985,7.653-2.983c3.341-1.069,6.37-1.801,8.334-2.062C430.536,28.728,427.507,27.996,424.166,26.928z"/>
+ </g>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M252.5,28.05
+ l-89.805,0.022"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M158.156,30.122c3.178,0.999,5.244,1.919,7.792,2.983V23.017
+ c-0.912,0.451-4.615,1.985-7.792,2.983c-3.401,1.069-6.485,1.801-8.485,2.062C151.671,28.322,154.755,29.054,158.156,30.122z"
+ />
+ </g>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M8.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>0</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_9_" />
+ </foreignObject>
+ <text id="XMLID_9_" transform="matrix(1 0 0 1 8.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">0</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M25.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>1</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_10_" />
+ </foreignObject>
+ <text id="XMLID_10_" transform="matrix(1 0 0 1 25.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">1</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M44.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>2</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_11_" />
+ </foreignObject>
+ <text id="XMLID_11_" transform="matrix(1 0 0 1 44.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">2</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M62.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>3</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_12_" />
+ </foreignObject>
+ <text id="XMLID_12_" transform="matrix(1 0 0 1 62.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">3</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M80.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>4</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_13_" />
+ </foreignObject>
+ <text id="XMLID_13_" transform="matrix(1 0 0 1 80.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">4</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M98.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>5</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_14_" />
+ </foreignObject>
+ <text id="XMLID_14_" transform="matrix(1 0 0 1 98.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">5</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M116.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>6</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_15_" />
+ </foreignObject>
+ <text id="XMLID_15_" transform="matrix(1 0 0 1 116.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">6</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M132.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>7</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_16_" />
+ </foreignObject>
+ <text id="XMLID_16_" transform="matrix(1 0 0 1 132.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">7</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M154.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>8</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_17_" />
+ </foreignObject>
+ <text id="XMLID_17_" transform="matrix(1 0 0 1 154.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">8</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M219.5,217"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>8 + sizeof(T)</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_18_" />
+ </foreignObject>
+ <text id="XMLID_18_" transform="matrix(1 0 0 1 219.5 217)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">8 + sizeof(T)</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M440.5,216"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>8 + n sizeof(T)</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_19_" />
+ </foreignObject>
+ <text id="XMLID_19_" transform="matrix(1 0 0 1 440.5 216)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">8 + n sizeof(T)</tspan></text>
+ </switch>
+ </g>
+ </g>
+ </switch>
+ <i:pgf id="adobe_illustrator_pgf">
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+REFvCX19g6SO3ev0zfeeJGW49UDrmDeObA0M1J2tdVYfJohACr2xi522F1IJj3469mMDJYhpXxjo
+M7A3Rq0fpX2oXExowW5vQrSGAxom71BsZtTlryrBKnF8+0GD1cFf25dSBWcQVKCfxI5mOnzgqcOm
+J0eDfdZiHDExbckGVlbaMzRZ6h9yTo58Mn7UrrbBLVkTlaAyqtGHMZTE4H1MwJM1X+yumEaAfv/n
+66u/3pxf3Z5f/Xh4yHBUWMe/+ex3f36Bf2cN/eV3//iPb88v2lSf/e73+meIwf/9P//05M/XT8/g
+z188Q/AQiv/L5cVV+8tD+D/QfzEWf/Nfvz65eEV/b7mF+/i3t1JI8Pdf3dycvFl++ezvr25+eHVx
+dnV69it9/8s+4vT5+cXTmzNKNfj9NElhskya5u3L++L2rp30pbpHXeowrF2bm/MfXt2evcSB7W/6
+tOOGbs5evrq43WlLa9qMLHu+nR9OXp59e3P2f1817L+5c1cQQ7qmXc1WP9/c1avLv5zenryGH9yx
+M7embY3rnu/p5e357enzv59f7LCpq+vvcPSa9jZZ///z9sHzvT87O76+fHH98vx2zQ==
+ ]]>
+ <![CDATA[
+ JO/86s6D+e761c3p2X/cnLx4fn66ptM5v1reuPOrbY9jveQO1zzfyPWLs5uT2+s72fX2E/xN9tKX
+ffdzuc99/eVusv/5mvDxy/Jkd+Bcq9rCBl718/nT222Eum/DmnVthFc938zzs/Mfn98tJK1tN7Ls
+BQV8eudWvvrj919dvHh+8r1d04Zg4QsmiirLf12d394tQFz/8D9np7dfX7+6etpGfX29jVT8Jpub
+bOQO0vj7b86eHXy5V+Xeuyr37OakSa4Xf74+f7lX5tauzK2KVj2eLhfWtK29LrfX5fa63F6X2+ty
+e11uuo21aT97XW6uy61KkNjrch+GLvcfJ69evjw/ufr64tWvtYL3KtngU1jTXdkk1+yoyP2w/UxW
+pci9vH36zdnrc67m9iGpO9OVv7NO8Jdnz16e3XmO6342a7tkD3gv13gcb6Fkq3o1T+8WHVf1Vp5u
+EB2f3i3Br2sPv9zjlX/34uz01cXJzRMQ0do+fhtG/dfr86vbJ7sIt78hvbn7OhxGY8yarsS9dLrD
+pj+saxsbHue/7t6GW9s2/vW+TA2fFid82UjWX15tG7cqNvjy9s3F3Y6aC6a9h6fXF9c3//7z8+2G
+2N9IkMRdLDb36ubZyenZd6cnO+xxVbFq05Uv9sUs8Q+/vLi+Orvaxd6yqs0tlr9tg8fXVy9vT3bZ
+4Br311f/zkLPR+LuWCEh/DTI+i6um9VabD5ND87HSQE+KIfnjnTg4vz2ryfnW7nSB0cIVkjXHkYE
+Tm7Ob59fnt2u68ZNiMFkYz9ts9IMbsw17QTWu9jDNhFsrXuwG/bgPyxBE9a72MPd731de3D3YI5/
+Orv58ddijJs+Df/+YfPldRrrz+/jBvpITmSNUsVu5/EIX9p9lnc1eLt1RZrcz969sk3cP4oprGsj
+D4xiWtluHhbF9PXZ67OL756fPL3+eZV5KR9wlM+frm9ePL++uP7xzqf+G7Kom5On56/ujgyzR6vK
+fpZVL/XeD9f+dW/DxKr2sc0isbMW//T84mRdbqbtGvwOJHZVh7MDTd0gaO/J2ArJ2Lru1QPCLde0
+jz3xWvHh3It4fRTBoqs6hQc89VXpF1tdJzs8i1VtZFPSxw5hrofrihF9c4/HvU+Jf9/Hsjklfhea
+ta4n8gCitS6B8ZGy+le1qcfL6l9VMN+nlNX/zhx0VRfwXpLlN+cvX1ycnJ5dnl3d/unkxYo50CdF
+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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ y2v0ZeXv7vWLl+/Lyt/+69st35eVv73Xr7Z8t73yNxz8J/n69Zbvtlb+hoP/9F6/4L7fw8p/0kt3
+zde3wLR3uPI3HPwn+foVaNwdrPwNB/9Jvn4N7uIWVv6WBv9Jv34/K39Hg/+kX7+Dlb/C18//+Xxf
+v4Essx3qeMBz/ziv34IUuR0KeYBz/zivf5Hf7/v1W5Tfv/A2V3r9y8rf6+u3IL9/Wfkr/dxAiryf
+ld/+5xNZ+Wucuvtd+av/PLCVv8X7fj8rf/2fX6+e9hpfX/75hFb+fmncLaz8xT8PeOW/cBf39frD
+4C4+ezz/YOb+2a/8g537Z7vyD37un83K38Hcz+/6E115+rmtlb/Fua/+fHZnnn6utfJ3M/fLv3aX
+X7+HlV/++ViyzBW+/mte+Yex77fw+sdZ+WsM/uN+/fKfT4yn3WLwt/D17X5+XSt/Aaa9xa9v93NX
+K/8w8fyGlb/Fr1/t5xOQJu4A29zu16/38wCliXugsJ/syt/Cfb+flT9/4Df++hfLyMZHlw/8xl//
+5Cwjy13f9X2/n32/3s/HssfdYO4rg7/8Kx/rxj2M+775Zyut0SWvX/TzcanMg79xd/j6Z7fy9efL
+yl/r1a2/fv7Pl5W/1qvnfn37ny8rf61Xtxr8xT8P/PWHtfJXHPzFPw/89Y+z8rc0+M/q9V8Td3G9
+1zX/ueWva2VVq3bznzb/Td/q4A2kgzfeRhuN1/CdDfUSzn/9/B+jBkY7G2JMMYXorDFqqOytDF6r
+1mjvkxqkXbtrB/2kfd/E3P+NB6/Vnh3GwXC4N9gP+2FvsGvSnk8mf/KmK2/y69q6Qb/d8/v9/b38
+Z7ivd1Uc2qHau+mxyYvtVX8vD3uXK1oM9nw/uIE2tCrXHzx2nV+/qPfrD97wmoR9KMpxzppcb/C0
+mbu7sHH7JvffLu/ntv1s/jqdwkHf7Q73dnd3B8PzTuF1Bp8vi9lrzWC4iysfw75zdIOu2tPmrzud
+fNsPA91aa7U7/95fffD5uLj9tNd3flcjhQ3br/TlX4fj0k+pn8duWhUv7vpqg4fjshv7AxP7dhdO
+361iWq2iaUMfxp6vjVNOmaU/a4TjKl+3eTt9X/eNH5igg3baAbZx/Mfk2YTtLuqmr+OO9vXAReeH
+bt/tlT+7Llqv4/oWb00m8Pbr4XCw349pLw3TAP7k1/P/+nE/DKzOp/6KB0i+btS+3Yv7w+GuHuS7
+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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 8D3+fpFZ3zHTP91LeURLRPDR2ezsFCS+e5/dOpvUyyh5A6fUZmytM/IHFkUb5hfyVXeugJ5WELAp
+kfgUeXEDqPPi650OlwY121Y/lhHz2tcKrNN3eXcTbOmDWsW1r8S09hEBdfuTNzfBlr6R1NonMh+3
++gkBdbqTFzeANq0ab1qXKz3CeS8xqSZ0udIVnnWFo329s3p7dbrw5NeL+9EO8+qIMw+8/V19OMOO
+wDhviyafvPrhQ8YxB4+fz49Gs8ypNC71ok8hd8bI5f9+lDldLHhZZ7ondUVCWpGfoPHKr0sntcg8
+KN+AEBTjsrDEgCpfuczKLAlcg9vjqACjVtkM75WLIjSG6ImBy0MSOPy1wM92MhfIomdmUoQBdxlp
+GtUSl2qMv3Mu0LWhF5AFZmYaB5E5OucSs9wZ6biMuzxgJWQFU6ZvLvPpSpu28u6Zn6pAYfKnBEwq
+S5zACrrMqHS6B2HB6KYOovLZLkJtjxCZG0+wi5kdt0Ezu55fi57ZeU2frw2A6ceTUDppqVLI2nzv
+lQ3cRjKwimYlkkGWSHp5+iS5JNO2F56JPPFoszBxkzNhdL6E3hMPjow5DiNzMlB6h7j1LA3AwGJK
+IvQBIGYZhncaJYExvCfAoElmmAKw7XncqQz01mSZu3YPJyw2nUGgYJBvRb7DeGoyO2DzHTHK9XSr
+CKJTyp0oIxDg+CMNoDbLW9+28GLpCmTLYJv1GV90LK66xltKB6ILyMviwvWEg4tUMI/U9dUTbbzC
+kB7p638otVf5kLn+h3Qmm1f4kr3Bl7LMe4UvuRt8yV/l5DzyN/hSSFf5UrjBl+KV9qm9/peA7F7h
+S/EGX2rNlb7U/C80w83f/Nejl//1zfW/6xKcxK05Zfju7LpfftoJf0KlPvrZf/1s9Hby8mR0OAUL
+wtvT0XsIF5hhAqjj/AisnJCLfdKcvpv/AhB4qbzw9dd7P+7vfPX/AXGZYYA=
+ ]]>
+ </i:pgf>
+</svg>
diff --git a/doc/images/mpj-static.png b/doc/images/mpj-static.png
new file mode 100755
index 0000000..42e27aa
Binary files /dev/null and b/doc/images/mpj-static.png differ
diff --git a/doc/images/mpj-static.svg b/doc/images/mpj-static.svg
new file mode 100755
index 0000000..e2d9aee
--- /dev/null
+++ b/doc/images/mpj-static.svg
@@ -0,0 +1,2590 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 10.0, SVG Export Plug-In . SVG Version: 3.0.0 Build 76) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd" [
+ <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+ <!ENTITY ns_svg "http://www.w3.org/2000/svg">
+ <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
+]>
+<svg
+ xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" i:viewOrigin="100.4473 639" i:rulerOrigin="0 0" i:pageBounds="0 792 612 0"
+ xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+ width="473.053" height="170" viewBox="0 0 473.053 170" overflow="visible" enable-background="new 0 0 473.053 170"
+ xml:space="preserve">
+ <metadata>
+ <variableSets xmlns="http://ns.adobe.com/Variables/1.0/">
+ <variableSet varSetName="binding1" locked="none">
+ <variables></variables>
+ <v:sampleDataSets xmlns="http://ns.adobe.com/GenericCustomNamespace/1.0/" xmlns:v="http://ns.adobe.com/Variables/1.0/">
+ </v:sampleDataSets>
+ </variableSet>
+ </variableSets>
+ <sfw xmlns="&ns_sfw;">
+ <slices></slices>
+ <sliceSourceBounds x="100.447" y="469" width="473.053" height="170" bottomLeftOrigin="true"></sliceSourceBounds>
+ </sfw>
+ </metadata>
+ <switch>
+ <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
+ <i:pgfRef xlink:href="#adobe_illustrator_pgf">
+ </i:pgfRef>
+ </foreignObject>
+ <g i:extraneous="self">
+ <g id="Layer_1" i:layer="yes" i:dimmedPercent="50" i:rgbTrio="#4F008000FFFF">
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M128.553,152h-126v-14h126V152z"/>
+ <path i:knockout="Off" fill="#DEDEDE" stroke="#000000" d="M25.553,152h-24v-14h24V152z"/>
+ <g>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M297.553,152h-150v-14h150V152z"/>
+ <path i:knockout="Off" fill="#DEDEDE" stroke="#000000" d="M170.553,152h-24v-14h24V152z"/>
+ </g>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M380.553,152h-58v-14h59"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" d="M431.553,138h41v14h-38"/>
+ <path i:knockout="Off" fill="#DEDEDE" stroke="#000000" d="M345.553,152h-24v-14h24V152z"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" stroke-dasharray="5 4" d="M381.553,138h50"/>
+ <path i:knockout="Off" fill="#FFFFFF" stroke="#000000" stroke-dasharray="5 4" d="M434.553,152h-54"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M128.553,138h18"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M128.553,152h18"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M297.553,138h24"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M297.553,152h24"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M1.553,168V0"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M145.553,170V2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M128.553,169V1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M472.553,170V2"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M320.553,169V1"/>
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-dasharray="5 4" d="M297.553,169V1"/>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M32.553,15"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>First section</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_1_" />
+ </foreignObject>
+ <text id="XMLID_1_" transform="matrix(1 0 0 1 32.5527 15)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">First section</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M181.553,16"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Second section</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_2_" />
+ </foreignObject>
+ <text id="XMLID_2_" transform="matrix(1 0 0 1 181.5527 16)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Second section</tspan></text>
+ </switch>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M29.553,11h-16"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M8.829,13.05c3.307,0.999,5.456,1.919,8.108,2.983V5.944
+ c-0.949,0.451-4.802,1.985-8.108,2.983C5.29,9.997,2.081,10.729,0,10.989C2.081,11.25,5.29,11.981,8.829,13.05z"/>
+ </g>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M177.553,12h-16"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M156.829,14.05c3.307,0.999,5.456,1.919,8.108,2.983V6.944
+ c-0.949,0.451-4.802,1.985-8.108,2.983c-3.539,1.069-6.748,1.801-8.829,2.062C150.081,12.25,153.29,12.981,156.829,14.05z"/>
+ </g>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M269.553,13h14.376"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M288.173,10.95c-2.971-0.999-4.902-1.919-7.285-2.983v10.089
+ c0.853-0.451,4.314-1.985,7.285-2.983c3.18-1.069,6.063-1.801,7.933-2.062C294.235,12.75,291.353,12.019,288.173,10.95z"/>
+ </g>
+ <g i:knockout="On" a:adobe-knockout="true">
+ <path i:knockout="Off" fill="none" stroke="#000000" stroke-width="2" a:adobe-knockout="false" d="M102.553,11h13.834"/>
+ <path i:knockout="Off" a:adobe-knockout="false" d="M120.472,8.95c-2.859-0.999-4.718-1.919-7.011-2.983v10.089
+ c0.821-0.451,4.152-1.985,7.011-2.983c3.06-1.069,5.834-1.801,7.634-2.062C126.306,10.75,123.532,10.019,120.472,8.95z"/>
+ </g>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M383.553,18"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>etc. . .</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_3_" />
+ </foreignObject>
+ <text id="XMLID_3_" transform="matrix(1 0 0 1 383.5527 18)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">etc. . .</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M18.553,131"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Header</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_4_" />
+ </foreignObject>
+ <text id="XMLID_4_" transform="matrix(0 -1 1 0 18.5527 131)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Header</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M60.553,130"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>data</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_5_" />
+ </foreignObject>
+ <text id="XMLID_5_" transform="matrix(1 0 0 1 60.5527 130)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">data</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M140.553,131"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Padding</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_6_" />
+ </foreignObject>
+ <text id="XMLID_6_" transform="matrix(0 -1 1 0 140.5527 131)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Padding</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M312.553,131"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Padding</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_7_" />
+ </foreignObject>
+ <text id="XMLID_7_" transform="matrix(0 -1 1 0 312.5527 131)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Padding</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region textMatrix="0 -1 1 0 0 0">
+ <path d="M162.553,131"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>Header</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_8_" />
+ </foreignObject>
+ <text id="XMLID_8_" transform="matrix(0 -1 1 0 162.5527 131)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">Header</tspan></text>
+ </switch>
+ <switch i:knockout="Off" i:objectNS="&ns_flows;" i:objectType="pointText">
+ <foreignObject requiredExtensions="&ns_flows;" x="0" y="0" width="1" height="1" overflow="visible">
+ <flowDef xmlns="&ns_flows;">
+ <region>
+ <path d="M205.553,128"/>
+ </region>
+ <flow xmlns="&ns_flows;" font-family="'ArialMT'" font-size="12">
+ <p><span>data</span></p>
+ </flow>
+ </flowDef>
+ <x:targetRef xlink:href="#XMLID_9_" />
+ </foreignObject>
+ <text id="XMLID_9_" transform="matrix(1 0 0 1 205.5527 128)"><tspan x="0" y="0" font-family="'ArialMT'" font-size="12">data</tspan></text>
+ </switch>
+ </g>
+ </g>
+ </switch>
+ <i:pgf id="adobe_illustrator_pgf">
+ <![CDATA[
+ eJzsvWtzHbmRIPpdEfoP536YCDvuNlV4FuA7MXHJQ3LHu/Qj7Pbs7B1vONgS3a21SPXq0d7eX3/z
+DVQVziHVYo89NlUzbTKJQgGZiUS+kPiH/+vXv/3i9NXbr26+CCfT7vmzf/iH/bub6w9v3/1sR+Dd
+z9+8+fj+wzsE/eQ3P9256WTCVqc/L3+Qlv9y8+7967d3P7O/XeLbPzl79/313W5//e7bm7sPN+9+
+uvvJr2/efXf9/vV3N7svb15+c/f2zduvv99dXX/1fvf/7n5+9+r19d317nd38Hfo78P3P8Wuvnz9
+4c0NdLb/2e9///L7r//8+u73v//m7e3N73//6quXv//97bf/E356Cz+9vr3++uY9Qb54/+H6w+uX
+J++/+/qnNiEY4Pn1B+hqfuHdCz9NcRd+Nvndr3+BTc7efoTv33199vZ/4zSmXcx1l+a4y6Hi3//5
+9W9u3q8bncQ4B2kZTpK2PX/78uMtTPnX796+vHn/fg/TfPf+Z7uzN9cv/9T//fLt3QeAn757ff3m
+F1/2f/nlzc2rm1ebv5/+PP3h8vWbG0Dv7fWHXSZkn/48/IE+8bv3gICf7ehngs9/+Dni5Lc3Hz7A
+oKEnos3+F//9v/Yjg5nI85N/+83N16+J1ICs//FTpnLm3n978+01/wH643d+An/cnd/88frjmw/8
+2V1rBT9++Cmx0/+9+9W3CHlPb+XdBP/D/8+PfL4YQJ8vHP5fa7b9CX/2OyABf+fXvz7Hb3hukIGI
+Cf7s5QW3+QA+P6FBIhK/vLn99g1wCFE3TBkIGmrC/7aftSkQgZkg71zapZp386x/bOS/+e71zZ9/
+tvvl27sbod7puw+/ff1/gErZ+d1cvYB/8/HNzTtgfCQ3wypj/RdvX928URi9fvnm+mvCZJsS/Vda
+fHn97uubD8Crb998/EBrskz6t19+vL26/v4GedHJR34FS/PLt/9Cw/zC13lXAGVADO/DrsLMPJMr
+lt3cE0t7xNfxZe12Rjr8GnjuV+9ef/367meEHmaj8IdfX3978+43Ny8//OwLh/jKhDf4WRv8AsbO
+L30h/09/Q0b+z+9ev2p8PPtd4f/Q1E9K9/9V/19mCPj68OHmTpj/4u7V/u0tUuc9rXrg9ztYDCCH
+5K/tF/obfPPjt8+f/dvzZ6G++F8f3364eQ9DeHOzq/nF1++uQZC5MHV/+Or6/c2LPwLhXt8x9NVX
+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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ ey/+q2LdqBs8VSjMdFrL8FO3jb/wonfvC7xdg6TRrScn4otolcydLrjAhHrRX9d5NPqDgUnzIpZw
+4iXP1wOtI0a0DqTvcICCaiane88Vpy1L7tquYxBLl8/Vs+JhuhZrUTXouAVy8Ytose3j4pF+Mc0q
+kOHDo+MYU8gLoIKYrjuUnWhZ9tsVe45+HWmXf/i4x4KPVw5pDFrzxb3qc00Va7B2c7LfbWmp0N2/
+HMXSOVvoHmUaKbbBu6nAtdhDcyxWLggX7WTc24nDUlyc6GmMTwfpz3Lg4BGwQKn/tjcweXsxxqEG
+tE70OBMmn7GDV+Iseb8YbyP/WdbEYWiN674kywjB7lseQsPs41sFb5zWGR/gDeaKqpe0OLlS9uxP
+J7FyHn7/z1Lk35znh5KjnJ5w0w826Tl7xE87LE+mfyecdnj1j9vHdloREeNCH2fwZ4njy7ad1+4A
+O/20ps9vvv/Fb2DtqKLbwRRMqEo3NDHkUEFGXJ5evGX5i+Z4H5niNVCqXt+y5b3Tu3ce8Y97O/gx
+WnD6l0vhr23TWleC1Sk0vSk/iN74wv/eS2Mvs8q7wbuvII/FF2bwhbG2EhSkO/JjbaQZJObLxxGY
+c7MDUEa0VJOh6NP0V8PaZr+2CrvkHQM4gEHV4JFTjNaJ6+jXp/e+C79aV/PqsXWaYZy71Prc8uLz
+m89/teq1f/dy7Dw4nI9TDO1hQukYkoEZYc8IYD+N/KtZ6YXSjOhNdb1z+ojZjNPUHab2PVxp2kXE
+3j2N34keudyL/NAIR+31Gpk0ALT2tvTbzH7x0odpVbOeou1Y+rAG4K46vpQevxHDi3Nt0WsxLORE
+r2B+EWekq4EOX9VYLyHnHSBfcsS7mYDmqWlGM/DgDFp0q3qRJ5K5ne4F5yBmMGOxpYMRkT7vH3rZ
+DgfwZnV2usxv0iCWejcPbwHR5QCIPetLrxONEbyTvP+aJwWDOKuLCs/LzOO362RJ5AjmhHc56pBb
+B7+dtZLmCWJO6wjrA6U6WOAHJ0BefUCEG4ZjyiI85E1uXfpYtveOZJ5mldAY5lOzashT8ZrJtTa9
+VPxiCtdQ93xoG8SbH0B/796EC7SaInxtRXfZdWLvFARJbpV83Ue1KrOVtOnLbfXhxVR7ybEUD2NB
+JGwuRtOsMxu9lPQ4MY1HxKr4Pb0JnKzOCS9k0RrG9EwE1afEAN6Yyuml69x596z97fncWflJioPf
+rbDFY/tew7IGj9hrqyeI6KbvX/pZeRHbRsO+fGyQx0MndxTSAD17Ps3eW3acBuCBtr7Ci3tmvXP1
+capwxRjcp8ffxqyot+IIjcE6o6OY2Ymv172CiAwpDOuy3bo3GN48rBhDYnTfoy0YTc9fxIQdeRGL
+ZF6T18ZoM4VT09AHkWE1KyqgjWgVEDh4jeXU/mWy3C4wfFRZYvYxVE/vmY+Ao6eyztOmgUZD7LqT
+zQQu/1yfKr9iOPxH/e382QSUFv+4yQ60CjKeQ8ON656Q5nWB8PkZENzkkNGVyYeteZ4POKbaFq8/
+0EvAQXdDhEwIDh6wgywVFYLG+zuORuFTl4g1LUovj8z+1AATitlL/mXyz7pNtqtItD597gMyYrRi
+OPHaxOqEa9w60kEFPQngFsq/ifBZ195BfbzfAGuhV/BxJyDfZap9o+T60orEfUzBeh8lTtevOo4m
+/Ry2VquninOsjKuK3jtGtHxfz2bTgo1oDs7SblywK1bg6xC6Am7o5LyAgXAWB2vsKqrLm2WholV4
+7bzV0vUhs1wgPrkOUsI17Ok6tEnnGjpyzhab2oEI9fxF81edA5gH03Pk1iLQkE8rIbnSw1p9XEWE
+HDs/xYTm0mAdxJ32UanKK8vPv6u90FkUqF1nHpw8S142piy/SnEUb5s+5ASkeZg+tWAuD0L8ORGF
+2U/q0C/Wt1AOQRZFBdaLbopipU+Mvq9mOKji26Z16MLnHECn08uwLOs16+M15bkq1DbuM/jVKuWI
+pdi+p1Apz3R0knDi6G4qGoIuHIze5RhXtHqLE+qU3hH7uKhTw/RySbmB3DZr3D6kdjnmKf++eUmt
+jwr0O6fNCclRI1fFusEjh5WS76d+vxZoX4SyANEPnxO9EhPEVYaEwYJnDQsrueerAmsVtU3DSpzc
+efjnOXOMz9bSw3+7HHv3kGl7EptG61LI+URYL2s+Ug2AFR/6+xN9LIUEvFE2X5+jy0lyGbloq+lo
+EEu4J0tKeqi+dipSv23UFJepDbwv9E/zGCnAEIeO5qYSFUeUsSDM0CrV9UHvRCQkjnMzyJNvTeQf
+p5iLqyIjY1TzftR+Um8ig7RXfYxOjEgrLf4wqJn1j1OuaWjaMYXSoSZO9B+K0E9u+rzTaSd95kqr
+46Dik7dC5I7Stk62QYzLMbZOtZ2BDmc4lLFKX+IZMezKs6JvJ0rK34nMHL7aPe6FFF020nZPO5Rf
+jzRWKi+sOdzpzyA25hCQojrG66Hh30bGK8KpRj9GVb5pplJYdhJqzF8C8PrrBYU51986HcSJIopQ
+KN9Ttx3YfPx22SsvSr9y32oR27wnTZ+k8okYRvJOxRYk9VvO8/Duju24HCwH5u7jeg+sDMt064/r
+wfTuYE25xfRbe0Ha0qA82V6HXE6p5xo4I1PsyoKMFBYyAUnqtykw6COMAyzMDSJ8rJTfuJ8OjRxG
+44UL7gT4FL0tjTy0kLj83qhpiFhzp/nvrWdiZCbc63jGyAlhNe+FWftv7x9nCaszUSkWRo88+qsj
+4mi/Y912zXRzuvUkPN9+fFgSRUoLr8thILMwXmmS4VN3wV+cCPal50iFb2KPALo8J/wxRAylVXCP
+xkmOx3ZShMXj5YGrfFUz7s/An/rGS0OprkZ/vT/9IH/eyV3wfG+jfEfnML84TWHR5KTDbYeb4CCg
+4vgueJR4vEtLvDZ2nZ6C67h/WuwwzgcFbixID8ZFjvO9kSS8Lp3S4r2s5SzK9eR9Jx7dN7ALOsiq
+y8fHvPoWbiv4/yA1JYkVZxad552ZN/z4/a/fy2/DoVuWck5f7zJT/S0v0nh7eu1L63Z8eym2LL08
+CvvjEs/l2xT+RO2WupOm+PVAz1GhJeKJI3GULh4tO8oI050ZdT7fpxvyNoVffRi36OazGmscrd1m
+KAUps0H29cOWImohVeykyWwJcCFqyOvpYJrS5XA43h7PHFqEP83/19/WN40mbqt0qBOa0xvd660/
+7+N8R9c4f97tbmX0k8b99X7rOdd3hS3fFbAMULF36+v6cWXcbXt973P41Rt4Vu/Oi2SB4JtqdJT1
+NsETLQve+aLzXRYj+XVh3NsE/kQBxrvJJcbd3vfYl/SWRPgWZ7sN86vLL6yZnX7XHQPMR7VoVTnx
+7VPkjIDXG/02zK9X1tJRTsZG3BY6FVZCNQiIi1HnxKYaJyWbfIy7sj+Nqs5tBp0sm/cJ/OKrMiNJ
+0sr3LEH7S3RH577YHNbQfDZaJ4C6eRGrctbM63I06V4WE/vtEsqcbDq8nRggMgJz7nvk9F7rmzU2
+69mfRBYb3uSabzzibPN6sxS9813jsAdN2zsTfmUyoe1isaxURp29b0aklyDr7RRoO9j2zL1bQ16s
+RKegQ+Ju6z3JqxsgtU5MTcFDoMjXwxzreXKEAJN0+kDTBHTo++GlPscxNCv63Jbh/sAwXeeq7SgB
+Op8TD7VEkF0lEK//nhaZPE/FQgeypK4CNKEpA5yBFVVMno9VHqz8yEc5X7yCfoxXH9ZtH371Ruu6
+6jB/vb343hq35K0JXD//1eJLyug0aKF6ymzk3bLp2Hn/fP78T9RLkkIR8k9+ie7I05cUDLsNCJyc
+PZyGO9LPrpe4I6KfTqhy/M4Xb49KYgyw6bPF02nNMTK9zeFY3pc3guw7t+oqII+soILokaDl7aHC
+NRRkqMIn2WtzgK/iu3WcXEtJ0YboHnZZxPDmFte7R8TEGGDLlRmfznId0vPM9UiclrtZPqIXhNHK
+4lQTgmoeffVAgga9SaoLu650ysuTuPuGmFbb68qpzysTL98e+W216/dt9tiXs8yTZLwyYUWVz+bA
+xQVv33poz17FFPuizaKger8LLe+s8TM9nI7WC1N3vKpS6XbLfrE6YVHZfHniv0TPaXKRCmq8XoS1
+xps+8CLO/4e9N+2t67gSRb8H8H/gFwNu4JGpeWh/sum4X14rA+J0bhoXFwZNURbbHHQpSrby61+t
+sWrvfY54RFL2lnQSJJaX6tSuWlW15iHrc+21OSBbtQj2dYbF5/7715KzIRnC2uHUVMVgHQEOHnK+
+1C5Mqoes/smWaR5b0BaBWr57qYJzzLNVTkcXyXzaMMkj84UNzEAudKH2iZdzJsHw2atUH1p/0kVz
+zaakjeFP5iSgH8P8gxveZuklZRZLfk/2cKZ4RraMT0QfmdCsiZdxOf6xxQxlTfPjEuZSqE7PRIgb
+z7CzwsmjX0z8yAuHyMEoZHpYedczhkVOgXwZspdySNNo0Ak89bOYTCJxppNlSLzccm2PHzgeJAoV
+V6hx4yJ+dKRvGv7YaeoQ0OPz4iwmrEPOYgo0Knl0bjB43wtkabjpe4UJqM7agPLJrHFQchZLe/wH
+lFMdFj4P4Z+Rq2H4FjDO8quVorDgAqwD4bkUeK7z90twNtvI6T3ZMs+vqIBAIV9hAVIPZAYWpE6F
++jl8Os2vdgZOY79JS7kUMNdwnPGEcTg6mjfAWdl5ZNMs25nlu11ucmxzSFDDee6o5+VMYQP/Xcz7
+qNQSZaDkJOK9WDNYLAVhHAmvMpMgPvSing1IZliZZOPMjx22KQEl0BYF4vsvBVyx/kdK0O+bqqxA
+/WOKXklckJqA2K4Cgb5EDRRX6z4ErVEocAgNRmODxn1CeUo0HnFdXQ7SdtCWnqvwxugl7DNQPho4
+4osGjjrKRIIF9NjaAFXa0YAyrhbCZBHzbb9Y8vNwDDFtQMxq4jV46PMAx5egoVXSsHgO2ICGnlVC
+7adYfGTTEdjlAq8a+1uxKJKkPmY7JWcpwgpLNSfaduLoX2j14QUXGBKsZlCqWtnPCFpYUgReipq2
+2CUWHqh22BT455LC3g258ikCUp44tF6BOp76e/ZxJuigkmZG35SpwxcBMTsEMRC8GnCG1UIFfO+m
+GKjcOmADBh/zhCZlroF/tP2P9anbP59+9rv0mFWx64OqYucCsT6VmiyGdiTcLyFXp31XCfxkBoYj
+t0U7bOos2+B9mqtNJbHb1NCp1XHnH2yieCnwArST4JY6qmD90Cwtdyp1LjTY6Y1HWgmLRjiWPaMZ
+ov6emzlh9Q76UAVjCLUeEsEO4egYoE5FaGZGYKqOgcFhcfQNW3gbkYb2GyWntPPzb8u20osSdtjb
+kja4pwaeOUt5eYBVGUqd5IwdESSJgASviRs/SdNkY4fNYMYIA0vkVupS5pgmKLEsxvoijZRs1CXM
+dvDYKHJUo4PbbknfAihirAuXVs9QGtlK/yhpQw+1TpJhZHifpFcClErRlUsPeJg2Bg==
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
++gzsjVHrR2kfKhcTWrDbmxCt4YCGyTsUmxl1+atKsEoc337QYHXw1/alVMEZBBXoJ7GjmQ4feOqw
+6cnRYJ+1GEdMTFuygZWV9gxNlvqHnJMjn4wftattcEvWRCWojGr0YQwlMXgfE/BkzRe7K6YRoN//
++frqrzfnV7fnVz8eHjIcFdbxbz773Z9f4N9ZQ3/53T/+49vzizbVZ7/7vf4ZYvB//88/Pfnz9dMz
++PMXzxA8hOL/cnlx1f7yEP4P9F+Mxd/8169PLl7R31tu4T7+7a0UEvz9Vzc3J2+WXz77+6ubH15d
+nF2dnv1K3/+yjzh9fn7x9OaMUg1+P01SmCyTpnn78r64vWsnfanuUZc6DGvX5ub8h1e3Zy9xYPub
+Pu24oZuzl68ubnfa0po2I8ueb+eHk5dn396c/d9XDftv7twVxJCuaVez1c83d/Xq8i+ntyev4Qd3
+7MytaVvjuud7enl7fnv6/O/nFzts6ur6Oxy9pr1N1v//vH3wfO/Pzo6vL19cvzy/XTPJO7+682C+
+u351c3r2HzcnL56fn67pdM6vljfu/Grb41gvucM1zzdy/eLs5uT2+k52vf0Ef5O99A==
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ qaZiJsIn+YpHCwRJrFgwNZMLR2o2kYoVFcjNJWoZ+ioUtEJKqHfkPixYxlp825qH0m41yd0wMnYz
+J+iShgPuc3Zq3qMi0033s1pq1/vK+rWPPfwTMhVZlZYiWKCGReMFMVlMK4miDJni6e8TB8pGcv3K
+x2IlIFrRSOiKRTL3YqgTPZPTTLHcPAvhhnOuMcWDYQXzUS0UUynKI8HfYjjLN/WOMcbQdgu5BwhY
+PcU6ZyrFoStAiZXK5HYZhmzFsAcX1BIEd4rize3gCqHSKrUoP4ZYpeT5ImbumoPWJcmlwJyDY2HS
+JLAD3HIRYZT9K2cSoN2c95UDh8djNetTQQLGSSQMQCiCMCoFnbDTw+znjUaEPGhCtkg/BVdFzHB8
+uVE0YXGE+4BUKmvSnUlSslkeTa56txNzhAxks0r6Yh38IULnqxQSRS2qJAYmZrYwskqJYpTxj9Un
+EzNfbsy0YDnLUsVp8AUUORbxFqPxtHbZNnvJrAypSiEbGVzQrkAwg+8AZ+3uMKydVMVOFYuIeiZx
+eoIUe4eBXu4A4vB4MBzwEUqjJhBVM8cRFjb/Z2nGgodViqqSifrp0GqtlsmymucjpSILuzGA06XR
+LSWxcUEDcIr2PQLDvFS8N+oag9gZOyizIrsZLbA/TOt6FcOiFjJPazgWLApjZWMdT2slcprTArE0
+kGXHSLsytr8DbGNA4g23xIDnlbgEvRcKY8S6iRXz3WC7k6xhL21VSM+q7O1wbJNFxyLHvAxF+3MV
+Joo+WiN30XIXrgipLHIOMUhLB2RQepXYko98g2Oqs+AWhbwsFVilXG8hQULR6CubvJwsIaGuQ6oI
+R4TjlRFdJhptfpDZIE7LpeK6WO1KdS9JMoUD49Y03NenPwcnjhKRZmAwa9heS35kbcbkKOh9MYHt
+VdSKWJPLWJeK2gWByc+6QVmV/hOVrMW0L08yFiZoah8xDj1C4uCGuk7Eb9A0Y6PUDJNCjlbLvWMl
+OctaNN77bloJbFkRqxoWkeJoW2mYArAouj02F+u/N1zSVZJkQWPXS4MuOB7Iq4JAn25TixL2jK4i
+5kySRRaKlAtrtJOVEl/HMmjGJpbwgg1iRcpVQves0/J6JkvXAmfVBwoYNJaN/4nL84NZjf1USdcE
+udxWS8qDKY8vspEeOaC+cSsUSBd1LGUGPgFLugwuC3US+j0UOPTiqxCPM0aiM+2RYoApi/WxsnOC
+tgB9HmzmhWHnDgJiui3xsWAly1E6zNXRGZAiFRBDOJYjOaTkenLhQo8zKQgZOhM2VTsvpMRpOyBd
+5CgfYxQkldqgnxAjNoyxkrAApdY+OOkck7PU0cSCboec5Fr4GoWeZjdk3rSbyv0rshEklK6GpU6W
+3dDDDM/BiTfe+iqDuWFTMVroGqKL1e/vnXonochzYVNgcE6K8XJzEjC0sAsQgDwyQQHEoeZwCZWz
+yiK7daDGr5OKh9wZDUvTenZODFleUPOCW7ckrRFTyMZPhvMstyMSA8Ayer0TinQfgB1wdeMkxCuX
+jsNI1nZKxdeoIzjeJJvFLjg0ARdyBtoauMeM2uiB3vUOUEnNyoABTnaAwVS6GgxbmcPk8VZxrTwM
+tNUZuKcAlCHmeK+EzqhKQGe9FFV23oppXStY0EOnyoJgLMpSMpflQvyTl4KlbPDBQswqbENN65S5
+CIlanyG0CBcGpxS0MAdaWCFrp0zKe9IzwWweK4wBq5oj0EhVhdwry6D8qJwleil2JEX6gXVQs8TU
+ewqWvgUGqs6EtlaGq5cbi17T51idxUAxw2uwwQ1ZJ5XK1KdMUTyHaLBh3MJJ16QBPXRrYbW9ymzV
+eIOU1cOITQWol0XpHRvLEWPL2awRbCipV8YiqYhD9wAYTD3GMHyaF5BJh8UZsK8e2VaBvFBsAob2
+4q3BbRnpi0jaNy6q9L6IoHU5Xixa7gnoUXABOkJcH/vccd8qQ1qhTsDdIbBWMH3MyqRQrZF8Ewj0
+4jZL0fu+BYlRchQIyV/jogaNtsoC2GqXWQ/QBZCxAp+Z444J2jwUq5I66Y9BIjDWLBUWTWDDtYu4
+nwguIIgDrHgpKFOkTRuG8fLvAxvCMie2cb8FdoqBnlB1TgpDRHfq2JmQW4KBf6IYwWHStlXamRB6
+pYro1pvCYeB2dJJrGpJEc7M2hq4Y2kJbqxGfC36KJ0jQGYE9YBynA8BC5XYxmqa34lApqYua1DYz
+cFRY8iXzYGulEDi37aTKWSJYTytqsfMKS0Vn6cWYyU6KtnteGMQSSUKE9lfADhOUhYthPFGKULGq
+iZFdRdphSJwplFntPT79sAnuY4MJAEbK9PuapSUHU1sQ+kEIVkSKjhIkPBMP3hkW2WPUJ51JthZn
+bycK3DcpU9aFJD94SRciKxn22ozSJQKDGvQo2BAN+R6Wa9O4IycmruBK1utURYCCHNtjeVJsRK1C
+F+nyWrGRadUlsT4maoOiaHQkqNRIrSAmB1HJ6Mnn4KWFqNV8eqxwldmKSwIBvgdNOmMrH+CQe3pi
+TohmFNduyHYSqV8x9KXnxvBVMmIyD9RDgRdgpFEXRNz0Sj6su2HTMO6+WIWbg8LfG/9CWRWSNLA5
+XpDBWcNeG5GXNrZickhDRVwAO6mg4knqbksgEVbsyvjbwIXP0LbRv849aLmY/yEmnZBMhSZgaXsk
+Wiq2iu59P1BVcGLk4sw/sEhbSQjOlV0UgQ3WaM8DtfxYnVAKN85IVnwTwthc7JOmF1ENaQxF6m3v
+KteQRhsN27Gr5tVCnIzTTlO01f4KMG2G3Q6F2nbwjJWDkgwz/CSgSC3Z+OdZVF+sTOelgUxiy0qU
+qodgrXNyh3NP6YSvsnshQC836U3k2J3ju6OroBeW3DZDSQVIVKUIKkcTM3UIEsSp7RezesQctTHS
+PTTxQlLE5Mpga2hPn3PSBS+K2x5EHeuHE8COFeSMcIpE6VPRbjHH98Amk8RjY/Se+vso6wGTzIK6
+9kSdi1Q7iIHRM4HwRnUOWBHxpsoVxmlaV6XvkMpugdUbQGTPVYBz4fB/SJQw0l+1FBks1fmXftPT
+t6RAffNYWZlSWLRdGKhDCHUZ4B9NaE2D/zcvUguNdLABOdQZ7dVsKD5ytEFiRyW+z0D9KsNYyYK6
+YyEOVbW6vdLJBJbahJFnTEQacSegB0yralG6n+R5c0NAMEE7YfskJ1FPJ8uVlWpv9owZi8SzPfd5
+BV6UJHdcG5kXjB7ANWH/N/29MCartURgUuZgVoM/KjZ18QT0SbOJ4UlFacqoBLRIQBlkVlWrwCKO
+2JLy+Pwj41arDBaxQgRqOM8D+T2Cw8f3BYjRJYjZHHx/tjBjj0UC7zN3+o6TCqdAfb2k1HNds6ol
+PbGfWZSXy10VYCnQiVTpNwvcQAvZiAszpCx1IopOm5jOJLovSj3EEQkNoqtEC5QsYgCryliBJ/Jm
+cSBPoKoUWJnYeobkxzBVY0kTCbvlA0e9Tyew2mrICQ1VbR0uAnf/gSwSagKA8d7d0Z5EKYZrF3rJ
+Y+qYDCEIoiSOTUMbadcevFnrkFZh5MhJVAIN7OEEO1RNbI/H9pO6hh4eYdgfC2goEkiROfAb2atk
+dboeCgvU2bKcZIwM5X4QwDSymSm6gNsh18qrlDMwfgmvoI5bAgoSrhC6DRXgLA1BXAsP7YjVCk1B
+alkZYha6fLYsYCKJchwrUSdVr7JL0lF+qJQIdDDL0Tipcccd2xDb2TjBCtsKoN5pTsNzYsNXVwIK
+xehzxFLlstaUPsSw3LN4vaRkYGWQoBjUCrUxChtk6g1m6KzRclXSB6mHX5Sim9KqPvcWzU77JqSx
+wgMmojrOINEEEKg4aVnJ0z14qTTGXUaPZYJSRCEMRruXM/0q3MOBTSscyRLIvKMmF4l6TP0goGKe
+0zRVp6VCtFWuGeQycEMJxzE+ScffkHwQ3uAlmsaIFwx5EE/QRhR5C1L7FnOgtUceZyFUfUue/Bzs
+Z64akuNEo8TQGRZSemQVRGeQxmPJiXUqEzAwss2Y8sKJSLGnCXwNYm/GgBH9rZEkO3w+PLSKjhyi
+wnwPhetRM5Vd+pjwwX1S0e/FqA5caAScXlEG2v+fvXfbtew6rgTfDfAf8kWAbOCk5/2CeiKPytWu
+OoYLUkklo9EgqBQtu80UDRVVbv9974gYI2KuvU9SJJM2/FACbErBdeZe15hxGTFGUFysaKEJEhyj
+D5NdvOXgKyUPgk3RGrh7w9GWArVfPAGmK1khAWZbmx2GNJ27WM7bOk3yVTe/2s4YfBMJhERcNpcR
+Ez7z4Gz0+S6wfC7j+0xEzASpdI+htjWdY2EZP7cZrcwp6bUJp9rIDYeA0wWvUtnTL9BvF9xRvss2
+5DtniHsQdqpEMsxoRguIp7FpwSme4R2pdvaXpdrAW0XJOCU5YehNsh5VtMxAeNUowQtEdQyGBXiA
+osxEzgd/hbtF25qZ6V7lC1jZQXs03cH6mn0atGY7BTkzVsWyHCPTOttrI+jT0a46NGqoJeAYV0GF
+QZJQ6drhGUpcy/l+Hcx7Ai52Irv1Nn31IyWySOcpDCanhFbIkNtg2r2hg3wYl7XVfAUV+bPcqhKZ
+Mr1M46ChSti73MfjUyrORyBF/M5RlrHdiB1Brsyq7fJ4yjwwN7fQFh+Dgo1h3AwSC7nYbyuUjpd2
+zQNKbJ5Ds8oY70dm1eM5xDU0487xm5DNTWg8sDgnlMlQoNLWarNjdvJdXeE6nByqlQyNJW+CCokK
+zB75N7tMLJBd5PyAXTsyU9JQaJ9JW9yP1Hryc5xChb3SG2Zq+mrSnDjQwGGZ20udHVG70kGAkqpP
+PxBw0hy9NkMftRkc2bESDe/RCFqKZPO6y6bDMqFD6PpoySFA7ZuOZkZ/eHv+MjwBEhAJLnecPllA
+7Zk5zKCe5vLaVD0vAuVj2SeDzUamwAp7z0T+qEoVN0GXJUhII7URe4KvGHkmzzVWFF63gcjxLCPn
+HOkArcQmhhhAbBHoN2fQAlRYNmGJEZ95F0pjAVu1LvB0OjE2rIKpnhXVpHUX9pehk62Kk6bxkip4
+sPB9ROVW5k1STMLstz5ckAPvQSR2dRCaQjcWVlV5M1+gGMmqTiI43VXBAEjUMgV9BEXQbi0zvwvY
+Co4oU43U82wxdzHITnJAEQWPsxiC62DFkyF3CrU/Z6DAJrVye8AdJvuuMmCyEg8l+KjHNM+keKFs
+iuMcYIs5LFcz8460hLQzc1mAkHXwZR/AGzTV5fnMyZGJjlZEZV1er8HyfBl4uczQJY4kpela0Sq2
+qe2fCciEdp2ICgj9RCl2kBd7BVIpBnlYuNP+fPbpngO4gjH45AmfDL9kdpRYMxOhv0nskTLI+QIb
+0AahHwLIZXj4WR39L8ZMsNiIV3EQ0ah77fBfWxwHLwCCqLECDzRDZIAShPJ0MYo0B+sXIpoM8gI5
+EICLecEz9ghh+elKP9FSUU3P/B4kxsRH7VM0+FjGOi5gMVNh11qOs6xIChI1H132ng==
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ K/gWioMlqhHDeoN5+Dl0aL9tHzg45J026/z1bENpj9w3D0iziRGzSjVQKMXBYtWyzOjSYxqkGvgZ
+d6H7LWuAAnnUs8CKEHcBSIESyKmisAV7OsvVGwGWKBfeI4G34UEy9dRxuYU1lRvCjOivLWAv/SYS
+3cIfSnCrJTBPxV9lOXunGZV+DtxqYVFFG6b+blWf2yewplhG8uwLOMmcu+DMGfPiyaXij1jkPJ9A
+Rl1Gz7YTZEAW3uqas9snLa3tdEAEMt19ReZNJUxzHqAZ1a2VXnmGKnTytnanZI0U1LBXHOQHyaVE
+0It0fICNfhPAgWPR1O4c01f6kM0KeBkHQgFFLJ3CXsQXcBfrDtVXOm+XDgrKDNXyYGEnrQAjwKV1
+8oBoQYpb2LG7ru14meYTYCHwscB2ZkZKp7STNOSAF8gu5118sqE0JWY1G553M97RZwcX+Mmiuqj8
+HbwH27kO0PaQKnTe589D0EV9M/4cBCHTX0PVHJlo50zHJZt0NUFPibIOoVsdbLPBXyD/Wu6AXwHH
+NAH+MCOxfisUL5YXCJclKX4O7AQeZAPLd/3ppV8HLCjDgb9JmnV7/TmR7gCT58tzFwUhNMI1D/7t
+oEE4ONPXJJRbBVM28RGZFe3m5JRQBlo+tal6u5TlyWFDxXEbWZqDAlgQB0ueGYMocrdBVAGZo9NJ
+ny2xSmYYTQnkzqkKDvCasXcOFpcRKmWdlJniLMgz250DIlk504wkBklW4HjHFfiF7dBj6d712fbW
+Xo3L+ANihcWSLtmnlSueqlwJEYOeQwJk9fYW5LgK6DgoufmghCho1KdTo6/unZx5wMMXpMLslQk9
+FUh+y6PneHUYh8FxYoHCTIR8Pwpz3GiZEEmq/Nh0lOvo5vZDt6zyPjZHd7e4CMisOJDcy1JQkJF7
+1xybwGJzD/hO855rN8BbrODEOA7DAP+sKq8VnsAB5IxYWRLixeYmRwG1X8XYHs03DWTpvgPNS7C6
+XRl719XHcruTMUuC6jtLi61Nk3fuLI6WChQj5mvMGLBsLYQ+cwUM0nFI8MnQDZl9ckLqKEpjOLCQ
+lygmNLlsmnDw2MxHtviGl2MYvRfyk5rOG7fnRoXt4n2nzlqG9vq9mVzGKVbjfWPug36yLYhxsgsM
+NivMOa6gdW/5NlZCYybB4VaZcNxupE/PbOlXdHhaMO4kLzo0a0/A6PmGYuADFADG3+o4fKnQAs1a
+XcFFGiDN57BHtDC3gyOLddTMyC8EiuQwdkI5D1W8uX0ms5p4B4z4SCvrmwext7zX1ecJBYQA6Y1m
+A0MwZvbODxoFBkQqixQL8B2VvMrr3Ns7wdRWnj6YCnhv4BKwGVcfWJuLNVpNeZzvgK6qmtKRl9rP
+hCWT7yCyGypgi5Hj/+1oYUaYEYScStCf8WsUk3PNmYWyarT0h0f3w1VNmkfxTD4VLkHBzIOsVlZo
+XIEzlTLQilipxHTtdIX1chk0nz7SU1yxa84jn/SJ2enuo1660ZPN1AWBPxrxQtNZzelk19WIGGKB
+xGKO8z7EaEizooMZIVC8LnSD00XDtHAzCSHAfJtG3YXNmHD6bR/IBnq27swv0iMzcqXVifrWWV8O
+WylGJXAF1k/ReGY6PYGDb10zph8g22OASXkbiG5CliP1cLzkwjbhDSkqaAqsJVrSirRgaMeHVg+0
+Auf4FWzABY52anUvNF3ATur0ifLvzhBT3dvMt0EzNznlp9Epvp1Chsjlc5k6icsBpX6oR2ePdbbL
+cmj7ejHCBJ42+raa7cSAbjqggcm78pT9diZy6xUWp3PYZ0vZAcwzevCMgKZrNk4f1tSJjXmAM9CQ
+0TfEnxmn6bq8lRnGyVgnEC6Nk9oSINGFKdVL5sewOaQcDvukw1EtddLGDDYs6QOLh5xyoCUjF0yy
+mF3gmEq+8mM2US37RKxK47K/eeYKKE0qVQw4jCodELXR7GaB/Efn+OMcCjNmFYaebNviQSoMb9DI
+mDOZyPKzv0u2Q6lOfSIUAm+4LBuwi+nSyT3kPmZmdmkYOJJ4sCEdsbvo71gZU/BY48QGLA74E4Cs
+WtuUVyENSgaCWlv1+Zh3ty6kyg45xwEyIJVHcjIE6qBIIBpkNombrDgXcmVsyP1Jt408gGP7E2tG
+7vdMaAE4amZ1QbEgM6jez5ZGvRV0ZjG+accmgKeh+LyXtDrxJmTHRQqIAZ3BW+jVHB4h9kmZitT9
+YKCC5AT3CKiO1gpV4qjGTaA4ynTayOlcYdK47f4igI1besyHY5UQeaDb3yg6VTmiKC1tcgI5N/Xo
+F7TQMEkja9dj2kK4HAwB0H1Ab3rdYfQLhcViZ0DsaTq700SvvoQQ+Wgc+j+E3TRwxd+nAN+iQDyC
+GEmxgYYAuFTWtFlkg/jNalFPViZBU10Yd8QkAwe4s91E4b00irRGQAw9+UCjdWFGaHxJx8QpEtKF
+EpikDsOe9JM29rATCcEASLa2U6Ap+cI8yPV5F8fb7X3IIGrAdUXLVW3pmLRGLfnCELASbSpjRxmE
+jf5/9okTVaQwKNZw3lg9uFK9B89GjRmwFVVy8ZY4CDeGw+nVaMGLcvFkNyZwZfR5CjSg8DxUotOP
+Ne696cOqBm0g9EYrZ7FCw8frEjGF+mHTG7QnMiEfo7na/LZGn2yhYxGHgPdWlWMK7y09czFNx+ip
+VyILhgttkMyk2cQiWuq66852R/+AsVChKHCVG8CqJUBbiaPiFHeCEqAvAHkU8eLbWQfwfs7BcoAa
+rZ0me8AxtJ85baGULpw1N2U2palpbEdjWF2Aa8U3+e2TYfLFA8G4NxE1M4pue1PTQ6kM9oGS4YTc
+IciwmfamoCpeHnQn64CiVO6JWfLJjk0QptjSoErCIMxvnDTrkB2Qnx8utkQkb4rW8nIkf7JqrV8A
+EevJIFTmD7azOZDwSKhdM+CDO1h1lBBzWvxDUjbxJ5OdDe2mmJE9zWq8/IEqQHerBdf8OICZI7lY
+x7WZb5CAN5Liv8mEAeQrAkAyCSR9yTq872nHY1aJLS+jOjmFF3upnacIsHoU9KB+rUMdlYUvCFys
+4kmYBJBI3suJONROZ2Z7k0yjmWBbqb50UjaiE1AOZI+WNiYbZS351hVtW85WWEhmNv0hLx90b5+B
+BEcJG3my7D6J0UnuxnJudyVB9K4co1Ef3dNMNjFrJSthO3tdcwBCrZO6hfqYfPZS3YTobnNmrH5y
+Qk0f91JowGK61DkG3khxVEguOa1k79lW916/4+ar15abwZAQp795qF70Y85gktlrmBiN5QlErk4H
+6INrzvN2Iw5QPpTmQq3AqG4Sp6jRFphQRosFFoG2nic4VGcqEbITPjZ6Z80inz1vT4imOeAW4ZrG
+7Zn3laUWSQx7pLyohGk4Df2/6fDd7Fwb00eHhEroIIz0yWyNlzbvgp3WMFpDe+UxmjKaPTe2ecxE
+3evdWbWQKMdKgbLnIosXvOn2cKL5PpYpz2liRwDolhAQIrZWmDPbhagjA/7sYM0o7QsqzvUJQAsm
+zjK+ZBURLQCtUaNZYkCUY5LTimtvvWNzUpY/bzqHN6I4sHQmvabkU1JnnWg78EDbUnDCeW6flkVp
+Lis556vu9N23aMT85x9bI+aNiLuIHIz8Py0p/5Ndv3NXKIi9EefVvLyA6XTcQ0h+7sCaVOxuUo+U
+EuAznwzwVJo8jBBJxN+zRKQYDTyXw0cLOYBBUJV2L3G0nwR522a8nrS9TSSgIrB9EHE760GOud5F
+Yl5VPHYadI55FnvTn9nC5DRAMc5gGBc3leSNUbYbs3UxfAEWhFPo0Jvq1DSSf7xYNnwjpYlQIFZx
+iA5n5ozp47gvzgLvflMr5v3YagHJ0JvrnOu42GhsNlMtsvOs+WDZxhmsQzagehs12R02Y4ROivbx
+FcBwmhyXJ5vuYOQ0N+dkQUwnn2GUJZcXXZQd29srsdVDJ04nG1FhzjY57z0T8sxmL2hrJMbi0wDB
+jg6pFrww2sn2FZD1yM+RQ3hz/8XQrtmIISxnG1YVzDkC0yiHPZ1ds8ZeOxxAUu3Co0CMEbEaOu7t
+QFqQEkO2+xozOM48IZuw42XrZAGNVePilRDJP1BczcZwGkUEdHOysSCYkSO4yQoG2H4Kv1Idk/f9
+lrvosl4KDnbKSJfUnhz1V4nzY8NGBV/r6NnJicEOhx62GQ8WuKPGTG05pYxbjVVAr3/dQlfW9UBI
+KCe4YoFCGMesPnAjVSbL0wQZX6LyTLy+EuRF2GVAlNG4NUjChcQ+0G8rpHbbWYfQjc5g+M2fw4Lu
+6WiuHKsB5z6PI6yCJUSxk8YpHwyOyq1jW0P3EtEOWTSfh5XBCRYBsscXgzw9Gjd4dUTH1D1wsJbp
+zAybTPmrgA6wFScIQ09hXqh5hZvecHnavFlEHCNwmEEA8LC9vWPmcwvMxH29gSrtPzEiIS3rMnm4
+975LWvwm3zJGNJV4f3Drg361oD9dQLrUfeyHBuPTXtpwkCW3SJe5qp7by8Uz2t4+c6kM7J1PDUoz
+2l7LNFIpexpZLFaQ9JdhKYkcNlt1xmPLHRKogGRtVHjB5fWUHVopwNXOHSQZPpytE+yxF8p1d1Tl
+CW4UsEniLWDAv5zrTcN5nyZ3ZRiZi8OssGml+7Bc4QKYQ5zzwjozyOYpCwMcrCibjhuzCWoSVZGF
+iygxYRUsG+S2fwKUZPn+TaKP7qFO0LPLRotJN0kXK2kyULPUF3fTCBCctiD6sSWTShdipfatQ2Xe
+EAJ0AMBfJesvOwiiFZYoHEpSbLge5ZBOpwKZaWV4dxxHdlCsvVJwVmjTZSpSa/bN4fAz/08ebBQX
+5ZreAVglWN+Xs+QLciMd+ylFdItBrrBnZAfFktp2sCIuWWaN9n3MbOeTSZetPonWfEc+Gzn1GGef
+DIWp23TsT8vjEtki0Z1Zpx8Xe1t4y0HtqL9WOaXpHSJnCVQv2I4VcMWyZ/skOPA081IXYP7VToK5
+6bj4eQAxspO4Nnd1OiyLVbW97F2uiZ0+xfh+cm7ZacDQJ/QrGkrtLXpMw96Am1l1cVywxCLUUQPi
+FttZVQiVfw4oI8JsNsxdDcjHIZQ1djYxHhC5RcDUQMQFx+pziFCIEaXAycw4jXM7RCVxUKJCh7y8
+XwKqZ90NDUgs/R0BF/huiAQo8VW0CUC0szqQKCINZM0Z7ZwGyd9iDCYPH6hOqQ1iM5w2fvPq7ua7
+oSiG3j5S+W+5Te6GkzMH8qpJldeHgLipDh+s1QEavM4+D9J4yROyRM/MLhHOTmAIbOdjFX85n4Wy
+8vGT0m6i74ek011GxcdNkv3GNYlAB3pavoLigdyOkbthFHDYI63gqHFnJcoYMblc2Q4w1iYQQkJ5
+4q72sUKFRoIyU3aEs9oc8BUY5oaYgFKj8aZ3bomubSJOKsaAxG7qk+rRBndg9J/0YNdlwxScLHsJ
+B2MufMxFWK3V0eXlSV7NBTWJPmDXHSeJPRAqglWxT0fDDweMovsmxkCCKXCxINjJ4A==
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 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
+ ]]>
+ <![CDATA[
+ 3gRjEBS5TUPdcWtgG03QXRVahxtuYtrPavR0/3RsO9Uk0sHRLW6HiarbRiASAOyYiJWJtuuD9nj2
+Wx3SUNF3HSj38DaEaOjF3M2D+2k1kE+dElpZXzTu4y2B+XbuYmMEEeqEhYKxrmDDOzwPGrZOhUiX
+jM+DVglMLnrabDgPMKcEQI0teB60SlvXpK1DBMoHojTCVvOJ0ICRYfdgt/FElPFhq+FElGnAxvKJ
+0HA62kj7CAdC40U1ltAlDKnThvKBaPOBqLoFOBBlnEDnYX3R93oelimwDTBRtSMFXj45j8eLUbeT
+/lydAYCBnuA0FbCeYVcO4I/j4REIrlu/twWKquvapo1+98N6IdSUB2Ei7jprclW6Noy0VVeB0fPh
+EQnqHwlIed5WmU9y3tpfad4P5EyaJsmJatebfOUz+axy90YFBvoVPno+fDd+dTY8noC25N18+AHc
+I6eY8OI0PQKNLuSeHXfm72c/Qwu8lF949Ojgh8O9r/4/BHxyhg==
+ ]]>
+ </i:pgf>
+</svg>
diff --git a/doc/javadocs/allclasses-frame.html b/doc/javadocs/allclasses-frame.html
new file mode 100644
index 0000000..cc1e3b0
--- /dev/null
+++ b/doc/javadocs/allclasses-frame.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>All Classes</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<h1 class="bar">All Classes</h1>
+<div class="indexContainer">
+<ul>
+<li><a href="mpi/Cartcomm.html" title="class in mpi" target="classFrame">Cartcomm</a></li>
+<li><a href="mpi/CartParms.html" title="class in mpi" target="classFrame">CartParms</a></li>
+<li><a href="mpi/Comm.html" title="class in mpi" target="classFrame">Comm</a></li>
+<li><a href="mpi/Datatype.html" title="class in mpi" target="classFrame">Datatype</a></li>
+<li><a href="mpi/Errhandler.html" title="class in mpi" target="classFrame">Errhandler</a></li>
+<li><a href="mpi/Graphcomm.html" title="class in mpi" target="classFrame">Graphcomm</a></li>
+<li><a href="mpi/GraphParms.html" title="class in mpi" target="classFrame">GraphParms</a></li>
+<li><a href="mpi/Group.html" title="class in mpi" target="classFrame">Group</a></li>
+<li><a href="mpi/Intercomm.html" title="class in mpi" target="classFrame">Intercomm</a></li>
+<li><a href="mpi/Intracomm.html" title="class in mpi" target="classFrame">Intracomm</a></li>
+<li><a href="mpi/MPI.html" title="class in mpi" target="classFrame">MPI</a></li>
+<li><a href="mpi/MPIException.html" title="class in mpi" target="classFrame">MPIException</a></li>
+<li><a href="mpi/Op.html" title="class in mpi" target="classFrame">Op</a></li>
+<li><a href="mpi/Prequest.html" title="class in mpi" target="classFrame">Prequest</a></li>
+<li><a href="mpi/Request.html" title="class in mpi" target="classFrame">Request</a></li>
+<li><a href="mpi/ShiftParms.html" title="class in mpi" target="classFrame">ShiftParms</a></li>
+<li><a href="mpi/Status.html" title="class in mpi" target="classFrame">Status</a></li>
+<li><a href="mpi/User_function.html" title="class in mpi" target="classFrame">User_function</a></li>
+</ul>
+</div>
+</body>
+</html>
diff --git a/doc/javadocs/allclasses-noframe.html b/doc/javadocs/allclasses-noframe.html
new file mode 100644
index 0000000..7cf0a58
--- /dev/null
+++ b/doc/javadocs/allclasses-noframe.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>All Classes</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<h1 class="bar">All Classes</h1>
+<div class="indexContainer">
+<ul>
+<li><a href="mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></li>
+<li><a href="mpi/CartParms.html" title="class in mpi">CartParms</a></li>
+<li><a href="mpi/Comm.html" title="class in mpi">Comm</a></li>
+<li><a href="mpi/Datatype.html" title="class in mpi">Datatype</a></li>
+<li><a href="mpi/Errhandler.html" title="class in mpi">Errhandler</a></li>
+<li><a href="mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></li>
+<li><a href="mpi/GraphParms.html" title="class in mpi">GraphParms</a></li>
+<li><a href="mpi/Group.html" title="class in mpi">Group</a></li>
+<li><a href="mpi/Intercomm.html" title="class in mpi">Intercomm</a></li>
+<li><a href="mpi/Intracomm.html" title="class in mpi">Intracomm</a></li>
+<li><a href="mpi/MPI.html" title="class in mpi">MPI</a></li>
+<li><a href="mpi/MPIException.html" title="class in mpi">MPIException</a></li>
+<li><a href="mpi/Op.html" title="class in mpi">Op</a></li>
+<li><a href="mpi/Prequest.html" title="class in mpi">Prequest</a></li>
+<li><a href="mpi/Request.html" title="class in mpi">Request</a></li>
+<li><a href="mpi/ShiftParms.html" title="class in mpi">ShiftParms</a></li>
+<li><a href="mpi/Status.html" title="class in mpi">Status</a></li>
+<li><a href="mpi/User_function.html" title="class in mpi">User_function</a></li>
+</ul>
+</div>
+</body>
+</html>
diff --git a/doc/javadocs/constant-values.html b/doc/javadocs/constant-values.html
new file mode 100644
index 0000000..734cbe7
--- /dev/null
+++ b/doc/javadocs/constant-values.html
@@ -0,0 +1,187 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>Constant Field Values</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Constant Field Values";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
+<li><a href="constant-values.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 title="Constant Field Values" class="title">Constant Field Values</h1>
+<h2 title="Contents">Contents</h2>
+<ul>
+<li><a href="#mpi">mpi.*</a></li>
+</ul>
+</div>
+<div class="constantValuesContainer"><a name="mpi">
+<!-- -->
+</a>
+<h2 title="mpi">mpi.*</h2>
+<ul class="blockList">
+<li class="blockList">
+<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
+<caption><span>mpi.<a href="mpi/Group.html" title="class in mpi">Group</a></span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th scope="col">Constant Field</th>
+<th class="colLast" scope="col">Value</th>
+</tr>
+<tbody>
+<tr class="altColor">
+<td class="colFirst"><a name="mpi.Group.EMPTY">
+<!-- -->
+</a><code>public static final int</code></td>
+<td><code><a href="mpi/Group.html#EMPTY">EMPTY</a></code></td>
+<td class="colLast"><code>3</code></td>
+</tr>
+</tbody>
+</table>
+</li>
+<li class="blockList">
+<table border="0" cellpadding="3" cellspacing="0" summary="Constant Field Values table, listing constant fields, and values">
+<caption><span>mpi.<a href="mpi/MPI.html" title="class in mpi">MPI</a></span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th scope="col">Constant Field</th>
+<th class="colLast" scope="col">Value</th>
+</tr>
+<tbody>
+<tr class="altColor">
+<td class="colFirst"><a name="mpi.MPI.CONGRUENT">
+<!-- -->
+</a><code>public static final int</code></td>
+<td><code><a href="mpi/MPI.html#CONGRUENT">CONGRUENT</a></code></td>
+<td class="colLast"><code>3</code></td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a name="mpi.MPI.DEBUG">
+<!-- -->
+</a><code>public static final boolean</code></td>
+<td><code><a href="mpi/MPI.html#DEBUG">DEBUG</a></code></td>
+<td class="colLast"><code>false</code></td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a name="mpi.MPI.IDENT">
+<!-- -->
+</a><code>public static final int</code></td>
+<td><code><a href="mpi/MPI.html#IDENT">IDENT</a></code></td>
+<td class="colLast"><code>0</code></td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a name="mpi.MPI.SIMILAR">
+<!-- -->
+</a><code>public static final int</code></td>
+<td><code><a href="mpi/MPI.html#SIMILAR">SIMILAR</a></code></td>
+<td class="colLast"><code>1</code></td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a name="mpi.MPI.UNEQUAL">
+<!-- -->
+</a><code>public static final int</code></td>
+<td><code><a href="mpi/MPI.html#UNEQUAL">UNEQUAL</a></code></td>
+<td class="colLast"><code>2</code></td>
+</tr>
+</tbody>
+</table>
+</li>
+</ul>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?constant-values.html" target="_top">Frames</a></li>
+<li><a href="constant-values.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/deprecated-list.html b/doc/javadocs/deprecated-list.html
new file mode 100644
index 0000000..aef60e5
--- /dev/null
+++ b/doc/javadocs/deprecated-list.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>Deprecated List</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Deprecated List";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li class="navBarCell1Rev">Deprecated</li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
+<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 title="Deprecated API" class="title">Deprecated API</h1>
+<h2 title="Contents">Contents</h2>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li class="navBarCell1Rev">Deprecated</li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?deprecated-list.html" target="_top">Frames</a></li>
+<li><a href="deprecated-list.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/help-doc.html b/doc/javadocs/help-doc.html
new file mode 100644
index 0000000..7ea41a1
--- /dev/null
+++ b/doc/javadocs/help-doc.html
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>API Help</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="API Help";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li class="navBarCell1Rev">Help</li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
+<li><a href="help-doc.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 class="title">How This API Document Is Organized</h1>
+<div class="subTitle">This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.</div>
+</div>
+<div class="contentContainer">
+<ul class="blockList">
+<li class="blockList">
+<h2>Package</h2>
+<p>Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:</p>
+<ul>
+<li>Interfaces (italic)</li>
+<li>Classes</li>
+<li>Enums</li>
+<li>Exceptions</li>
+<li>Errors</li>
+<li>Annotation Types</li>
+</ul>
+</li>
+<li class="blockList">
+<h2>Class/Interface</h2>
+<p>Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:</p>
+<ul>
+<li>Class inheritance diagram</li>
+<li>Direct Subclasses</li>
+<li>All Known Subinterfaces</li>
+<li>All Known Implementing Classes</li>
+<li>Class/interface declaration</li>
+<li>Class/interface description</li>
+</ul>
+<ul>
+<li>Nested Class Summary</li>
+<li>Field Summary</li>
+<li>Constructor Summary</li>
+<li>Method Summary</li>
+</ul>
+<ul>
+<li>Field Detail</li>
+<li>Constructor Detail</li>
+<li>Method Detail</li>
+</ul>
+<p>Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</p>
+</li>
+<li class="blockList">
+<h2>Annotation Type</h2>
+<p>Each annotation type has its own separate page with the following sections:</p>
+<ul>
+<li>Annotation Type declaration</li>
+<li>Annotation Type description</li>
+<li>Required Element Summary</li>
+<li>Optional Element Summary</li>
+<li>Element Detail</li>
+</ul>
+</li>
+<li class="blockList">
+<h2>Enum</h2>
+<p>Each enum has its own separate page with the following sections:</p>
+<ul>
+<li>Enum declaration</li>
+<li>Enum description</li>
+<li>Enum Constant Summary</li>
+<li>Enum Constant Detail</li>
+</ul>
+</li>
+<li class="blockList">
+<h2>Tree (Class Hierarchy)</h2>
+<p>There is a <a href="overview-tree.html">Class Hierarchy</a> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.</p>
+<ul>
+<li>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.</li>
+<li>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</li>
+</ul>
+</li>
+<li class="blockList">
+<h2>Deprecated API</h2>
+<p>The <a href="deprecated-list.html">Deprecated API</a> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</p>
+</li>
+<li class="blockList">
+<h2>Index</h2>
+<p>The <a href="index-all.html">Index</a> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</p>
+</li>
+<li class="blockList">
+<h2>Prev/Next</h2>
+<p>These links take you to the next or previous class, interface, package, or related page.</p>
+</li>
+<li class="blockList">
+<h2>Frames/No Frames</h2>
+<p>These links show and hide the HTML frames. All pages are available with or without frames.</p>
+</li>
+<li class="blockList">
+<h2>All Classes</h2>
+<p>The <a href="allclasses-noframe.html">All Classes</a> link shows all classes and interfaces except non-static nested types.</p>
+</li>
+<li class="blockList">
+<h2>Serialized Form</h2>
+<p>Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.</p>
+</li>
+<li class="blockList">
+<h2>Constant Field Values</h2>
+<p>The <a href="constant-values.html">Constant Field Values</a> page lists the static final fields and their values.</p>
+</li>
+</ul>
+<em>This help file applies to API documentation generated using the standard doclet.</em></div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="overview-tree.html">Tree</a></li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li class="navBarCell1Rev">Help</li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?help-doc.html" target="_top">Frames</a></li>
+<li><a href="help-doc.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/index-all.html b/doc/javadocs/index-all.html
new file mode 100644
index 0000000..14131ad
--- /dev/null
+++ b/doc/javadocs/index-all.html
@@ -0,0 +1,1039 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>Index</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="./stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Index";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="./mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="./overview-tree.html">Tree</a></li>
+<li><a href="./deprecated-list.html">Deprecated</a></li>
+<li class="navBarCell1Rev">Index</li>
+<li><a href="./help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="./index.html?index-all.html" target="_top">Frames</a></li>
+<li><a href="index-all.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="./allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="contentContainer"><a href="#_A_">A</a> <a href="#_B_">B</a> <a href="#_C_">C</a> <a href="#_D_">D</a> <a href="#_E_">E</a> <a href="#_F_">F</a> <a href="#_G_">G</a> <a href="#_H_">H</a> <a href="#_I_">I</a> <a href="#_L_">L</a> <a href="#_M_">M</a> <a href="#_N_">N</a> <a href="#_O_">O</a> <a href="#_P_">P</a> <a href="#_Q_">Q</a> <a href="#_R_">R</a> <a href="#_S_">S</a> <a href="#_T_">T</a> [...]
+<!-- -->
+</a>
+<h2 class="title">A</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Comm.html#Abort(int)">Abort(int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Abort MPI.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Allgather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Allgather(Object, int, int, Datatype, Object, int, int, Datatype)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Similar to <tt>Gather</tt>, but all processes receive the result.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Allgatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Allgatherv(Object, int, int, Datatype, Object, int, int[], int[], Datatype)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Similar to <tt>Gatherv</tt>, but all processes receive the result.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Allreduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Allreduce(Object, int, Object, int, int, Datatype, Op)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ all process in the group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Alltoall(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Alltoall(Object, int, int, Datatype, Object, int, int, Datatype)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Extension of <tt>Allgather</tt> to the case where each process sends
+ distinct data to each of the receivers.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Alltoallv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Alltoallv(Object, int, int[], int[], Datatype, Object, int, int[], int[], Datatype)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ specified by <tt>sdispls</tt> and location to place data on receive side is
+ specified by <tt>rdispls</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#ANY_SOURCE">ANY_SOURCE</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#ANY_TAG">ANY_TAG</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Attr_delete(int)">Attr_delete(int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Retrieves attribute value by key.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Attr_get(int)">Attr_get(int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Retrieves attribute value by key.</div>
+</dd>
+</dl>
+<a name="_B_">
+<!-- -->
+</a>
+<h2 class="title">B</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/MPI.html#BAND">BAND</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Barrier()">Barrier()</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#baseType">baseType</a></span> - Variable in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Bcast(java.lang.Object, int, int, mpi.Datatype, int)">Bcast(Object, int, int, Datatype, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#BOOLEAN">BOOLEAN</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#BOR">BOR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Send in buffered mode.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Creates a persistent communication request for a buffered mode send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#BSEND_OVERHEAD">BSEND_OVERHEAD</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Overhead incurred by buffered send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Buffer_attach(java.nio.ByteBuffer)">Buffer_attach(ByteBuffer)</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Provides to MPI a buffer in user's memory to be used for buffering outgoing
+ messages.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Buffer_detach()">Buffer_detach()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Detach the buffer currently associated with MPI.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#BXOR">BXOR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#BYTE">BYTE</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_C_">
+<!-- -->
+</a>
+<h2 class="title">C</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/User_function.html#Call(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype)">Call(Object, int, Object, int, int, Datatype)</a></span> - Method in class mpi.<a href="./mpi/User_function.html" title="class in mpi">User_function</a></dt>
+<dd>
+<div class="block">User-defined function for a new <tt>Op</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Cancel()">Cancel()</a></span> - Method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Mark a pending nonblocking communication for cancellation.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#CART">CART</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Cartcomm.html" title="class in mpi"><span class="strong">Cartcomm</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/CartParms.html" title="class in mpi"><span class="strong">CartParms</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#CHAR">CHAR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#clone()">clone()</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#clone()">clone()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Duplicate this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Graphcomm.html#clone()">clone()</a></span> - Method in class mpi.<a href="./mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Intercomm.html#clone()">clone()</a></span> - Method in class mpi.<a href="./mpi/Intercomm.html" title="class in mpi">Intercomm</a></dt>
+<dd>
+<div class="block">where would peer communicator come from ...and also localleader,
+ and remoteleader ....</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#clone()">clone()</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ ....</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Group.html#code">code</a></span> - Variable in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Comm.html" title="class in mpi"><span class="strong">Comm</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#COMM_NULL">COMM_NULL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#COMM_SELF">COMM_SELF</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#COMM_WORLD">COMM_WORLD</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Commit()">Commit()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Commit a derived datatype.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Compare(mpi.Comm, mpi.Comm)">Compare(Comm, Comm)</a></span> - Static method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Compare two communicators.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Compare(mpi.Group, mpi.Group)">Compare(Group, Group)</a></span> - Static method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Compare two groups.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Compare(mpi.Comm, mpi.Comm)">Compare(Comm, Comm)</a></span> - Static method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Compare two communicators.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#CONGRUENT">CONGRUENT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Contiguous(int, mpi.Datatype)">Contiguous(int, Datatype)</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Construct new datatype representing replication of old datatype into
+ contiguous locations.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Coords(int)">Coords(int)</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Translate process rank to logical process coordinates.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/CartParms.html#coords">coords</a></span> - Variable in class mpi.<a href="./mpi/CartParms.html" title="class in mpi">CartParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Create(mpi.Group)">Create(Group)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Create a new communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Create_cart(int[], boolean[], boolean)">Create_cart(int[], boolean[], boolean)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Create a Cartesian topology communicator whose group is a subset of the
+ group of this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Create_graph(int[], int[], boolean)">Create_graph(int[], int[], boolean)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Create a graph topology communicator whose group is a subset of the group
+ of this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Create_intercomm(mpi.Comm, int, int, int)">Create_intercomm(Comm, int, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Create an inter-communicator.</div>
+</dd>
+</dl>
+<a name="_D_">
+<!-- -->
+</a>
+<h2 class="title">D</h2>
+<dl>
+<dt><a href="./mpi/Datatype.html" title="class in mpi"><span class="strong">Datatype</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Datatype()">Datatype()</a></span> - Constructor for class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#DEBUG">DEBUG</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Difference(mpi.Group, mpi.Group)">Difference(Group, Group)</a></span> - Static method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Result contains all elements of the first group that are not in the second
+ group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/CartParms.html#dims">dims</a></span> - Variable in class mpi.<a href="./mpi/CartParms.html" title="class in mpi">CartParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Dims_create(int, int[])">Dims_create(int, int[])</a></span> - Static method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Select a balanced distribution of processes per coordinate direction.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#DOUBLE">DOUBLE</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#DOUBLE2">DOUBLE2</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_E_">
+<!-- -->
+</a>
+<h2 class="title">E</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/GraphParms.html#edges">edges</a></span> - Variable in class mpi.<a href="./mpi/GraphParms.html" title="class in mpi">GraphParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#EMPTY">EMPTY</a></span> - Static variable in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#EMPTY_STATUS">EMPTY_STATUS</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Errhandler.html" title="class in mpi"><span class="strong">Errhandler</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Errorhandler_get()">Errorhandler_get()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Gets the error handler <font color="RED"> Not Implemented in the current
+ release </font></div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Errorhandler_set(mpi.Errhandler)">Errorhandler_set(Errhandler)</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Set Error Handler <font color="RED"> Not Implemented in the current release
+ </font></div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#ERRORS_ARE_FATAL">ERRORS_ARE_FATAL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#ERRORS_RETURN">ERRORS_RETURN</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Excl(int[])">Excl(int[])</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Create a subset group excluding specified processes.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Extent()">Extent()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Returns the extent of a datatype - the difference between upper and lower
+ bound.</div>
+</dd>
+</dl>
+<a name="_F_">
+<!-- -->
+</a>
+<h2 class="title">F</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Datatype.html#finalize()">finalize()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#finalize()">finalize()</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Destructor.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Finalize()">Finalize()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Finalize MPI.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Op.html#finalize()">finalize()</a></span> - Method in class mpi.<a href="./mpi/Op.html" title="class in mpi">Op</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Request.html#finalize()">finalize()</a></span> - Method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#FLOAT">FLOAT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#FLOAT2">FLOAT2</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Free()">Free()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Destroy this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#free()">free()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#free()">free()</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">This method frees this group object.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Op.html#free()">free()</a></span> - Method in class mpi.<a href="./mpi/Op.html" title="class in mpi">Op</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Status.html#free()">free()</a></span> - Method in class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd> </dd>
+</dl>
+<a name="_G_">
+<!-- -->
+</a>
+<h2 class="title">G</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Gather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Gather(Object, int, int, Datatype, Object, int, int, Datatype, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Each process sends the contents of its send buffer to the root process.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Gatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype, int)">Gatherv(Object, int, int, Datatype, Object, int, int[], int[], Datatype, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ from each process.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Get()">Get()</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Returns Cartesian topology information.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Graphcomm.html#Get()">Get()</a></span> - Method in class mpi.<a href="./mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dt>
+<dd>
+<div class="block">Returns graph topology information.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Status.html#Get_count(mpi.Datatype)">Get_count(Datatype)</a></span> - Method in class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd>
+<div class="block">Get the number of received entries.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Status.html#Get_elements(mpi.Datatype)">Get_elements(Datatype)</a></span> - Method in class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd>
+<div class="block">Retrieve number of basic elements from status.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Get_processor_name()">Get_processor_name()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Returns the name of the processor on which it is called.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#getByteSize()">getByteSize()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#getType()">getType()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#GRAPH">GRAPH</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Graphcomm.html" title="class in mpi"><span class="strong">Graphcomm</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/GraphParms.html" title="class in mpi"><span class="strong">GraphParms</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/GraphParms.html#GraphParms()">GraphParms()</a></span> - Constructor for class mpi.<a href="./mpi/GraphParms.html" title="class in mpi">GraphParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#group">group</a></span> - Variable in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Group()">Group()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Return group associated with a communicator.</div>
+</dd>
+<dt><a href="./mpi/Group.html" title="class in mpi"><span class="strong">Group</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Group(mpjdev.Group)">Group(mpjdev.Group)</a></span> - Constructor for class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#GROUP_EMPTY">GROUP_EMPTY</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#GROUP_NULL">GROUP_NULL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_H_">
+<!-- -->
+</a>
+<h2 class="title">H</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Hindexed(int[], int[], mpi.Datatype)">Hindexed(int[], int[], Datatype)</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Identical to <tt>indexed</tt> except that the displacements are expressed
+ directly in terms of the buffer index, rather than the units of the old
+ type.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#HOST">HOST</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Hvector(int, int, int, mpi.Datatype)">Hvector(int, int, int, Datatype)</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Identical to <tt>vector</tt> except that the stride is expressed directly
+ in terms of the buffer index, rather than the units of the old type.</div>
+</dd>
+</dl>
+<a name="_I_">
+<!-- -->
+</a>
+<h2 class="title">I</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Comm.html#Ibsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Ibsend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Start a buffered mode, nonblocking send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#ibsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">ibsend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#IDENT">IDENT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Incl(int[])">Incl(int[])</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Create a subset group including specified processes.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/GraphParms.html#index">index</a></span> - Variable in class mpi.<a href="./mpi/GraphParms.html" title="class in mpi">GraphParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Indexed(int[], int[], mpi.Datatype)">Indexed(int[], int[], Datatype)</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Construct new datatype representing replication of old datatype into a
+ sequence of blocks where each block can contain a different number of
+ copies and have a different displacement.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Init(java.lang.String[])">Init(String[])</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Initialize MPI.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Initialized()">Initialized()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Test if MPI has been initialized.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#initThread(int, int, java.lang.String[])">initThread(int, int, String[])</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Used to initialize MPI with certain level of threadedness ...</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#INT">INT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#INT2">INT2</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Intercomm.html" title="class in mpi"><span class="strong">Intercomm</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Intersection(mpi.Group, mpi.Group)">Intersection(Group, Group)</a></span> - Static method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Set intersection of two groups.</div>
+</dd>
+<dt><a href="./mpi/Intracomm.html" title="class in mpi"><span class="strong">Intracomm</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#IO">IO</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Iprobe(int, int)">Iprobe(int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Check if there is an incoming message matching the pattern specified.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Irecv(java.lang.Object, int, int, mpi.Datatype, int, int)">Irecv(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Start a nonblocking receive.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#irecv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">irecv(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Irsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Irsend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Start a ready mode, nonblocking send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#irsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">irsend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Is_null()">Is_null()</a></span> - Method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Test if request object is void.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Isend(java.lang.Object, int, int, mpi.Datatype, int, int)">Isend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Start a standard mode, nonblocking send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#isend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">isend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#isMainThread()">isMainThread()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Returns true if this thread initialized MPI</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Issend(java.lang.Object, int, int, mpi.Datatype, int, int)">Issend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Start a synchronous mode, nonblocking send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#issend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">issend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+</dl>
+<a name="_L_">
+<!-- -->
+</a>
+<h2 class="title">L</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/MPI.html#LAND">LAND</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Lb()">Lb()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Find the lower bound of a datatype - the least value in its displacement
+ sequence.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#LB">LB</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#LONG">LONG</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#LONG2">LONG2</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#LOR">LOR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#LXOR">LXOR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_M_">
+<!-- -->
+</a>
+<h2 class="title">M</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Map(int[], boolean[])">Map(int[], boolean[])</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Compute an optimal placement.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Graphcomm.html#Map(int[], int[])">Map(int[], int[])</a></span> - Method in class mpi.<a href="./mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dt>
+<dd>
+<div class="block">Compute an optimal placement.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#MAX">MAX</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#MAXLOC">MAXLOC</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Intercomm.html#Merge(boolean)">Merge(boolean)</a></span> - Method in class mpi.<a href="./mpi/Intercomm.html" title="class in mpi">Intercomm</a></dt>
+<dd>
+<div class="block">Create an inter-communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#MIN">MIN</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#MINLOC">MINLOC</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/package-summary.html">mpi</a> - package mpi</dt>
+<dd> </dd>
+<dt><a href="./mpi/MPI.html" title="class in mpi"><span class="strong">MPI</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#MPI()">MPI()</a></span> - Constructor for class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/MPIException.html" title="class in mpi"><span class="strong">MPIException</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPIException.html#MPIException()">MPIException()</a></span> - Constructor for class mpi.<a href="./mpi/MPIException.html" title="class in mpi">MPIException</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPIException.html#MPIException(java.lang.String)">MPIException(String)</a></span> - Constructor for class mpi.<a href="./mpi/MPIException.html" title="class in mpi">MPIException</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPIException.html#MPIException(java.lang.Throwable)">MPIException(Throwable)</a></span> - Constructor for class mpi.<a href="./mpi/MPIException.html" title="class in mpi">MPIException</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#mpjdevComm">mpjdevComm</a></span> - Variable in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#mpjdevGroup">mpjdevGroup</a></span> - Variable in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd> </dd>
+</dl>
+<a name="_N_">
+<!-- -->
+</a>
+<h2 class="title">N</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Graphcomm.html#Neighbours(int)">Neighbours(int)</a></span> - Method in class mpi.<a href="./mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dt>
+<dd>
+<div class="block">Provides adjacency information for general graph topology.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#NULL">NULL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#NUM_OF_PROCESSORS">NUM_OF_PROCESSORS</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_O_">
+<!-- -->
+</a>
+<h2 class="title">O</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/MPI.html#OBJECT">OBJECT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Op.html" title="class in mpi"><span class="strong">Op</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Op.html#Op(mpi.User_function, boolean)">Op(User_function, boolean)</a></span> - Constructor for class mpi.<a href="./mpi/Op.html" title="class in mpi">Op</a></dt>
+<dd>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Op.html#Op(mpi.User_function, boolean, int)">Op(User_function, boolean, int)</a></span> - Constructor for class mpi.<a href="./mpi/Op.html" title="class in mpi">Op</a></dt>
+<dd>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Op.html#opCode">opCode</a></span> - Variable in class mpi.<a href="./mpi/Op.html" title="class in mpi">Op</a></dt>
+<dd> </dd>
+</dl>
+<a name="_P_">
+<!-- -->
+</a>
+<h2 class="title">P</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Comm.html#Pack(java.lang.Object, int, int, mpi.Datatype, mpjbuf.Buffer, int)">Pack(Object, int, int, Datatype, mpjbuf.Buffer, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Packs message in send buffer <tt>inbuf</tt> into space specified in
+ <tt>outbuf</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Pack_size(int, mpi.Datatype)">Pack_size(int, Datatype)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Returns an upper bound on the increment of <tt>position</tt> effected by
+ <tt>pack</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#PACKED">PACKED</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/CartParms.html#periods">periods</a></span> - Variable in class mpi.<a href="./mpi/CartParms.html" title="class in mpi">CartParms</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Prequest.html" title="class in mpi"><span class="strong">Prequest</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Probe(int, int)">Probe(int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Wait until there is an incoming message matching the pattern specified.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#PROC_NULL">PROC_NULL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#PROD">PROD</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_Q_">
+<!-- -->
+</a>
+<h2 class="title">Q</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/MPI.html#queryThread()">queryThread()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Returns the level of thread support provided by the MPI library and the
+ underlying device selected</div>
+</dd>
+</dl>
+<a name="_R_">
+<!-- -->
+</a>
+<h2 class="title">R</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Group.html#Range_excl(int[][])">Range_excl(int[][])</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Create a subset group excluding processes specified by strided intervals of
+ ranks.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Range_incl(int[][])">Range_incl(int[][])</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Create a subset group including processes specified by strided intervals of
+ ranks.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Rank(int[])">Rank(int[])</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Translate logical process coordinates to process rank.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Rank()">Rank()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Rank of this process in group of this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Rank()">Rank()</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Rank of this process in group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/ShiftParms.html#rank_dest">rank_dest</a></span> - Variable in class mpi.<a href="./mpi/ShiftParms.html" title="class in mpi">ShiftParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/ShiftParms.html#rank_source">rank_source</a></span> - Variable in class mpi.<a href="./mpi/ShiftParms.html" title="class in mpi">ShiftParms</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Recv(java.lang.Object, int, int, mpi.Datatype, int, int)">Recv(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Blocking receive operation.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#recv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">recv(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Recv_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Recv_init(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Creates a persistent communication request for a receive operation.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#RECV_OVERHEAD">RECV_OVERHEAD</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Reduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op, int)">Reduce(Object, int, Object, int, int, Datatype, Op, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and return the combined value in the output buffer of the root
+ process.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Reduce_scatter(java.lang.Object, int, java.lang.Object, int, int[], mpi.Datatype, mpi.Op)">Reduce_scatter(Object, int, Object, int, int[], Datatype, Op)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and scatter the combined values over the output buffers of the
+ processes.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intercomm.html#Remote_group()">Remote_group()</a></span> - Method in class mpi.<a href="./mpi/Intercomm.html" title="class in mpi">Intercomm</a></dt>
+<dd>
+<div class="block">Return the remote group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intercomm.html#Remote_size()">Remote_size()</a></span> - Method in class mpi.<a href="./mpi/Intercomm.html" title="class in mpi">Intercomm</a></dt>
+<dd>
+<div class="block">Size of remote group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#req">req</a></span> - Variable in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd> </dd>
+<dt><a href="./mpi/Request.html" title="class in mpi"><span class="strong">Request</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Request(mpjdev.Request)">Request(mpjdev.Request)</a></span> - Constructor for class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#REQUEST_NULL">REQUEST_NULL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Rsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Rsend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Send in ready mode.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#rsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">rsend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Rsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Rsend_init(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Creates a persistent communication request for a ready mode send.</div>
+</dd>
+</dl>
+<a name="_S_">
+<!-- -->
+</a>
+<h2 class="title">S</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Scan(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Scan(Object, int, Object, int, int, Datatype, Op)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Perform a prefix reduction on data distributed across the group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Scatter(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Scatter(Object, int, int, Datatype, Object, int, int, Datatype, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Inverse of the operation <tt>Gather</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Scatterv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Scatterv(Object, int, int[], int[], Datatype, Object, int, int, Datatype, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Inverse of the operation <tt>Gatherv</tt>.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Send(java.lang.Object, int, int, mpi.Datatype, int, int)">Send(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Blocking send operation.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#send(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">send(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Send_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Send_init(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Creates a persistent communication request for a standard mode send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#SEND_OVERHEAD">SEND_OVERHEAD</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">Sendrecv(Object, int, int, Datatype, int, int, Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Execute a blocking send and receive operation.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">sendrecv(Object, int, int, Datatype, int, int, Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Sendrecv_replace(java.lang.Object, int, int, mpi.Datatype, int, int, int, int)">Sendrecv_replace(Object, int, int, Datatype, int, int, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Execute a blocking send and receive operation, receiving message into send
+ buffer.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Shift(int, int)">Shift(int, int)</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Compute source and destination ranks for ``shift'' communication.</div>
+</dd>
+<dt><a href="./mpi/ShiftParms.html" title="class in mpi"><span class="strong">ShiftParms</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#SHORT">SHORT</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#SHORT2">SHORT2</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Its actually not good to call the following basic datatypes because they
+ are not ...</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#SIMILAR">SIMILAR</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Size()">Size()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Size of group of this communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Size()">Size()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Returns the total size of a datatype - the number of buffer elements it
+ represents.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Size()">Size()</a></span> - Method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Size of group.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Intracomm.html#Split(int, int)">Split(int, int)</a></span> - Method in class mpi.<a href="./mpi/Intracomm.html" title="class in mpi">Intracomm</a></dt>
+<dd>
+<div class="block">Partition the group associated with this communicator and create a new
+ communicator within each subgroup.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Ssend(java.lang.Object, int, int, mpi.Datatype, int, int)">Ssend(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Send in synchronous mode.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#ssend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">ssend(Object, int, int, Datatype, int, int, boolean)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Ssend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Ssend_init(Object, int, int, Datatype, int, int)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Creates a persistent communication request for a synchronous mode send.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Prequest.html#Start()">Start()</a></span> - Method in class mpi.<a href="./mpi/Prequest.html" title="class in mpi">Prequest</a></dt>
+<dd>
+<div class="block">Activate a persistent communication request.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Prequest.html#Startall(mpi.Prequest[])">Startall(Prequest[])</a></span> - Static method in class mpi.<a href="./mpi/Prequest.html" title="class in mpi">Prequest</a></dt>
+<dd>
+<div class="block">Activate a list of communication requests.</div>
+</dd>
+<dt><a href="./mpi/Status.html" title="class in mpi"><span class="strong">Status</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Status.html#Status(mpjdev.Status)">Status(mpjdev.Status)</a></span> - Constructor for class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Status.html#Status()">Status()</a></span> - Constructor for class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd>
+<div class="block">Constructor</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Struct(int[], int[], mpi.Datatype[])">Struct(int[], int[], Datatype[])</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">The most general type constructor.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Sub(boolean[])">Sub(boolean[])</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd>
+<div class="block">Partition Cartesian communicator into subgroups of lower dimension.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#SUM">SUM</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+</dl>
+<a name="_T_">
+<!-- -->
+</a>
+<h2 class="title">T</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/MPI.html#TAG_UB">TAG_UB</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Test()">Test()</a></span> - Method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Returns a status object if the operation identified by the request is
+ complete, or a null reference otherwise.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Status.html#Test_cancelled()">Test_cancelled()</a></span> - Method in class mpi.<a href="./mpi/Status.html" title="class in mpi">Status</a></dt>
+<dd>
+<div class="block">Test if communication was cancelled.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Test_inter()">Test_inter()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Test if this communicator is an inter-communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Testall(mpi.Request[])">Testall(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Tests for completion of <em>all</em> of the operations associated with
+ active requests.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Testany(mpi.Request[])">Testany(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Tests for completion of either one or none of the operations associated
+ with active requests.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Testsome(mpi.Request[])">Testsome(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Behaves like <tt>Waitsome</tt>, except that it returns immediately.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#THREAD_FUNNELED">THREAD_FUNNELED</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#THREAD_MULTIPLE">THREAD_MULTIPLE</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#THREAD_SERIALIZED">THREAD_SERIALIZED</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#THREAD_SINGLE">THREAD_SINGLE</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Cartcomm.html#Topo_test()">Topo_test()</a></span> - Method in class mpi.<a href="./mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Topo_test()">Topo_test()</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Returns the type of topology associated with the communicator.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Graphcomm.html#Topo_test()">Topo_test()</a></span> - Method in class mpi.<a href="./mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Translate_ranks(mpi.Group, int[], mpi.Group)">Translate_ranks(Group, int[], Group)</a></span> - Static method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Translate ranks within one group to ranks within another.</div>
+</dd>
+</dl>
+<a name="_U_">
+<!-- -->
+</a>
+<h2 class="title">U</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Ub()">Ub()</a></span> - Method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Find the upper bound of a datatype - the greatest value in its displacement
+ sequence.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#UB">UB</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#UNDEFINED">UNDEFINED</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#UNEQUAL">UNEQUAL</a></span> - Static variable in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/Group.html#Union(mpi.Group, mpi.Group)">Union(Group, Group)</a></span> - Static method in class mpi.<a href="./mpi/Group.html" title="class in mpi">Group</a></dt>
+<dd>
+<div class="block">Set union of two groups.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Comm.html#Unpack(mpjbuf.Buffer, int, java.lang.Object, int, int, mpi.Datatype)">Unpack(mpjbuf.Buffer, int, Object, int, int, Datatype)</a></span> - Method in class mpi.<a href="./mpi/Comm.html" title="class in mpi">Comm</a></dt>
+<dd>
+<div class="block">Unpacks message in receive buffer <tt>outbuf</tt> into space specified in
+ <tt>inbuf</tt>.</div>
+</dd>
+<dt><a href="./mpi/User_function.html" title="class in mpi"><span class="strong">User_function</span></a> - Class in <a href="./mpi/package-summary.html">mpi</a></dt>
+<dd> </dd>
+<dt><span class="strong"><a href="./mpi/User_function.html#User_function()">User_function()</a></span> - Constructor for class mpi.<a href="./mpi/User_function.html" title="class in mpi">User_function</a></dt>
+<dd> </dd>
+</dl>
+<a name="_V_">
+<!-- -->
+</a>
+<h2 class="title">V</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Datatype.html#Vector(int, int, int, mpi.Datatype)">Vector(int, int, int, Datatype)</a></span> - Static method in class mpi.<a href="./mpi/Datatype.html" title="class in mpi">Datatype</a></dt>
+<dd>
+<div class="block">Construct new datatype representing replication of old datatype into
+ locations that consist of equally spaced blocks.</div>
+</dd>
+</dl>
+<a name="_W_">
+<!-- -->
+</a>
+<h2 class="title">W</h2>
+<dl>
+<dt><span class="strong"><a href="./mpi/Request.html#Wait()">Wait()</a></span> - Method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Blocks until the operation identified by the request is complete.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Waitall(mpi.Request[])">Waitall(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Blocks until all of the operations associated with the active requests in
+ the array have completed.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Waitany(mpi.Request[])">Waitany(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Blocks until one of the operations associated with the active requests in
+ the array has completed.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/Request.html#Waitsome(mpi.Request[])">Waitsome(Request[])</a></span> - Static method in class mpi.<a href="./mpi/Request.html" title="class in mpi">Request</a></dt>
+<dd>
+<div class="block">Blocks until at least one of the operations associated with the active
+ requests in the array has completed.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Wtick()">Wtick()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Returns resolution of timer.</div>
+</dd>
+<dt><span class="strong"><a href="./mpi/MPI.html#Wtime()">Wtime()</a></span> - Static method in class mpi.<a href="./mpi/MPI.html" title="class in mpi">MPI</a></dt>
+<dd>
+<div class="block">Returns wallclock time.</div>
+</dd>
+</dl>
+<a href="#_A_">A</a> <a href="#_B_">B</a> <a href="#_C_">C</a> <a href="#_D_">D</a> <a href="#_E_">E</a> <a href="#_F_">F</a> <a href="#_G_">G</a> <a href="#_H_">H</a> <a href="#_I_">I</a> <a href="#_L_">L</a> <a href="#_M_">M</a> <a href="#_N_">N</a> <a href="#_O_">O</a> <a href="#_P_">P</a> <a href="#_Q_">Q</a> <a href="#_R_">R</a> <a href="#_S_">S</a> <a href="#_T_">T</a> <a href="#_U_">U</a>&nbs [...]
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="./mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="./overview-tree.html">Tree</a></li>
+<li><a href="./deprecated-list.html">Deprecated</a></li>
+<li class="navBarCell1Rev">Index</li>
+<li><a href="./help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="./index.html?index-all.html" target="_top">Frames</a></li>
+<li><a href="index-all.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="./allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/index.html b/doc/javadocs/index.html
new file mode 100644
index 0000000..bc661e8
--- /dev/null
+++ b/doc/javadocs/index.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc on Fri May 09 20:51:30 PKT 2014 -->
+<title>Generated Documentation (Untitled)</title>
+<script type="text/javascript">
+ targetPage = "" + window.location.search;
+ if (targetPage != "" && targetPage != "undefined")
+ targetPage = targetPage.substring(1);
+ if (targetPage.indexOf(":") != -1 || (targetPage != "" && !validURL(targetPage)))
+ targetPage = "undefined";
+ function validURL(url) {
+ var pos = url.indexOf(".html");
+ if (pos == -1 || pos != url.length - 5)
+ return false;
+ var allowNumber = false;
+ var allowSep = false;
+ var seenDot = false;
+ for (var i = 0; i < url.length - 5; i++) {
+ var ch = url.charAt(i);
+ if ('a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' ||
+ ch == '$' ||
+ ch == '_') {
+ allowNumber = true;
+ allowSep = true;
+ } else if ('0' <= ch && ch <= '9'
+ || ch == '-') {
+ if (!allowNumber)
+ return false;
+ } else if (ch == '/' || ch == '.') {
+ if (!allowSep)
+ return false;
+ allowNumber = false;
+ allowSep = false;
+ if (ch == '.')
+ seenDot = true;
+ if (ch == '/' && seenDot)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ function loadFrames() {
+ if (targetPage != "" && targetPage != "undefined")
+ top.classFrame.location = top.targetPage;
+ }
+</script>
+</head>
+<frameset cols="20%,80%" title="Documentation frame" onload="top.loadFrames()">
+<frame src="allclasses-frame.html" name="packageFrame" title="All classes and interfaces (except non-static nested types)">
+<frame src="mpi/package-summary.html" name="classFrame" title="Package, class and interface descriptions" scrolling="yes">
+<noframes>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<h2>Frame Alert</h2>
+<p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="mpi/package-summary.html">Non-frame version</a>.</p>
+</noframes>
+</frameset>
+</html>
diff --git a/doc/javadocs/mpi/CartParms.html b/doc/javadocs/mpi/CartParms.html
new file mode 100644
index 0000000..66ee076
--- /dev/null
+++ b/doc/javadocs/mpi/CartParms.html
@@ -0,0 +1,252 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>CartParms</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="CartParms";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Cartcomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Comm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/CartParms.html" target="_top">Frames</a></li>
+<li><a href="CartParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class CartParms" class="title">Class CartParms</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.CartParms</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">CartParms</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/CartParms.html#coords">coords</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/CartParms.html#dims">dims</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>boolean[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/CartParms.html#periods">periods</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="dims">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>dims</h4>
+<pre>public int[] dims</pre>
+</li>
+</ul>
+<a name="periods">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>periods</h4>
+<pre>public boolean[] periods</pre>
+</li>
+</ul>
+<a name="coords">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>coords</h4>
+<pre>public int[] coords</pre>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Cartcomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Comm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/CartParms.html" target="_top">Frames</a></li>
+<li><a href="CartParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Cartcomm.html b/doc/javadocs/mpi/Cartcomm.html
new file mode 100644
index 0000000..dc59642
--- /dev/null
+++ b/doc/javadocs/mpi/Cartcomm.html
@@ -0,0 +1,515 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:28 PKT 2014 -->
+<title>Cartcomm</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Cartcomm";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev Class</li>
+<li><a href="../mpi/CartParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Cartcomm.html" target="_top">Frames</a></li>
+<li><a href="Cartcomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Cartcomm" class="title">Class Cartcomm</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Comm.html" title="class in mpi">mpi.Comm</a></li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Intracomm.html" title="class in mpi">mpi.Intracomm</a></li>
+<li>
+<ul class="inheritance">
+<li>mpi.Cartcomm</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Cartcomm</span>
+extends <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="fields_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Fields inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#group">group</a>, <a href="../mpi/Comm.html#mpjdevComm">mpjdevComm</a></code></li>
+</ul>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#clone()">clone</a></strong>()</code>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ ....</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Coords(int)">Coords</a></strong>(int rank)</code>
+<div class="block">Translate process rank to logical process coordinates.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Dims_create(int, int[])">Dims_create</a></strong>(int nnodes,
+ int[] dims)</code>
+<div class="block">Select a balanced distribution of processes per coordinate direction.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/CartParms.html" title="class in mpi">CartParms</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Get()">Get</a></strong>()</code>
+<div class="block">Returns Cartesian topology information.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Map(int[], boolean[])">Map</a></strong>(int[] dims,
+ boolean[] periods)</code>
+<div class="block">Compute an optimal placement.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Rank(int[])">Rank</a></strong>(int[] coords)</code>
+<div class="block">Translate logical process coordinates to process rank.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/ShiftParms.html" title="class in mpi">ShiftParms</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Shift(int, int)">Shift</a></strong>(int direction,
+ int disp)</code>
+<div class="block">Compute source and destination ranks for ``shift'' communication.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Sub(boolean[])">Sub</a></strong>(boolean[] remain_dims)</code>
+<div class="block">Partition Cartesian communicator into subgroups of lower dimension.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Cartcomm.html#Topo_test()">Topo_test</a></strong>()</code>
+<div class="block">Returns the type of topology associated with the communicator.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Intracomm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></h3>
+<code><a href="../mpi/Intracomm.html#Allgather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Allgather</a>, <a href="../mpi/Intracomm.html#Allgatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Allgatherv</a>, <a href="../mpi/Intracomm.html#Allreduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Allreduce</a>, <a href="../mpi/Intracomm.html#Alltoall(java.lang.Object, int, [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#Abort(int)">Abort</a>, <a href="../mpi/Comm.html#Attr_delete(int)">Attr_delete</a>, <a href="../mpi/Comm.html#Attr_get(int)">Attr_get</a>, <a href="../mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init</a>, <a href="../mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend</a>, <a href="../mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend</a>, <a href="../mp [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="clone()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>clone</h4>
+<pre>public java.lang.Object clone()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block"><strong>Description copied from class: <code><a href="../mpi/Intracomm.html#clone()">Intracomm</a></code></strong></div>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ .... changed the return value to Intracomm ...(instead of Object) ...</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Intracomm.html#clone()">clone</a></code> in class <code><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Rank(int[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Rank</h4>
+<pre>public int Rank(int[] coords)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Translate logical process coordinates to process rank.
+ <p>
+ <table>
+ <tr><td><tt> coords </tt></td><td> Cartesian coordinates of a
+ process </tr>
+ <tr><td><em> returns: </em></td><td> rank of the specified process </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_RANK</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Coords(int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Coords</h4>
+<pre>public int[] Coords(int rank)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Translate process rank to logical process coordinates.
+ <p>
+ <table>
+ <tr><td><tt> rank </tt></td><td> rank of a process </tr>
+ <tr><td><em> returns: </em></td><td> Cartesian coordinates of the
+ specified process </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_COORDS</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Shift(int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Shift</h4>
+<pre>public <a href="../mpi/ShiftParms.html" title="class in mpi">ShiftParms</a> Shift(int direction,
+ int disp)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compute source and destination ranks for ``shift'' communication.
+ <p>
+ <table>
+ <tr><td><tt> direction </tt></td><td> coordinate dimension of shift </tr>
+ <tr><td><tt> disp </tt></td><td> displacement </tr>
+ <tr><td><em> returns: </em></td><td> object containing ranks of source
+ and destination processes </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_SHIFT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Sub(boolean[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Sub</h4>
+<pre>public <a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a> Sub(boolean[] remain_dims)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Partition Cartesian communicator into subgroups of lower dimension.
+ <p>
+ <table>
+ <tr><td><tt> remain_dims </tt></td><td> by dimension, <tt>true</tt> if
+ dimension is to be kept,
+ <tt>false</tt> otherwise </tr>
+ <tr><td><em> returns: </em></td><td> communicator containing subgrid
+ including this process </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_SUB</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Map(int[], boolean[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Map</h4>
+<pre>public int Map(int[] dims,
+ boolean[] periods)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compute an optimal placement.
+ <p>
+ <table>
+ <tr><td><tt> dims </tt></td><td> the number of processes in each
+ dimension </tr>
+ <tr><td><tt> periods </tt></td><td> <tt>true</tt> if grid is periodic,
+ <tt>false</tt> if not, in each
+ dimension </tr>
+ <tr><td><em> returns: </em></td><td> reordered rank of calling
+ process </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_MAP</tt>.
+ <p>
+ The number of dimensions is taken to be size of the <tt>dims</tt> argument.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Get()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Get</h4>
+<pre>public <a href="../mpi/CartParms.html" title="class in mpi">CartParms</a> Get()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns Cartesian topology information.
+ <p>
+ <table>
+ <tr><td><em> returns: </em></td><td> object containing dimensions,
+ periods and local coordinates </tr>
+ </table>
+ <p>
+ Java binding of the MPI operations <tt>MPI_CARTDIM_GET</tt> and
+ <tt>MPI_CART_GET</tt>.
+ <p>
+ The number of dimensions can be obtained from the size of (eg)
+ <tt>dims</tt> field of the returned object.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Topo_test()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Topo_test</h4>
+<pre>public int Topo_test()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block"><strong>Description copied from class: <code><a href="../mpi/Comm.html#Topo_test()">Comm</a></code></strong></div>
+<div class="block">Returns the type of topology associated with the communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>topology type of communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TOPO_TEST</tt>.
+ <p>
+ The return value will be one of <tt>MPI.GRAPH</tt>, <tt>MPI.CART</tt> or
+ <tt>MPI.UNDEFINED</tt>.</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Comm.html#Topo_test()">Topo_test</a></code> in class <code><a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Dims_create(int, int[])">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Dims_create</h4>
+<pre>public static void Dims_create(int nnodes,
+ int[] dims)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Select a balanced distribution of processes per coordinate direction.
+ <p>
+ <table>
+ <tr><td><tt> nnodes </tt></td><td> number of nodes in a grid </tr>
+ <tr><td><tt> ndims </tt></td><td> number of dimensions of grid </tr>
+ <tr><td><tt> dims </tt></td><td> array specifying the number of nodes
+ in each dimension </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_DIMS_CREATE</tt>.
+ <p>
+ Size <tt>dims</tt> should be <tt>ndims</tt>. Note that
+ <tt>dims</tt> is an <em>inout</em> parameter.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev Class</li>
+<li><a href="../mpi/CartParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Cartcomm.html" target="_top">Frames</a></li>
+<li><a href="Cartcomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Comm.html b/doc/javadocs/mpi/Comm.html
new file mode 100644
index 0000000..fb9c953
--- /dev/null
+++ b/doc/javadocs/mpi/Comm.html
@@ -0,0 +1,2364 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Comm</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Comm";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/CartParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Datatype.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Comm.html" target="_top">Frames</a></li>
+<li><a href="Comm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Comm" class="title">Class Comm</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Comm</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<dl>
+<dt>Direct Known Subclasses:</dt>
+<dd><a href="../mpi/Intercomm.html" title="class in mpi">Intercomm</a>, <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></dd>
+</dl>
+<hr>
+<br>
+<pre>public class <span class="strong">Comm</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#group">group</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>mpjdev.Comm</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#mpjdevComm">mpjdevComm</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Abort(int)">Abort</a></strong>(int errorcode)</code>
+<div class="block">Abort MPI.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Attr_delete(int)">Attr_delete</a></strong>(int keyval)</code>
+<div class="block">Retrieves attribute value by key.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Attr_get(int)">Attr_get</a></strong>(int keyval)</code>
+<div class="block">Retrieves attribute value by key.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Creates a persistent communication request for a buffered mode send.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Send in buffered mode.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#clone()">clone</a></strong>()</code>
+<div class="block">Duplicate this communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Compare(mpi.Comm, mpi.Comm)">Compare</a></strong>(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm1,
+ <a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm2)</code>
+<div class="block">Compare two communicators.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Intercomm.html" title="class in mpi">Intercomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Create_intercomm(mpi.Comm, int, int, int)">Create_intercomm</a></strong>(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> local_comm,
+ int local_leader,
+ int remote_leader,
+ int tag)</code>
+<div class="block">Create an inter-communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Free()">Free</a></strong>()</code>
+<div class="block">Destroy this communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Group()">Group</a></strong>()</code>
+<div class="block">Return group associated with a communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Ibsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Ibsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Start a buffered mode, nonblocking send.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>protected <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#ibsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">ibsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Iprobe(int, int)">Iprobe</a></strong>(int source,
+ int tag)</code>
+<div class="block">Check if there is an incoming message matching the pattern specified.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Irecv(java.lang.Object, int, int, mpi.Datatype, int, int)">Irecv</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int src,
+ int tag)</code>
+<div class="block">Start a nonblocking receive.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#irecv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">irecv</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int src,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Irsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Irsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Start a ready mode, nonblocking send.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#irsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">irsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Isend(java.lang.Object, int, int, mpi.Datatype, int, int)">Isend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Start a standard mode, nonblocking send.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#isend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">isend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Issend(java.lang.Object, int, int, mpi.Datatype, int, int)">Issend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Start a synchronous mode, nonblocking send.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#issend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">issend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Pack_size(int, mpi.Datatype)">Pack_size</a></strong>(int incount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)</code>
+<div class="block">Returns an upper bound on the increment of <tt>position</tt> effected by
+ <tt>pack</tt>.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Pack(java.lang.Object, int, int, mpi.Datatype, mpjbuf.Buffer, int)">Pack</a></strong>(java.lang.Object inbuf,
+ int offset,
+ int incount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ mpjbuf.Buffer outbuf,
+ int position)</code>
+<div class="block">Packs message in send buffer <tt>inbuf</tt> into space specified in
+ <tt>outbuf</tt>.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Probe(int, int)">Probe</a></strong>(int source,
+ int tag)</code>
+<div class="block">Wait until there is an incoming message matching the pattern specified.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Rank()">Rank</a></strong>()</code>
+<div class="block">Rank of this process in group of this communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Recv_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Recv_init</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Creates a persistent communication request for a receive operation.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Recv(java.lang.Object, int, int, mpi.Datatype, int, int)">Recv</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int source,
+ int tag)</code>
+<div class="block">Blocking receive operation.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>protected <a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#recv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">recv</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int source,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Rsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Rsend_init</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Creates a persistent communication request for a ready mode send.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Rsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Rsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Send in ready mode.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#rsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">rsend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Send_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Send_init</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Creates a persistent communication request for a standard mode send.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Send(java.lang.Object, int, int, mpi.Datatype, int, int)">Send</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Blocking send operation.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>protected void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#send(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">send</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Sendrecv_replace(java.lang.Object, int, int, mpi.Datatype, int, int, int, int)">Sendrecv_replace</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int sendtag,
+ int source,
+ int recvtag)</code>
+<div class="block">Execute a blocking send and receive operation, receiving message into send
+ buffer.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>protected <a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">sendrecv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ int dest,
+ int sendtag,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int source,
+ int recvtag)</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">Sendrecv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ int dest,
+ int sendtag,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int source,
+ int recvtag)</code>
+<div class="block">Execute a blocking send and receive operation.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Size()">Size</a></strong>()</code>
+<div class="block">Size of group of this communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Ssend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Ssend_init</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Creates a persistent communication request for a synchronous mode send.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Ssend(java.lang.Object, int, int, mpi.Datatype, int, int)">Ssend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)</code>
+<div class="block">Send in synchronous mode.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>protected void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#ssend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">ssend</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Test_inter()">Test_inter</a></strong>()</code>
+<div class="block">Test if this communicator is an inter-communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Topo_test()">Topo_test</a></strong>()</code>
+<div class="block">Returns the type of topology associated with the communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Comm.html#Unpack(mpjbuf.Buffer, int, java.lang.Object, int, int, mpi.Datatype)">Unpack</a></strong>(mpjbuf.Buffer inbuf,
+ int position,
+ java.lang.Object outbuf,
+ int offset,
+ int outcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)</code>
+<div class="block">Unpacks message in receive buffer <tt>outbuf</tt> into space specified in
+ <tt>inbuf</tt>.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="group">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>group</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> group</pre>
+</li>
+</ul>
+<a name="mpjdevComm">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>mpjdevComm</h4>
+<pre>public mpjdev.Comm mpjdevComm</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Size()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Size</h4>
+<pre>public int Size()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Size of group of this communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>number of processors in the group of this communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_SIZE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Rank()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Rank</h4>
+<pre>public int Rank()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Rank of this process in group of this communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>rank of the calling process in the group of this communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_RANK</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Group()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Group</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Group()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Return group associated with a communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>group corresponding to this communicator group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_GROUP</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Compare(mpi.Comm, mpi.Comm)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Compare</h4>
+<pre>public static int Compare(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm1,
+ <a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compare two communicators.
+ <p>
+ <table>
+ <tr>
+ <td><tt> comm1 </tt></td>
+ <td>first communicator
+ </tr>
+ <tr>
+ <td><tt> comm2 </tt></td>
+ <td>second communicator
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>result
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ <p>
+ <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ the underlying groups are similar but the communicators differ by context.
+ <tt>MPI.UNEQUAL</tt>(2) results otherwise.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Free()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Free</h4>
+<pre>public void Free()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Destroy this communicator.
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_FREE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Test_inter()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Test_inter</h4>
+<pre>public boolean Test_inter()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Test if this communicator is an inter-communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td> <tt>true</tt> if this is an inter-communicator, <tt>false</tt>
+ otherwise
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_TEST_INTER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Create_intercomm(mpi.Comm, int, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Create_intercomm</h4>
+<pre>public <a href="../mpi/Intercomm.html" title="class in mpi">Intercomm</a> Create_intercomm(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> local_comm,
+ int local_leader,
+ int remote_leader,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create an inter-communicator.
+ <p>
+ <table>
+ <tr>
+ <td><tt> local_comm </tt></td>
+ <td>local intra-communicator
+ </tr>
+ <tr>
+ <td><tt> local_leader </tt></td>
+ <td>rank of local group leader in <tt>localComm</tt>
+ </tr>
+ <tr>
+ <td><tt> remote_leader </tt></td>
+ <td>rank of remote group leader in this communictor
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>``safe'' tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new inter-communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_INTERCOMM_CREATE</tt>.
+ <p>
+ (This operation is defined as a method on the ``peer communicator'', making
+ it analogous to a <tt>send</tt> or <tt>recv</tt> communication with the
+ remote group leader.)</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Attr_get(int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Attr_get</h4>
+<pre>public java.lang.Object Attr_get(int keyval)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Retrieves attribute value by key.
+ <p>
+ <table>
+ <tr>
+ <td><tt> keyval </tt></td>
+ <td>one of the key values predefined by the implementation
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>attribute value
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ATTR_GET</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Attr_delete(int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Attr_delete</h4>
+<pre>public void Attr_delete(int keyval)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Retrieves attribute value by key.
+ <p>
+ <table>
+ <tr>
+ <td><tt> keyval </tt></td>
+ <td>one of the key values predefined by the implementation
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>attribute value
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ATTR_GET</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Send(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Send</h4>
+<pre>public void Send(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocking send operation.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SEND</tt>.
+ <p>
+ The actual argument associated with <tt>buf</tt> must be one-dimensional
+ array. The value <tt>offset</tt> is a subscript in this array, defining the
+ position of the first item of the message.
+ <p>
+ If the <tt>datatype</tt> argument represents an MPI basic type, its value
+ must agree with the element type of <tt>buf</tt>---either a primitive type
+ or a reference (object) type. If the <tt>datatype</tt> argument represents
+ an MPI derived type, its <em>base type</em> must agree with the element
+ type of <tt>buf</tt></div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="send(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>send</h4>
+<pre>protected void send(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Ssend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Ssend</h4>
+<pre>public void Ssend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Send in synchronous mode.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SSEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="ssend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ssend</h4>
+<pre>protected void ssend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Bsend</h4>
+<pre>public void Bsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Send in buffered mode.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_BSEND</tt>.
+ <p>
+ This operation copies message into a buffer (mpi.Buffer) specified by
+ MPI.Buffer_attach operation, and then sends using the standard mode of
+ communication. Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>bsend</h4>
+<pre>protected void bsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Rsend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Rsend</h4>
+<pre>public void Rsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Send in ready mode.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_RSEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="rsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>rsend</h4>
+<pre>protected void rsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Isend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Isend</h4>
+<pre>public <a href="../mpi/Request.html" title="class in mpi">Request</a> Isend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Start a standard mode, nonblocking send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ISEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="isend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>isend</h4>
+<pre>protected <a href="../mpi/Request.html" title="class in mpi">Request</a> isend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Ibsend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Ibsend</h4>
+<pre>public <a href="../mpi/Request.html" title="class in mpi">Request</a> Ibsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Start a buffered mode, nonblocking send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_IBSEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="ibsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ibsend</h4>
+<pre>protected <a href="../mpi/Request.html" title="class in mpi">Request</a> ibsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Issend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Issend</h4>
+<pre>public <a href="../mpi/Request.html" title="class in mpi">Request</a> Issend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Start a synchronous mode, nonblocking send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ISSEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="issend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>issend</h4>
+<pre>protected <a href="../mpi/Request.html" title="class in mpi">Request</a> issend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Irsend(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Irsend</h4>
+<pre>public <a href="../mpi/Request.html" title="class in mpi">Request</a> Irsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Start a ready mode, nonblocking send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_IRSEND</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="irsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>irsend</h4>
+<pre>protected <a href="../mpi/Request.html" title="class in mpi">Request</a> irsend(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Recv(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Recv</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Recv(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int source,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocking receive operation.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in receive buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_RECV</tt>.
+ <p>
+ The actual argument associated with <tt>buf</tt> must be one-dimensional
+ array. The value <tt>offset</tt> is a subscript in this array, defining the
+ position into which the first item of the incoming message will be copied.
+ <p>
+ If the <tt>datatype</tt> argument represents an MPI basic type, its value
+ must agree with the element type of <tt>buf</tt>---either a primitive type
+ or a reference (object) type. If the <tt>datatype</tt> argument represents
+ an MPI derived type, its <em>base type</em> must agree with the element
+ type of <tt>buf</tt></div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="recv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>recv</h4>
+<pre>protected <a href="../mpi/Status.html" title="class in mpi">Status</a> recv(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int source,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Irecv(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Irecv</h4>
+<pre>public <a href="../mpi/Request.html" title="class in mpi">Request</a> Irecv(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int src,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Start a nonblocking receive.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in receive buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_IRECV</tt>.
+ <p>
+ Further comments as for <tt>Recv</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="irecv(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>irecv</h4>
+<pre>protected <a href="../mpi/Request.html" title="class in mpi">Request</a> irecv(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int src,
+ int tag,
+ boolean pt2pt)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Iprobe(int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Iprobe</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Iprobe(int source,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Check if there is an incoming message matching the pattern specified.
+ <p>
+ <table>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object or null handle
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_IPROBE</tt>.
+ <p>
+ If such a message is currently available, a status object similar to the
+ return value of a matching <tt>Recv</tt> operation is returned. Otherwise a
+ null handle is returned.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Probe(int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Probe</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Probe(int source,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Wait until there is an incoming message matching the pattern specified.
+ <p>
+ <table>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_PROBE</tt>.
+ <p>
+ Returns a status object similar to the return value of a matching
+ <tt>Recv</tt> operation.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Pack_size(int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Pack_size</h4>
+<pre>public int Pack_size(int incount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns an upper bound on the increment of <tt>position</tt> effected by
+ <tt>pack</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> incount </tt></td>
+ <td>number of items in input buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in input buffer
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>upper bound on size of packed message
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_PACK_SIZE</tt>.
+ <p>
+ <em>It is an error to call this function if the base type of
+ <tt>datatype</tt> is <tt>MPI.OBJECT</tt></em>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Pack(java.lang.Object, int, int, mpi.Datatype, mpjbuf.Buffer, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Pack</h4>
+<pre>public int Pack(java.lang.Object inbuf,
+ int offset,
+ int incount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ mpjbuf.Buffer outbuf,
+ int position)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Packs message in send buffer <tt>inbuf</tt> into space specified in
+ <tt>outbuf</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> inbuf </tt></td>
+ <td>input buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in input buffer
+ </tr>
+ <tr>
+ <td><tt> incount </tt></td>
+ <td>number of items in input buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in input buffer
+ </tr>
+ <tr>
+ <td><tt> outbuf </tt></td>
+ <td>output buffer
+ </tr>
+ <tr>
+ <td><tt> position </tt></td>
+ <td>initial position in output buffer
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>final position in output buffer
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_PACK</tt>.
+ <p>
+ The return value is the output value of <tt>position</tt> - the inital
+ value incremented by the number of bytes written.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Unpack(mpjbuf.Buffer, int, java.lang.Object, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Unpack</h4>
+<pre>public int Unpack(mpjbuf.Buffer inbuf,
+ int position,
+ java.lang.Object outbuf,
+ int offset,
+ int outcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Unpacks message in receive buffer <tt>outbuf</tt> into space specified in
+ <tt>inbuf</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> inbuf </tt></td>
+ <td>input buffer
+ </tr>
+ <tr>
+ <td><tt> position </tt></td>
+ <td>initial position in input buffer
+ </tr>
+ <tr>
+ <td><tt> outbuf </tt></td>
+ <td>output buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in output buffer
+ </tr>
+ <tr>
+ <td><tt> outcount </tt></td>
+ <td>number of items in output buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in output buffer
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>final position in input buffer
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_UNPACK</tt>.
+ <p>
+ The return value is the output value of <tt>position</tt> - the inital
+ value incremented by the number of bytes read.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Bsend_init</h4>
+<pre>public <a href="../mpi/Prequest.html" title="class in mpi">Prequest</a> Bsend_init(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Creates a persistent communication request for a buffered mode send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>persistent communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_BSEND_INIT</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Send_init(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Send_init</h4>
+<pre>public <a href="../mpi/Prequest.html" title="class in mpi">Prequest</a> Send_init(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Creates a persistent communication request for a standard mode send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>persistent communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SEND_INIT</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Ssend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Ssend_init</h4>
+<pre>public <a href="../mpi/Prequest.html" title="class in mpi">Prequest</a> Ssend_init(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Creates a persistent communication request for a synchronous mode send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>persistent communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SSEND_INIT</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Rsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Rsend_init</h4>
+<pre>public <a href="../mpi/Prequest.html" title="class in mpi">Prequest</a> Rsend_init(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Creates a persistent communication request for a ready mode send.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>persistent communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_RSEND_INIT</tt>.
+ <p>
+ Further comments as for <tt>Send</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Recv_init(java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Recv_init</h4>
+<pre>public <a href="../mpi/Prequest.html" title="class in mpi">Prequest</a> Recv_init(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int tag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Creates a persistent communication request for a receive operation.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in receive buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> tag </tt></td>
+ <td>message tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>communication request
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_RECV_INIT</tt>.
+ <p>
+ Further comments as for <tt>Recv</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Sendrecv</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Sendrecv(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ int dest,
+ int sendtag,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int source,
+ int recvtag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Execute a blocking send and receive operation.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> sendtag </tt></td>
+ <td>send tag
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> recvtag </tt></td>
+ <td>receive tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SENDRECV</tt>.
+ <p>
+ Further comments as for <tt>Send</tt> and <tt>Recv</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Sendrecv_replace(java.lang.Object, int, int, mpi.Datatype, int, int, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Sendrecv_replace</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Sendrecv_replace(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ int dest,
+ int sendtag,
+ int source,
+ int recvtag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Execute a blocking send and receive operation, receiving message into send
+ buffer.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> type </tt></td>
+ <td>datatype of each item in buffer
+ </tr>
+ <tr>
+ <td><tt> dest </tt></td>
+ <td>rank of destination
+ </tr>
+ <tr>
+ <td><tt> sendtag </tt></td>
+ <td>send tag
+ </tr>
+ <tr>
+ <td><tt> source </tt></td>
+ <td>rank of source
+ </tr>
+ <tr>
+ <td><tt> recvtag </tt></td>
+ <td>receive tag
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Further comments as for <tt>Send</tt> and <tt>Recv</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="sendrecv(java.lang.Object, int, int, mpi.Datatype, int, int, java.lang.Object, int, int, mpi.Datatype, int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>sendrecv</h4>
+<pre>protected <a href="../mpi/Status.html" title="class in mpi">Status</a> sendrecv(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ int dest,
+ int sendtag,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int source,
+ int recvtag)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Topo_test()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Topo_test</h4>
+<pre>public int Topo_test()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns the type of topology associated with the communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>topology type of communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TOPO_TEST</tt>.
+ <p>
+ The return value will be one of <tt>MPI.GRAPH</tt>, <tt>MPI.CART</tt> or
+ <tt>MPI.UNDEFINED</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Abort(int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Abort</h4>
+<pre>public void Abort(int errorcode)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Abort MPI.
+ <p>
+ <table>
+ <tr>
+ <td><tt> errorcode </tt></td>
+ <td>error code for Unix or POSIX environments
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ABORT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="clone()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>clone</h4>
+<pre>public java.lang.Object clone()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Duplicate this communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>copy of this communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_DUP</tt>.
+ <p>
+ The new communicator is ``congruent'' to the old one, but has a different
+ context.</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code>clone</code> in class <code>java.lang.Object</code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/CartParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Datatype.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Comm.html" target="_top">Frames</a></li>
+<li><a href="Comm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Datatype.html b/doc/javadocs/mpi/Datatype.html
new file mode 100644
index 0000000..d037a20
--- /dev/null
+++ b/doc/javadocs/mpi/Datatype.html
@@ -0,0 +1,783 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Datatype</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Datatype";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Comm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Errhandler.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Datatype.html" target="_top">Frames</a></li>
+<li><a href="Datatype.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Datatype" class="title">Class Datatype</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Datatype</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public abstract class <span class="strong">Datatype</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#baseType">baseType</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/Datatype.html#Datatype()">Datatype</a></strong>()</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Commit()">Commit</a></strong>()</code>
+<div class="block">Commit a derived datatype.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Contiguous(int, mpi.Datatype)">Contiguous</a></strong>(int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)</code>
+<div class="block">Construct new datatype representing replication of old datatype into
+ contiguous locations.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Extent()">Extent</a></strong>()</code>
+<div class="block">Returns the extent of a datatype - the difference between upper and lower
+ bound.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#finalize()">finalize</a></strong>()</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#free()">free</a></strong>()</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#getByteSize()">getByteSize</a></strong>()</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#getType()">getType</a></strong>()</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Hindexed(int[], int[], mpi.Datatype)">Hindexed</a></strong>(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)</code>
+<div class="block">Identical to <tt>indexed</tt> except that the displacements are expressed
+ directly in terms of the buffer index, rather than the units of the old
+ type.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Hvector(int, int, int, mpi.Datatype)">Hvector</a></strong>(int count,
+ int blocklength,
+ int stride,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)</code>
+<div class="block">Identical to <tt>vector</tt> except that the stride is expressed directly
+ in terms of the buffer index, rather than the units of the old type.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Indexed(int[], int[], mpi.Datatype)">Indexed</a></strong>(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)</code>
+<div class="block">Construct new datatype representing replication of old datatype into a
+ sequence of blocks where each block can contain a different number of
+ copies and have a different displacement.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Lb()">Lb</a></strong>()</code>
+<div class="block">Find the lower bound of a datatype - the least value in its displacement
+ sequence.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Size()">Size</a></strong>()</code>
+<div class="block">Returns the total size of a datatype - the number of buffer elements it
+ represents.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Struct(int[], int[], mpi.Datatype[])">Struct</a></strong>(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a>[] array_of_types)</code>
+<div class="block">The most general type constructor.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Ub()">Ub</a></strong>()</code>
+<div class="block">Find the upper bound of a datatype - the greatest value in its displacement
+ sequence.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Datatype.html#Vector(int, int, int, mpi.Datatype)">Vector</a></strong>(int count,
+ int blocklength,
+ int stride,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)</code>
+<div class="block">Construct new datatype representing replication of old datatype into
+ locations that consist of equally spaced blocks.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="baseType">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>baseType</h4>
+<pre>public int baseType</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="Datatype()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Datatype</h4>
+<pre>public Datatype()</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="getType()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>getType</h4>
+<pre>public int getType()</pre>
+</li>
+</ul>
+<a name="getByteSize()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>getByteSize</h4>
+<pre>public int getByteSize()</pre>
+</li>
+</ul>
+<a name="Extent()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Extent</h4>
+<pre>public int Extent()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns the extent of a datatype - the difference between upper and lower
+ bound.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>datatype extent
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_EXTENT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Size()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Size</h4>
+<pre>public int Size()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns the total size of a datatype - the number of buffer elements it
+ represents.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>datatype size
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_SIZE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Lb()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Lb</h4>
+<pre>public int Lb()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Find the lower bound of a datatype - the least value in its displacement
+ sequence.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>displacement of lower bound from origin
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_LB</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Ub()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Ub</h4>
+<pre>public int Ub()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Find the upper bound of a datatype - the greatest value in its displacement
+ sequence.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>displacement of upper bound from origin
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_UB</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Commit()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Commit</h4>
+<pre>public void Commit()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Commit a derived datatype. Java binding of the MPI operation
+ <tt>MPI_TYPE_COMMIT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="finalize()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>finalize</h4>
+<pre>public void finalize()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code>finalize</code> in class <code>java.lang.Object</code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Contiguous(int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Contiguous</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Contiguous(int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Construct new datatype representing replication of old datatype into
+ contiguous locations.
+ <p>
+ <table>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>replication count
+ </tr>
+ <tr>
+ <td><tt> oldtype </tt></td>
+ <td>old datatype
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_CONTIGUOUS</tt>.
+ <p>
+ The base type of the new datatype is the same as the base type of
+ <tt>oldtype</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Vector(int, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Vector</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Vector(int count,
+ int blocklength,
+ int stride,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Construct new datatype representing replication of old datatype into
+ locations that consist of equally spaced blocks.
+ <p>
+ <table>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of blocks
+ </tr>
+ <tr>
+ <td><tt> blocklength </tt></td>
+ <td>number of elements in each block
+ </tr>
+ <tr>
+ <td><tt> stride </tt></td>
+ <td>number of elements between start of each block
+ </tr>
+ <tr>
+ <td><tt> oldtype </tt></td>
+ <td>old datatype
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_VECTOR</tt>.
+ <p>
+ The base type of the new datatype is the same as the base type of
+ <tt>oldtype</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Hvector(int, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Hvector</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Hvector(int count,
+ int blocklength,
+ int stride,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Identical to <tt>vector</tt> except that the stride is expressed directly
+ in terms of the buffer index, rather than the units of the old type.
+ <p>
+ <table>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of blocks
+ </tr>
+ <tr>
+ <td><tt> blocklength </tt></td>
+ <td>number of elements in each block
+ </tr>
+ <tr>
+ <td><tt> stride </tt></td>
+ <td>number of elements between start of each block
+ </tr>
+ <tr>
+ <td><tt> oldtype </tt></td>
+ <td>old datatype
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_HVECTOR</tt>.
+ <p>
+ <em>Unlike other language bindings</em>, the value of <tt>stride</tt> is
+ <em>not</em> measured in bytes.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Indexed(int[], int[], mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Indexed</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Indexed(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Construct new datatype representing replication of old datatype into a
+ sequence of blocks where each block can contain a different number of
+ copies and have a different displacement.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_blocklengths </tt></td>
+ <td>number of elements per block
+ </tr>
+ <tr>
+ <td><tt> array_of_displacements </tt></td>
+ <td>displacement of each block in units of old type
+ </tr>
+ <tr>
+ <td><tt> oldtype </tt></td>
+ <td>old datatype
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_INDEXED</tt>.
+ <p>
+ The number of blocks is taken to be size of the
+ <tt>array_of_blocklengths</tt> argument. The second argument,
+ <tt>array_of_displacements</tt>, should be the same size. The base type of
+ the new datatype is the same as the base type of <tt>oldtype</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Hindexed(int[], int[], mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Hindexed</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Hindexed(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> oldtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Identical to <tt>indexed</tt> except that the displacements are expressed
+ directly in terms of the buffer index, rather than the units of the old
+ type.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_blocklengths </tt></td>
+ <td>number of elements per block
+ </tr>
+ <tr>
+ <td><tt> array_of_displacements </tt></td>
+ <td>displacement in buffer for each block
+ </tr>
+ <tr>
+ <td><tt> oldtype </tt></td>
+ <td>old datatype
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_HINDEXED</tt>.
+ <p>
+ <em>Unlike other language bindings</em>, the values in
+ <tt>array_of_displacements</tt> are <em>not</em> measured in bytes.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Struct(int[], int[], mpi.Datatype[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Struct</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> Struct(int[] array_of_blocklengths,
+ int[] array_of_displacements,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a>[] array_of_types)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">The most general type constructor.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_blocklengths </tt></td>
+ <td>number of elements per block
+ </tr>
+ <tr>
+ <td><tt> array_of_displacements </tt></td>
+ <td>displacement in buffer for each block
+ </tr>
+ <tr>
+ <td><tt> array_of_types </tt></td>
+ <td>type of elements in each block
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new datatype
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TYPE_STRUCT</tt>.
+ <p>
+ The number of blocks is taken to be size of the
+ <tt>array_of_blocklengths</tt> argument. The second and third arguments,
+ <tt>array_of_displacements</tt>, and <tt>array_of_types</tt>, should be the
+ same size. <em>Unlike other language bindings</em>, the values in
+ <tt>array_of_displacements</tt> are <em>not</em> measured in bytes. All
+ elements of <tt>array_of_types</tt> with definite base types
+ <em>must have the <em>same</em> base type</em>: this will be the base type
+ of new datatype.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="free()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>free</h4>
+<pre>public void free()</pre>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Comm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Errhandler.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Datatype.html" target="_top">Frames</a></li>
+<li><a href="Datatype.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Errhandler.html b/doc/javadocs/mpi/Errhandler.html
new file mode 100644
index 0000000..528ae71
--- /dev/null
+++ b/doc/javadocs/mpi/Errhandler.html
@@ -0,0 +1,184 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Errhandler</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Errhandler";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Datatype.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Graphcomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Errhandler.html" target="_top">Frames</a></li>
+<li><a href="Errhandler.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Errhandler" class="title">Class Errhandler</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Errhandler</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Errhandler</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Datatype.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Graphcomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Errhandler.html" target="_top">Frames</a></li>
+<li><a href="Errhandler.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/GraphParms.html b/doc/javadocs/mpi/GraphParms.html
new file mode 100644
index 0000000..b7fa48d
--- /dev/null
+++ b/doc/javadocs/mpi/GraphParms.html
@@ -0,0 +1,273 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>GraphParms</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="GraphParms";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Graphcomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Group.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/GraphParms.html" target="_top">Frames</a></li>
+<li><a href="GraphParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class GraphParms" class="title">Class GraphParms</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.GraphParms</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">GraphParms</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/GraphParms.html#edges">edges</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/GraphParms.html#index">index</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/GraphParms.html#GraphParms()">GraphParms</a></strong>()</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="index">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>index</h4>
+<pre>public int[] index</pre>
+</li>
+</ul>
+<a name="edges">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>edges</h4>
+<pre>public int[] edges</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="GraphParms()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>GraphParms</h4>
+<pre>public GraphParms()</pre>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Graphcomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Group.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/GraphParms.html" target="_top">Frames</a></li>
+<li><a href="GraphParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Graphcomm.html b/doc/javadocs/mpi/Graphcomm.html
new file mode 100644
index 0000000..df239bc
--- /dev/null
+++ b/doc/javadocs/mpi/Graphcomm.html
@@ -0,0 +1,397 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Graphcomm</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Graphcomm";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Errhandler.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/GraphParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Graphcomm.html" target="_top">Frames</a></li>
+<li><a href="Graphcomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Graphcomm" class="title">Class Graphcomm</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Comm.html" title="class in mpi">mpi.Comm</a></li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Intracomm.html" title="class in mpi">mpi.Intracomm</a></li>
+<li>
+<ul class="inheritance">
+<li>mpi.Graphcomm</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Graphcomm</span>
+extends <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="fields_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Fields inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#group">group</a>, <a href="../mpi/Comm.html#mpjdevComm">mpjdevComm</a></code></li>
+</ul>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Graphcomm.html#clone()">clone</a></strong>()</code>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ ....</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/GraphParms.html" title="class in mpi">GraphParms</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Graphcomm.html#Get()">Get</a></strong>()</code>
+<div class="block">Returns graph topology information.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Graphcomm.html#Map(int[], int[])">Map</a></strong>(int[] index,
+ int[] edges)</code>
+<div class="block">Compute an optimal placement.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Graphcomm.html#Neighbours(int)">Neighbours</a></strong>(int rank)</code>
+<div class="block">Provides adjacency information for general graph topology.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Graphcomm.html#Topo_test()">Topo_test</a></strong>()</code>
+<div class="block">Returns the type of topology associated with the communicator.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Intracomm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></h3>
+<code><a href="../mpi/Intracomm.html#Allgather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Allgather</a>, <a href="../mpi/Intracomm.html#Allgatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Allgatherv</a>, <a href="../mpi/Intracomm.html#Allreduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Allreduce</a>, <a href="../mpi/Intracomm.html#Alltoall(java.lang.Object, int, [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#Abort(int)">Abort</a>, <a href="../mpi/Comm.html#Attr_delete(int)">Attr_delete</a>, <a href="../mpi/Comm.html#Attr_get(int)">Attr_get</a>, <a href="../mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init</a>, <a href="../mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend</a>, <a href="../mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend</a>, <a href="../mp [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="clone()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>clone</h4>
+<pre>public java.lang.Object clone()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block"><strong>Description copied from class: <code><a href="../mpi/Intracomm.html#clone()">Intracomm</a></code></strong></div>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ .... changed the return value to Intracomm ...(instead of Object) ...</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Intracomm.html#clone()">clone</a></code> in class <code><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Get()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Get</h4>
+<pre>public <a href="../mpi/GraphParms.html" title="class in mpi">GraphParms</a> Get()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns graph topology information.
+ <p>
+ <table>
+ <tr><td><em> returns: </em></td><td> object defining node degress and
+ edges of graph </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GRAPHDIMS_GET</tt>.
+ <p>
+ The number of nodes and number of edges can be extracted
+ from the sizes of the <tt>index</tt> and <tt>edges</tt> fields
+ of the returned object.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Neighbours(int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Neighbours</h4>
+<pre>public int[] Neighbours(int rank)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Provides adjacency information for general graph topology.
+ <p>
+ <table>
+ <tr><td><tt> rank </tt></td><td> rank of a process in the group
+ of this communicator </tr>
+ <tr><td><em> returns: </em></td><td> array of ranks of neighbouring
+ processes to one specified </tr>
+ </table>
+ <p>
+ Java binding of the MPI operations <tt>MPI_GRAPH_NEIGHBOURS_COUNT</tt>
+ and <tt>MPI_GRAPH_NEIGHBOURS</tt>.
+ <p>
+ The number of neighbours can be extracted from the size of the result.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Map(int[], int[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Map</h4>
+<pre>public int Map(int[] index,
+ int[] edges)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compute an optimal placement.
+ <p>
+ <table>
+ <tr><td><tt> index </tt></td><td> node degrees </tr>
+ <tr><td><tt> edges </tt></td><td> graph edges </tr>
+ <tr><td><em> returns: </em></td><td> reordered rank of calling
+ process </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GRAPH_MAP</tt>.
+ <p>
+ The number of nodes is taken to be size of the <tt>index</tt> argument.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Topo_test()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Topo_test</h4>
+<pre>public int Topo_test()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block"><strong>Description copied from class: <code><a href="../mpi/Comm.html#Topo_test()">Comm</a></code></strong></div>
+<div class="block">Returns the type of topology associated with the communicator.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>topology type of communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TOPO_TEST</tt>.
+ <p>
+ The return value will be one of <tt>MPI.GRAPH</tt>, <tt>MPI.CART</tt> or
+ <tt>MPI.UNDEFINED</tt>.</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Comm.html#Topo_test()">Topo_test</a></code> in class <code><a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Errhandler.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/GraphParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Graphcomm.html" target="_top">Frames</a></li>
+<li><a href="Graphcomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Group.html b/doc/javadocs/mpi/Group.html
new file mode 100644
index 0000000..a38cf89
--- /dev/null
+++ b/doc/javadocs/mpi/Group.html
@@ -0,0 +1,748 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Group</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Group";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/GraphParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Intercomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Group.html" target="_top">Frames</a></li>
+<li><a href="Group.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Group" class="title">Class Group</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Group</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Group</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#code">code</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#EMPTY">EMPTY</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>mpjdev.Group</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#mpjdevGroup">mpjdevGroup</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/Group.html#Group(mpjdev.Group)">Group</a></strong>(mpjdev.Group mpjdevGroup)</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Compare(mpi.Group, mpi.Group)">Compare</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)</code>
+<div class="block">Compare two groups.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Difference(mpi.Group, mpi.Group)">Difference</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)</code>
+<div class="block">Result contains all elements of the first group that are not in the second
+ group.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Excl(int[])">Excl</a></strong>(int[] ranks)</code>
+<div class="block">Create a subset group excluding specified processes.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#finalize()">finalize</a></strong>()</code>
+<div class="block">Destructor.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#free()">free</a></strong>()</code>
+<div class="block">This method frees this group object.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Incl(int[])">Incl</a></strong>(int[] ranks)</code>
+<div class="block">Create a subset group including specified processes.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Intersection(mpi.Group, mpi.Group)">Intersection</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)</code>
+<div class="block">Set intersection of two groups.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Range_excl(int[][])">Range_excl</a></strong>(int[][] ranges)</code>
+<div class="block">Create a subset group excluding processes specified by strided intervals of
+ ranks.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Range_incl(int[][])">Range_incl</a></strong>(int[][] ranges)</code>
+<div class="block">Create a subset group including processes specified by strided intervals of
+ ranks.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Rank()">Rank</a></strong>()</code>
+<div class="block">Rank of this process in group.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Size()">Size</a></strong>()</code>
+<div class="block">Size of group.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Translate_ranks(mpi.Group, int[], mpi.Group)">Translate_ranks</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ int[] ranks1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)</code>
+<div class="block">Translate ranks within one group to ranks within another.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Group.html#Union(mpi.Group, mpi.Group)">Union</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)</code>
+<div class="block">Set union of two groups.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="EMPTY">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>EMPTY</h4>
+<pre>public static final int EMPTY</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.Group.EMPTY">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="code">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>code</h4>
+<pre>public int code</pre>
+</li>
+</ul>
+<a name="mpjdevGroup">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>mpjdevGroup</h4>
+<pre>public mpjdev.Group mpjdevGroup</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="Group(mpjdev.Group)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Group</h4>
+<pre>public Group(mpjdev.Group mpjdevGroup)</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="free()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>free</h4>
+<pre>public void free()</pre>
+<div class="block">This method frees this group object. Though automatic garbage collector
+ will take care of it, but we mark this object for gc, by declaring it null
+ implement at the end.</div>
+</li>
+</ul>
+<a name="Size()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Size</h4>
+<pre>public int Size()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Size of group.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>number of processors in the group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_SIZE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Rank()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Rank</h4>
+<pre>public int Rank()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Rank of this process in group.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>rank of the calling process in the group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_RANK</tt>.
+
+ Result value is <tt>MPI.UNDEFINED</tt> if this process is not a member of
+ the group.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Translate_ranks(mpi.Group, int[], mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Translate_ranks</h4>
+<pre>public static int[] Translate_ranks(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ int[] ranks1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Translate ranks within one group to ranks within another.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group1 </tt></td>
+ <td>a group
+ </tr>
+ <tr>
+ <td><tt> ranks1 </tt></td>
+ <td>array of valid ranks in <tt>group1</tt>
+ </tr>
+ <tr>
+ <td><tt> group2 </tt></td>
+ <td>another group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>array of corresponding ranks in <tt>group2</tt>
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_TRANSLATE_RANKS</tt>.
+ <p>
+ Result elements are <tt>MPI.UNDEFINED</tt> where no correspondence exists.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Compare(mpi.Group, mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Compare</h4>
+<pre>public static int Compare(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compare two groups.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group1 </tt></td>
+ <td>first group
+ </tr>
+ <tr>
+ <td><tt> group2 </tt></td>
+ <td>second group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>result
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_COMPARE</tt>.
+ <p>
+ <tt>MPI.IDENT</tt> results if the group members and group order are exactly
+ the same in both groups. <tt>MPI.SIMILAR</tt> results if the group members
+ are the same but the order is different. <tt>MPI.UNEQUAL</tt> results
+ otherwise.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Union(mpi.Group, mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Union</h4>
+<pre>public static <a href="../mpi/Group.html" title="class in mpi">Group</a> Union(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Set union of two groups.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group1 </tt></td>
+ <td>first group
+ </tr>
+ <tr>
+ <td><tt> group2 </tt></td>
+ <td>second group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>union group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_UNION</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Intersection(mpi.Group, mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Intersection</h4>
+<pre>public static <a href="../mpi/Group.html" title="class in mpi">Group</a> Intersection(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Set intersection of two groups.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group1 </tt></td>
+ <td>first group
+ </tr>
+ <tr>
+ <td><tt> group2 </tt></td>
+ <td>second group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>intersection group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_INTERSECTION</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Difference(mpi.Group, mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Difference</h4>
+<pre>public static <a href="../mpi/Group.html" title="class in mpi">Group</a> Difference(<a href="../mpi/Group.html" title="class in mpi">Group</a> group1,
+ <a href="../mpi/Group.html" title="class in mpi">Group</a> group2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Result contains all elements of the first group that are not in the second
+ group.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group1 </tt></td>
+ <td>first group
+ </tr>
+ <tr>
+ <td><tt> group2 </tt></td>
+ <td>second group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>difference group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_DIFFERENCE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Incl(int[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Incl</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Incl(int[] ranks)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a subset group including specified processes.
+ <p>
+ <table>
+ <tr>
+ <td><tt> ranks </tt></td>
+ <td>ranks from this group to appear in new group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_INCL</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Excl(int[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Excl</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Excl(int[] ranks)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a subset group excluding specified processes.
+ <p>
+ <table>
+ <tr>
+ <td><tt> ranks </tt></td>
+ <td>ranks from this group <em>not</em> to appear in new group
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_EXCL</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Range_incl(int[][])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Range_incl</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Range_incl(int[][] ranges)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a subset group including processes specified by strided intervals of
+ ranks.
+ <p>
+ <table>
+ <tr>
+ <td><tt> ranges </tt></td>
+ <td>array of integer triplets
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_RANGE_INCL</tt>.
+ <p>
+ The triplets are of the form (first rank, last rank, stride) indicating
+ ranks in this group to be included in the new group. The size of the first
+ dimension of <tt>ranges</tt> is the number of triplets. The size of the
+ second dimension is 3.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Range_excl(int[][])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Range_excl</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Range_excl(int[][] ranges)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a subset group excluding processes specified by strided intervals of
+ ranks.
+ <p>
+ <table>
+ <tr>
+ <td><tt> ranges </tt></td>
+ <td>array of integer triplets
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new group
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_RANGE_EXCL</tt>.
+ <p>
+ Triplet array is defined as for <tt>Range_incl</tt>, the ranges indicating
+ ranks in this group to be excluded from the new group.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="finalize()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>finalize</h4>
+<pre>public void finalize()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Destructor.
+ <p>
+ Java binding of the MPI operation <tt>MPI_GROUP_FREE</tt>.</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code>finalize</code> in class <code>java.lang.Object</code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/GraphParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Intercomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Group.html" target="_top">Frames</a></li>
+<li><a href="Group.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Intercomm.html b/doc/javadocs/mpi/Intercomm.html
new file mode 100644
index 0000000..b3ece22
--- /dev/null
+++ b/doc/javadocs/mpi/Intercomm.html
@@ -0,0 +1,335 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Intercomm</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Intercomm";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Group.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Intracomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Intercomm.html" target="_top">Frames</a></li>
+<li><a href="Intercomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Intercomm" class="title">Class Intercomm</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Comm.html" title="class in mpi">mpi.Comm</a></li>
+<li>
+<ul class="inheritance">
+<li>mpi.Intercomm</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Intercomm</span>
+extends <a href="../mpi/Comm.html" title="class in mpi">Comm</a></pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="fields_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Fields inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#group">group</a>, <a href="../mpi/Comm.html#mpjdevComm">mpjdevComm</a></code></li>
+</ul>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intercomm.html#clone()">clone</a></strong>()</code>
+<div class="block">where would peer communicator come from ...and also localleader,
+ and remoteleader ....</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intercomm.html#Merge(boolean)">Merge</a></strong>(boolean high)</code>
+<div class="block">Create an inter-communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intercomm.html#Remote_group()">Remote_group</a></strong>()</code>
+<div class="block">Return the remote group.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intercomm.html#Remote_size()">Remote_size</a></strong>()</code>
+<div class="block">Size of remote group.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#Abort(int)">Abort</a>, <a href="../mpi/Comm.html#Attr_delete(int)">Attr_delete</a>, <a href="../mpi/Comm.html#Attr_get(int)">Attr_get</a>, <a href="../mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init</a>, <a href="../mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend</a>, <a href="../mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend</a>, <a href="../mp [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Remote_size()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Remote_size</h4>
+<pre>public int Remote_size()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Size of remote group.
+ <p>
+ <table>
+ <tr><td><em> returns: </em></td><td> number of process in remote group
+ of this communicator </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_REMOTE_SIZE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Remote_group()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Remote_group</h4>
+<pre>public <a href="../mpi/Group.html" title="class in mpi">Group</a> Remote_group()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Return the remote group.
+ <p>
+ <table>
+ <tr><td><em> returns: </em></td><td> remote group of this
+ communicator </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_REMOTE_GROUP</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Merge(boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Merge</h4>
+<pre>public <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a> Merge(boolean high)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create an inter-communicator.
+ <p>
+ <table>
+ <tr><td><tt> high </tt></td><td> true if the local group has higher
+ ranks in combined group </tr>
+ <tr><td><em> returns: </em></td><td> new intra-communicator </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_INTERCOMM_MERGE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="clone()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>clone</h4>
+<pre>public java.lang.Object clone()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">where would peer communicator come from ...and also localleader,
+ and remoteleader ....</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Comm.html#clone()">clone</a></code> in class <code><a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Group.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Intracomm.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Intercomm.html" target="_top">Frames</a></li>
+<li><a href="Intercomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Intracomm.html b/doc/javadocs/mpi/Intracomm.html
new file mode 100644
index 0000000..90bf411
--- /dev/null
+++ b/doc/javadocs/mpi/Intracomm.html
@@ -0,0 +1,1474 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Intracomm</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Intracomm";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Intercomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/MPI.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Intracomm.html" target="_top">Frames</a></li>
+<li><a href="Intracomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Intracomm" class="title">Class Intracomm</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Comm.html" title="class in mpi">mpi.Comm</a></li>
+<li>
+<ul class="inheritance">
+<li>mpi.Intracomm</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<dl>
+<dt>Direct Known Subclasses:</dt>
+<dd><a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a>, <a href="../mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></dd>
+</dl>
+<hr>
+<br>
+<pre>public class <span class="strong">Intracomm</span>
+extends <a href="../mpi/Comm.html" title="class in mpi">Comm</a></pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="fields_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Fields inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#group">group</a>, <a href="../mpi/Comm.html#mpjdevComm">mpjdevComm</a></code></li>
+</ul>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Allgather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Allgather</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)</code>
+<div class="block">Similar to <tt>Gather</tt>, but all processes receive the result.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Allgatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Allgatherv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)</code>
+<div class="block">Similar to <tt>Gatherv</tt>, but all processes receive the result.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Allreduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Allreduce</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)</code>
+<div class="block">Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ all process in the group.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Alltoall(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">Alltoall</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)</code>
+<div class="block">Extension of <tt>Allgather</tt> to the case where each process sends
+ distinct data to each of the receivers.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Alltoallv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">Alltoallv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] sdispls,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] rdispls,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)</code>
+<div class="block">Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ specified by <tt>sdispls</tt> and location to place data on receive side is
+ specified by <tt>rdispls</tt>.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Barrier()">Barrier</a></strong>()</code>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Bcast(java.lang.Object, int, int, mpi.Datatype, int)">Bcast</a></strong>(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> type,
+ int root)</code>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>java.lang.Object</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#clone()">clone</a></strong>()</code>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ ....</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Compare(mpi.Comm, mpi.Comm)">Compare</a></strong>(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm1,
+ <a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm2)</code>
+<div class="block">Compare two communicators.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Create_cart(int[], boolean[], boolean)">Create_cart</a></strong>(int[] dims,
+ boolean[] periods,
+ boolean reorder)</code>
+<div class="block">Create a Cartesian topology communicator whose group is a subset of the
+ group of this communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code><a href="../mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Create_graph(int[], int[], boolean)">Create_graph</a></strong>(int[] index,
+ int[] edges,
+ boolean reorder)</code>
+<div class="block">Create a graph topology communicator whose group is a subset of the group
+ of this communicator.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Create(mpi.Group)">Create</a></strong>(<a href="../mpi/Group.html" title="class in mpi">Group</a> group)</code>
+<div class="block">Create a new communicator.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Gather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Gather</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)</code>
+<div class="block">Each process sends the contents of its send buffer to the root process.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Gatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype, int)">Gatherv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)</code>
+<div class="block">Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ from each process.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Reduce_scatter(java.lang.Object, int, java.lang.Object, int, int[], mpi.Datatype, mpi.Op)">Reduce_scatter</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcounts,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)</code>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and scatter the combined values over the output buffers of the
+ processes.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Reduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op, int)">Reduce</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op,
+ int root)</code>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and return the combined value in the output buffer of the root
+ process.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Scan(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">Scan</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)</code>
+<div class="block">Perform a prefix reduction on data distributed across the group.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Scatter(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Scatter</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)</code>
+<div class="block">Inverse of the operation <tt>Gather</tt>.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Scatterv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">Scatterv</a></strong>(java.lang.Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)</code>
+<div class="block">Inverse of the operation <tt>Gatherv</tt>.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Intracomm.html#Split(int, int)">Split</a></strong>(int color,
+ int key)</code>
+<div class="block">Partition the group associated with this communicator and create a new
+ communicator within each subgroup.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Comm">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Comm.html" title="class in mpi">Comm</a></h3>
+<code><a href="../mpi/Comm.html#Abort(int)">Abort</a>, <a href="../mpi/Comm.html#Attr_delete(int)">Attr_delete</a>, <a href="../mpi/Comm.html#Attr_get(int)">Attr_get</a>, <a href="../mpi/Comm.html#Bsend_init(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend_init</a>, <a href="../mpi/Comm.html#Bsend(java.lang.Object, int, int, mpi.Datatype, int, int)">Bsend</a>, <a href="../mpi/Comm.html#bsend(java.lang.Object, int, int, mpi.Datatype, int, int, boolean)">bsend</a>, <a href="../mp [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Compare(mpi.Comm, mpi.Comm)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Compare</h4>
+<pre>public static int Compare(<a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm1,
+ <a href="../mpi/Comm.html" title="class in mpi">Comm</a> comm2)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Compare two communicators.
+ <p>
+ <table>
+ <tr>
+ <td><tt> comm1 </tt></td>
+ <td>first communicator
+ </tr>
+ <tr>
+ <td><tt> comm2 </tt></td>
+ <td>second communicator
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>result
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ <p>
+ <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ the underlying groups are similar but the communicators differ by context.
+ <tt>MPI.UNEQUAL</tt>(2) results otherwise.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Split(int, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Split</h4>
+<pre>public <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a> Split(int color,
+ int key)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Partition the group associated with this communicator and create a new
+ communicator within each subgroup.
+ <p>
+ <table>
+ <tr>
+ <td><tt> color </tt></td>
+ <td>control of subset assignment
+ </tr>
+ <tr>
+ <td><tt> key </tt></td>
+ <td>control of rank assignment
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_SPLIT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="clone()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>clone</h4>
+<pre>public java.lang.Object clone()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Clone the communicator This method will be called only by intracommunicator
+ .... changed the return value to Intracomm ...(instead of Object) ...</div>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code><a href="../mpi/Comm.html#clone()">clone</a></code> in class <code><a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Create(mpi.Group)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Create</h4>
+<pre>public <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a> Create(<a href="../mpi/Group.html" title="class in mpi">Group</a> group)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a new communicator.
+ <p>
+ <table>
+ <tr>
+ <td><tt> group </tt></td>
+ <td>group which is a subset of the group of this communicator
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_COMM_CREATE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Barrier()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Barrier</h4>
+<pre>public void Barrier()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in buffer
+ </tr>
+ /** A call to <tt>Barrier</tt> blocks the caller until all process in the
+ group have called it.
+ <p>
+ Java binding of the MPI operation <tt>MPI_BARRIER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Bcast(java.lang.Object, int, int, mpi.Datatype, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Bcast</h4>
+<pre>public void Bcast(java.lang.Object buf,
+ int offset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> type,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Broadcast a message from the process with rank <tt>root</tt> to all
+ processes of the group.
+ <p>
+ <table>
+ <tr>
+ <td><tt> buf </tt></td>
+ <td>buffer array
+ </tr>
+ <tr>
+ <td><tt> offset </tt></td>
+ <td>initial offset in buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>datatype of each item in buffer
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of broadcast root
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_BCST</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Gather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Gather</h4>
+<pre>public void Gather(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Each process sends the contents of its send buffer to the root process.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items to receive
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of receiving process
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GATHER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Gatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Gatherv</h4>
+<pre>public void Gatherv(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ from each process.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcounts </tt></td>
+ <td>number of elements received from each process
+ </tr>
+ <tr>
+ <td><tt> displs </tt></td>
+ <td>displacements at which to place incoming data
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of receiving process
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ <p>
+ The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt> at
+ which to place incoming data.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Scatter(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Scatter</h4>
+<pre>public void Scatter(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Inverse of the operation <tt>Gather</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items to receive
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of sending process
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SCATTER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Scatterv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int, mpi.Datatype, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Scatterv</h4>
+<pre>public void Scatterv(java.lang.Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Inverse of the operation <tt>Gatherv</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcounts </tt></td>
+ <td>number of items sent to each process
+ </tr>
+ <tr>
+ <td><tt> displs </tt></td>
+ <td>displacements from which to take outgoing data
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items to receive
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of sending process
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Allgather(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Allgather</h4>
+<pre>public void Allgather(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Similar to <tt>Gather</tt>, but all processes receive the result.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items to receive
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Allgatherv(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Allgatherv</h4>
+<pre>public void Allgatherv(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items to send
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcounts </tt></td>
+ <td>number of elements received from each process
+ </tr>
+ <tr>
+ <td><tt> displs </tt></td>
+ <td>displacements at which to place incoming data
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Alltoall(java.lang.Object, int, int, mpi.Datatype, java.lang.Object, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Alltoall</h4>
+<pre>public void Alltoall(java.lang.Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Extension of <tt>Allgather</tt> to the case where each process sends
+ distinct data to each of the receivers.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcount </tt></td>
+ <td>number of items sent to each process
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype send buffer items
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcount </tt></td>
+ <td>number of items received from any process
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of receive buffer items
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Alltoallv(java.lang.Object, int, int[], int[], mpi.Datatype, java.lang.Object, int, int[], int[], mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Alltoallv</h4>
+<pre>public void Alltoallv(java.lang.Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] sdispls,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> sendtype,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] rdispls,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> recvtype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ specified by <tt>sdispls</tt> and location to place data on receive side is
+ specified by <tt>rdispls</tt>.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> sendcounts </tt></td>
+ <td>number of items sent to each process
+ </tr>
+ <tr>
+ <td><tt> sdispls </tt></td>
+ <td>displacements from which to take outgoing data
+ </tr>
+ <tr>
+ <td><tt> sendtype </tt></td>
+ <td>datatype send buffer items
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcounts </tt></td>
+ <td>number of elements received from each process
+ <tr>
+ <td><tt> rdispls </tt></td>
+ <td>displacements at which to place incoming data
+ </tr>
+ <tr>
+ <td><tt> recvtype </tt></td>
+ <td>datatype of each item in receive buffer
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Reduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op, int)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Reduce</h4>
+<pre>public void Reduce(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op,
+ int root)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and return the combined value in the output buffer of the root
+ process.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in send buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>data type of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> op </tt></td>
+ <td>reduce operation
+ </tr>
+ <tr>
+ <td><tt> root </tt></td>
+ <td>rank of root process
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ <p>
+ The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Allreduce(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Allreduce</h4>
+<pre>public void Allreduce(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ all process in the group.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in send buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>data type of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> op </tt></td>
+ <td>reduce operation
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Reduce_scatter(java.lang.Object, int, java.lang.Object, int, int[], mpi.Datatype, mpi.Op)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Reduce_scatter</h4>
+<pre>public void Reduce_scatter(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int[] recvcounts,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Combine elements in input buffer of each process using the reduce
+ operation, and scatter the combined values over the output buffers of the
+ processes.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> recvcounts </tt></td>
+ <td>numbers of result elements distributed to each process
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>data type of each item in send buffer
+ </tr>
+ <tr>
+ <td><tt> op </tt></td>
+ <td>reduce operation
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Scan(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype, mpi.Op)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Scan</h4>
+<pre>public void Scan(java.lang.Object sendbuf,
+ int sendoffset,
+ java.lang.Object recvbuf,
+ int recvoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype,
+ <a href="../mpi/Op.html" title="class in mpi">Op</a> op)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Perform a prefix reduction on data distributed across the group.
+ <p>
+ <table>
+ <tr>
+ <td><tt> sendbuf </tt></td>
+ <td>send buffer array
+ </tr>
+ <tr>
+ <td><tt> sendoffset </tt></td>
+ <td>initial offset in send buffer
+ </tr>
+ <tr>
+ <td><tt> recvbuf </tt></td>
+ <td>receive buffer array
+ </tr>
+ <tr>
+ <td><tt> recvoffset </tt></td>
+ <td>initial offset in receive buffer
+ </tr>
+ <tr>
+ <td><tt> count </tt></td>
+ <td>number of items in input buffer
+ </tr>
+ <tr>
+ <td><tt> datatype </tt></td>
+ <td>data type of each item in input buffer
+ </tr>
+ <tr>
+ <td><tt> op </tt></td>
+ <td>reduce operation
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_SCAN</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Create_cart(int[], boolean[], boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Create_cart</h4>
+<pre>public <a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a> Create_cart(int[] dims,
+ boolean[] periods,
+ boolean reorder)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Create a Cartesian topology communicator whose group is a subset of the
+ group of this communicator.
+ <p>
+ <table>
+ <tr>
+ <td><tt> dims </tt></td>
+ <td>the number of processes in each dimension
+ </tr>
+ <tr>
+ <td><tt> periods </tt></td>
+ <td> <tt>true</tt> if grid is periodic, <tt>false</tt> if not, in each
+ dimension
+ </tr>
+ <tr>
+ <td><tt> reorder </tt></td>
+ <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new Cartesian topology communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_CART_CREATE</tt>.
+ <p>
+ The number of dimensions of the Cartesian grid is taken to be the size of
+ the <tt>dims</tt> argument. The array <tt>periods</tt> must be the same
+ size.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Create_graph(int[], int[], boolean)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Create_graph</h4>
+<pre>public <a href="../mpi/Graphcomm.html" title="class in mpi">Graphcomm</a> Create_graph(int[] index,
+ int[] edges,
+ boolean reorder)</pre>
+<div class="block">Create a graph topology communicator whose group is a subset of the group
+ of this communicator.
+ <p>
+ <table>
+ <tr>
+ <td><tt> index </tt></td>
+ <td>node degrees
+ </tr>
+ <tr>
+ <td><tt> edges </tt></td>
+ <td>graph edges
+ </tr>
+ <tr>
+ <td><tt> reorder </tt></td>
+ <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>new graph topology communicator
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GRAPH_CREATE</tt>.
+ <p>
+ The number of nodes in the graph, <em>nnodes</em>, is taken to be size of
+ the <tt>index</tt> argument. The size of array <tt>edges</tt> must be
+ <tt>index [nnodes} - 1]</tt>.</div>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Intercomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/MPI.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Intracomm.html" target="_top">Frames</a></li>
+<li><a href="Intracomm.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Comm">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/MPI.html b/doc/javadocs/mpi/MPI.html
new file mode 100644
index 0000000..f4d28ec
--- /dev/null
+++ b/doc/javadocs/mpi/MPI.html
@@ -0,0 +1,1375 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>MPI</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="MPI";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Intracomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/MPIException.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/MPI.html" target="_top">Frames</a></li>
+<li><a href="MPI.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class MPI" class="title">Class MPI</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.MPI</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">MPI</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#ANY_SOURCE">ANY_SOURCE</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#ANY_TAG">ANY_TAG</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BAND">BAND</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BOOLEAN">BOOLEAN</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BOR">BOR</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BSEND_OVERHEAD">BSEND_OVERHEAD</a></strong></code>
+<div class="block">Overhead incurred by buffered send.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BXOR">BXOR</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#BYTE">BYTE</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#CART">CART</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#CHAR">CHAR</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#COMM_NULL">COMM_NULL</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Comm.html" title="class in mpi">Comm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#COMM_SELF">COMM_SELF</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#COMM_WORLD">COMM_WORLD</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#CONGRUENT">CONGRUENT</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#DEBUG">DEBUG</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#DOUBLE">DOUBLE</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#DOUBLE2">DOUBLE2</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#EMPTY_STATUS">EMPTY_STATUS</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#ERRORS_ARE_FATAL">ERRORS_ARE_FATAL</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#ERRORS_RETURN">ERRORS_RETURN</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#FLOAT">FLOAT</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#FLOAT2">FLOAT2</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#GRAPH">GRAPH</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#GROUP_EMPTY">GROUP_EMPTY</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Group.html" title="class in mpi">Group</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#GROUP_NULL">GROUP_NULL</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#HOST">HOST</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#IDENT">IDENT</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#INT">INT</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#INT2">INT2</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#IO">IO</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LAND">LAND</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LB">LB</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LONG">LONG</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LONG2">LONG2</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LOR">LOR</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#LXOR">LXOR</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#MAX">MAX</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#MAXLOC">MAXLOC</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#MIN">MIN</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#MINLOC">MINLOC</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#NULL">NULL</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#NUM_OF_PROCESSORS">NUM_OF_PROCESSORS</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#OBJECT">OBJECT</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#PACKED">PACKED</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#PROC_NULL">PROC_NULL</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#PROD">PROD</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#RECV_OVERHEAD">RECV_OVERHEAD</a></strong></code>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Request.html" title="class in mpi">Request</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#REQUEST_NULL">REQUEST_NULL</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#SEND_OVERHEAD">SEND_OVERHEAD</a></strong></code>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#SHORT">SHORT</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#SHORT2">SHORT2</a></strong></code>
+<div class="block">Its actually not good to call the following basic datatypes because they
+ are not ...</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#SIMILAR">SIMILAR</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Op.html" title="class in mpi">Op</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#SUM">SUM</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#TAG_UB">TAG_UB</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#THREAD_FUNNELED">THREAD_FUNNELED</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#THREAD_MULTIPLE">THREAD_MULTIPLE</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#THREAD_SERIALIZED">THREAD_SERIALIZED</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#THREAD_SINGLE">THREAD_SINGLE</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#UB">UB</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#UNDEFINED">UNDEFINED</a></strong></code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#UNEQUAL">UNEQUAL</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/MPI.html#MPI()">MPI</a></strong>()</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Buffer_attach(java.nio.ByteBuffer)">Buffer_attach</a></strong>(java.nio.ByteBuffer userBuffer)</code>
+<div class="block">Provides to MPI a buffer in user's memory to be used for buffering outgoing
+ messages.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Buffer_detach()">Buffer_detach</a></strong>()</code>
+<div class="block">Detach the buffer currently associated with MPI.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Errorhandler_get()">Errorhandler_get</a></strong>()</code>
+<div class="block">Gets the error handler <font color="RED"> Not Implemented in the current
+ release </font></div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Errorhandler_set(mpi.Errhandler)">Errorhandler_set</a></strong>(<a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a> errhandler)</code>
+<div class="block">Set Error Handler <font color="RED"> Not Implemented in the current release
+ </font></div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Finalize()">Finalize</a></strong>()</code>
+<div class="block">Finalize MPI.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static java.lang.String</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Get_processor_name()">Get_processor_name</a></strong>()</code>
+<div class="block">Returns the name of the processor on which it is called.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static java.lang.String[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Init(java.lang.String[])">Init</a></strong>(java.lang.String[] argv)</code>
+<div class="block">Initialize MPI.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Initialized()">Initialized</a></strong>()</code>
+<div class="block">Test if MPI has been initialized.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static java.lang.String[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#initThread(int, int, java.lang.String[])">initThread</a></strong>(int required,
+ int provided,
+ java.lang.String[] argv)</code>
+<div class="block">Used to initialize MPI with certain level of threadedness ...</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#isMainThread()">isMainThread</a></strong>()</code>
+<div class="block">Returns true if this thread initialized MPI</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#queryThread()">queryThread</a></strong>()</code>
+<div class="block">Returns the level of thread support provided by the MPI library and the
+ underlying device selected</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static double</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Wtick()">Wtick</a></strong>()</code>
+<div class="block">Returns resolution of timer.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static double</code></td>
+<td class="colLast"><code><strong><a href="../mpi/MPI.html#Wtime()">Wtime</a></strong>()</code>
+<div class="block">Returns wallclock time.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="DEBUG">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>DEBUG</h4>
+<pre>public static final boolean DEBUG</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.MPI.DEBUG">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="COMM_WORLD">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>COMM_WORLD</h4>
+<pre>public static <a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a> COMM_WORLD</pre>
+</li>
+</ul>
+<a name="NUM_OF_PROCESSORS">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>NUM_OF_PROCESSORS</h4>
+<pre>public static final int NUM_OF_PROCESSORS</pre>
+</li>
+</ul>
+<a name="UNDEFINED">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>UNDEFINED</h4>
+<pre>public static int UNDEFINED</pre>
+</li>
+</ul>
+<a name="NULL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>NULL</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> NULL</pre>
+</li>
+</ul>
+<a name="BYTE">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BYTE</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> BYTE</pre>
+</li>
+</ul>
+<a name="CHAR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>CHAR</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> CHAR</pre>
+</li>
+</ul>
+<a name="SHORT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>SHORT</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> SHORT</pre>
+</li>
+</ul>
+<a name="BOOLEAN">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BOOLEAN</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> BOOLEAN</pre>
+</li>
+</ul>
+<a name="INT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>INT</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> INT</pre>
+</li>
+</ul>
+<a name="LONG">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LONG</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> LONG</pre>
+</li>
+</ul>
+<a name="FLOAT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>FLOAT</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> FLOAT</pre>
+</li>
+</ul>
+<a name="DOUBLE">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>DOUBLE</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> DOUBLE</pre>
+</li>
+</ul>
+<a name="PACKED">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>PACKED</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> PACKED</pre>
+</li>
+</ul>
+<a name="LB">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LB</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> LB</pre>
+</li>
+</ul>
+<a name="UB">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>UB</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> UB</pre>
+</li>
+</ul>
+<a name="OBJECT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>OBJECT</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> OBJECT</pre>
+</li>
+</ul>
+<a name="THREAD_SINGLE">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>THREAD_SINGLE</h4>
+<pre>public static int THREAD_SINGLE</pre>
+</li>
+</ul>
+<a name="THREAD_FUNNELED">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>THREAD_FUNNELED</h4>
+<pre>public static int THREAD_FUNNELED</pre>
+</li>
+</ul>
+<a name="THREAD_SERIALIZED">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>THREAD_SERIALIZED</h4>
+<pre>public static int THREAD_SERIALIZED</pre>
+</li>
+</ul>
+<a name="THREAD_MULTIPLE">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>THREAD_MULTIPLE</h4>
+<pre>public static int THREAD_MULTIPLE</pre>
+</li>
+</ul>
+<a name="SHORT2">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>SHORT2</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> SHORT2</pre>
+<div class="block">Its actually not good to call the following basic datatypes because they
+ are not ... this will be changed to sometyhing else ...need to think about
+ it</div>
+</li>
+</ul>
+<a name="INT2">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>INT2</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> INT2</pre>
+</li>
+</ul>
+<a name="LONG2">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LONG2</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> LONG2</pre>
+</li>
+</ul>
+<a name="FLOAT2">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>FLOAT2</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> FLOAT2</pre>
+</li>
+</ul>
+<a name="DOUBLE2">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>DOUBLE2</h4>
+<pre>public static <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> DOUBLE2</pre>
+</li>
+</ul>
+<a name="MAX">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MAX</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> MAX</pre>
+</li>
+</ul>
+<a name="MIN">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MIN</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> MIN</pre>
+</li>
+</ul>
+<a name="SUM">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>SUM</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> SUM</pre>
+</li>
+</ul>
+<a name="PROD">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>PROD</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> PROD</pre>
+</li>
+</ul>
+<a name="LAND">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LAND</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> LAND</pre>
+</li>
+</ul>
+<a name="BAND">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BAND</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> BAND</pre>
+</li>
+</ul>
+<a name="LOR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LOR</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> LOR</pre>
+</li>
+</ul>
+<a name="BOR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BOR</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> BOR</pre>
+</li>
+</ul>
+<a name="LXOR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>LXOR</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> LXOR</pre>
+</li>
+</ul>
+<a name="BXOR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BXOR</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> BXOR</pre>
+</li>
+</ul>
+<a name="MAXLOC">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MAXLOC</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> MAXLOC</pre>
+</li>
+</ul>
+<a name="MINLOC">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MINLOC</h4>
+<pre>public static <a href="../mpi/Op.html" title="class in mpi">Op</a> MINLOC</pre>
+</li>
+</ul>
+<a name="ANY_SOURCE">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ANY_SOURCE</h4>
+<pre>public static int ANY_SOURCE</pre>
+</li>
+</ul>
+<a name="ANY_TAG">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ANY_TAG</h4>
+<pre>public static int ANY_TAG</pre>
+</li>
+</ul>
+<a name="EMPTY_STATUS">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>EMPTY_STATUS</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a> EMPTY_STATUS</pre>
+</li>
+</ul>
+<a name="PROC_NULL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>PROC_NULL</h4>
+<pre>public static int PROC_NULL</pre>
+</li>
+</ul>
+<a name="BSEND_OVERHEAD">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>BSEND_OVERHEAD</h4>
+<pre>public static int BSEND_OVERHEAD</pre>
+<div class="block">Overhead incurred by buffered send. This variable should be accessed after
+ calling #Init(String[] args) method.</div>
+</li>
+</ul>
+<a name="SEND_OVERHEAD">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>SEND_OVERHEAD</h4>
+<pre>public static int SEND_OVERHEAD</pre>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</li>
+</ul>
+<a name="RECV_OVERHEAD">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>RECV_OVERHEAD</h4>
+<pre>public static int RECV_OVERHEAD</pre>
+<div class="block">These should be accessed after calling MPI.Init()</div>
+</li>
+</ul>
+<a name="GROUP_EMPTY">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>GROUP_EMPTY</h4>
+<pre>public static <a href="../mpi/Group.html" title="class in mpi">Group</a> GROUP_EMPTY</pre>
+</li>
+</ul>
+<a name="COMM_SELF">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>COMM_SELF</h4>
+<pre>public static <a href="../mpi/Comm.html" title="class in mpi">Comm</a> COMM_SELF</pre>
+</li>
+</ul>
+<a name="IDENT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>IDENT</h4>
+<pre>public static final int IDENT</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.MPI.IDENT">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="CONGRUENT">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>CONGRUENT</h4>
+<pre>public static final int CONGRUENT</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.MPI.CONGRUENT">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="SIMILAR">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>SIMILAR</h4>
+<pre>public static final int SIMILAR</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.MPI.SIMILAR">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="UNEQUAL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>UNEQUAL</h4>
+<pre>public static final int UNEQUAL</pre>
+<dl><dt><span class="strong">See Also:</span></dt><dd><a href="../constant-values.html#mpi.MPI.UNEQUAL">Constant Field Values</a></dd></dl>
+</li>
+</ul>
+<a name="GRAPH">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>GRAPH</h4>
+<pre>public static int GRAPH</pre>
+</li>
+</ul>
+<a name="CART">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>CART</h4>
+<pre>public static int CART</pre>
+</li>
+</ul>
+<a name="ERRORS_ARE_FATAL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ERRORS_ARE_FATAL</h4>
+<pre>public static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a> ERRORS_ARE_FATAL</pre>
+</li>
+</ul>
+<a name="ERRORS_RETURN">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>ERRORS_RETURN</h4>
+<pre>public static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a> ERRORS_RETURN</pre>
+</li>
+</ul>
+<a name="TAG_UB">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>TAG_UB</h4>
+<pre>public static int TAG_UB</pre>
+</li>
+</ul>
+<a name="HOST">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>HOST</h4>
+<pre>public static int HOST</pre>
+</li>
+</ul>
+<a name="IO">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>IO</h4>
+<pre>public static int IO</pre>
+</li>
+</ul>
+<a name="REQUEST_NULL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>REQUEST_NULL</h4>
+<pre>public static <a href="../mpi/Request.html" title="class in mpi">Request</a> REQUEST_NULL</pre>
+</li>
+</ul>
+<a name="COMM_NULL">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>COMM_NULL</h4>
+<pre>public static <a href="../mpi/Comm.html" title="class in mpi">Comm</a> COMM_NULL</pre>
+</li>
+</ul>
+<a name="GROUP_NULL">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>GROUP_NULL</h4>
+<pre>public static <a href="../mpi/Group.html" title="class in mpi">Group</a> GROUP_NULL</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="MPI()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>MPI</h4>
+<pre>public MPI()</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Buffer_attach(java.nio.ByteBuffer)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Buffer_attach</h4>
+<pre>public static void Buffer_attach(java.nio.ByteBuffer userBuffer)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Provides to MPI a buffer in user's memory to be used for buffering outgoing
+ messages. Java binding of the MPI operation <tt>MPI_BUFFER_ATTACH</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Buffer_detach()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Buffer_detach</h4>
+<pre>public static void Buffer_detach()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Detach the buffer currently associated with MPI. Java binding of the MPI
+ operation <tt>MPI_BUFFER_DETACH</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="initThread(int, int, java.lang.String[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>initThread</h4>
+<pre>public static java.lang.String[] initThread(int required,
+ int provided,
+ java.lang.String[] argv)</pre>
+<div class="block">Used to initialize MPI with certain level of threadedness ...</div>
+</li>
+</ul>
+<a name="isMainThread()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>isMainThread</h4>
+<pre>public static boolean isMainThread()</pre>
+<div class="block">Returns true if this thread initialized MPI</div>
+</li>
+</ul>
+<a name="queryThread()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>queryThread</h4>
+<pre>public static int queryThread()</pre>
+<div class="block">Returns the level of thread support provided by the MPI library and the
+ underlying device selected</div>
+</li>
+</ul>
+<a name="Init(java.lang.String[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Init</h4>
+<pre>public static java.lang.String[] Init(java.lang.String[] argv)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Initialize MPI.
+ <p>
+ <table>
+ <tr>
+ <td><tt> args </tt></td>
+ <td>arguments to <tt>main</tt> method.
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_INIT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Finalize()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Finalize</h4>
+<pre>public static void Finalize()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Finalize MPI.
+ <p>
+ Java binding of the MPI operation <tt>MPI_FINALIZE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Get_processor_name()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Get_processor_name</h4>
+<pre>public static java.lang.String Get_processor_name()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns the name of the processor on which it is called.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>A unique specifier for the actual node.
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GET_PROCESSOR_NAME</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Errorhandler_set(mpi.Errhandler)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Errorhandler_set</h4>
+<pre>public static void Errorhandler_set(<a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a> errhandler)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Set Error Handler <font color="RED"> Not Implemented in the current release
+ </font></div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Errorhandler_get()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Errorhandler_get</h4>
+<pre>public static <a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a> Errorhandler_get()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Gets the error handler <font color="RED"> Not Implemented in the current
+ release </font></div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Wtime()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Wtime</h4>
+<pre>public static double Wtime()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns wallclock time.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>elapsed wallclock time in seconds since some time in the past
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WTIME</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Wtick()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Wtick</h4>
+<pre>public static double Wtick()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns resolution of timer.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>resolution of <tt>wtime</tt> in seconds.
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WTICK</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Initialized()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Initialized</h4>
+<pre>public static boolean Initialized()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Test if MPI has been initialized.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td> <tt>true</tt> if <tt>Init</tt> has been called, <tt>false</tt>
+ otherwise.
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_INITIALIZED</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Intracomm.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/MPIException.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/MPI.html" target="_top">Frames</a></li>
+<li><a href="MPI.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/MPIException.html b/doc/javadocs/mpi/MPIException.html
new file mode 100644
index 0000000..957532d
--- /dev/null
+++ b/doc/javadocs/mpi/MPIException.html
@@ -0,0 +1,253 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>MPIException</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="MPIException";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/MPI.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Op.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/MPIException.html" target="_top">Frames</a></li>
+<li><a href="MPIException.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class MPIException" class="title">Class MPIException</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>MPJDevException</li>
+<li>
+<ul class="inheritance">
+<li>mpi.MPIException</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">MPIException</span>
+extends MPJDevException</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/MPIException.html#MPIException()">MPIException</a></strong>()</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colOne"><code><strong><a href="../mpi/MPIException.html#MPIException(java.lang.String)">MPIException</a></strong>(java.lang.String message)</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/MPIException.html#MPIException(java.lang.Throwable)">MPIException</a></strong>(java.lang.Throwable cause)</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="MPIException()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MPIException</h4>
+<pre>public MPIException()</pre>
+</li>
+</ul>
+<a name="MPIException(java.lang.String)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>MPIException</h4>
+<pre>public MPIException(java.lang.String message)</pre>
+</li>
+</ul>
+<a name="MPIException(java.lang.Throwable)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>MPIException</h4>
+<pre>public MPIException(java.lang.Throwable cause)</pre>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/MPI.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Op.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/MPIException.html" target="_top">Frames</a></li>
+<li><a href="MPIException.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Op.html b/doc/javadocs/mpi/Op.html
new file mode 100644
index 0000000..af6eb74
--- /dev/null
+++ b/doc/javadocs/mpi/Op.html
@@ -0,0 +1,356 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Op</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Op";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/MPIException.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Prequest.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Op.html" target="_top">Frames</a></li>
+<li><a href="Op.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Op" class="title">Class Op</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Op</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Op</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Op.html#opCode">opCode</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/Op.html#Op(mpi.User_function, boolean)">Op</a></strong>(<a href="../mpi/User_function.html" title="class in mpi">User_function</a> function,
+ boolean commute)</code>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colOne"><code><strong><a href="../mpi/Op.html#Op(mpi.User_function, boolean, int)">Op</a></strong>(<a href="../mpi/User_function.html" title="class in mpi">User_function</a> function,
+ boolean commute,
+ int opCode_)</code>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.</div>
+</td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Op.html#finalize()">finalize</a></strong>()</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Op.html#free()">free</a></strong>()</code> </td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="opCode">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>opCode</h4>
+<pre>public int opCode</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="Op(mpi.User_function, boolean)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Op</h4>
+<pre>public Op(<a href="../mpi/User_function.html" title="class in mpi">User_function</a> function,
+ boolean commute)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.
+ <p>
+ <table>
+ <tr><td><tt> function </tt></td><td> user defined function </tr>
+ <tr><td><tt> commute </tt></td><td> <tt>true</tt> if commutative,
+ <tt>false</tt> otherwise </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_OP_CREATE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Op(mpi.User_function, boolean, int)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Op</h4>
+<pre>public Op(<a href="../mpi/User_function.html" title="class in mpi">User_function</a> function,
+ boolean commute,
+ int opCode_)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Bind a user-defined global reduction operation to an <tt>Op</tt> object.
+ <p>
+ <table>
+ <tr><td><tt> function </tt></td><td> user defined function </tr>
+ <tr><td><tt> commute </tt></td><td> <tt>true</tt> if commutative,
+ <tt>false</tt> otherwise </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_OP_CREATE</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="free()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>free</h4>
+<pre>public void free()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="finalize()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>finalize</h4>
+<pre>public void finalize()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code>finalize</code> in class <code>java.lang.Object</code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/MPIException.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Prequest.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Op.html" target="_top">Frames</a></li>
+<li><a href="Op.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Prequest.html b/doc/javadocs/mpi/Prequest.html
new file mode 100644
index 0000000..fe98bda
--- /dev/null
+++ b/doc/javadocs/mpi/Prequest.html
@@ -0,0 +1,281 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Prequest</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Prequest";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Op.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Request.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Prequest.html" target="_top">Frames</a></li>
+<li><a href="Prequest.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Request">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Prequest" class="title">Class Prequest</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li><a href="../mpi/Request.html" title="class in mpi">mpi.Request</a></li>
+<li>
+<ul class="inheritance">
+<li>mpi.Prequest</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Prequest</span>
+extends <a href="../mpi/Request.html" title="class in mpi">Request</a></pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="fields_inherited_from_class_mpi.Request">
+<!-- -->
+</a>
+<h3>Fields inherited from class mpi.<a href="../mpi/Request.html" title="class in mpi">Request</a></h3>
+<code><a href="../mpi/Request.html#req">req</a></code></li>
+</ul>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Prequest.html#Start()">Start</a></strong>()</code>
+<div class="block">Activate a persistent communication request.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Prequest.html#Startall(mpi.Prequest[])">Startall</a></strong>(<a href="../mpi/Prequest.html" title="class in mpi">Prequest</a>[] array_of_request)</code>
+<div class="block">Activate a list of communication requests.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_mpi.Request">
+<!-- -->
+</a>
+<h3>Methods inherited from class mpi.<a href="../mpi/Request.html" title="class in mpi">Request</a></h3>
+<code><a href="../mpi/Request.html#Cancel()">Cancel</a>, <a href="../mpi/Request.html#finalize()">finalize</a>, <a href="../mpi/Request.html#Is_null()">Is_null</a>, <a href="../mpi/Request.html#Test()">Test</a>, <a href="../mpi/Request.html#Testall(mpi.Request[])">Testall</a>, <a href="../mpi/Request.html#Testany(mpi.Request[])">Testany</a>, <a href="../mpi/Request.html#Testsome(mpi.Request[])">Testsome</a>, <a href="../mpi/Request.html#Wait()">Wait</a>, <a href="../mpi/Request.html#Wait [...]
+</ul>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Start()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Start</h4>
+<pre>public void Start()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Activate a persistent communication request.
+ Java binding of the MPI operation <tt>MPI_START</tt>.
+ The communication is completed by using the request in
+ one of the <tt>wait</tt> or <tt>test</tt> operations.
+ On successful completion the request becomes inactive again.
+ It can be reactivated by a further call to <tt>Start</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Startall(mpi.Prequest[])">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Startall</h4>
+<pre>public static void Startall(<a href="../mpi/Prequest.html" title="class in mpi">Prequest</a>[] array_of_request)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Activate a list of communication requests.
+ <p>
+ <table>
+ <tr><td><tt> array_of_requests </tt></td><td> array of requests </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_STARTALL</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Op.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Request.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Prequest.html" target="_top">Frames</a></li>
+<li><a href="Prequest.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#fields_inherited_from_class_mpi.Request">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li>Constr | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Request.html b/doc/javadocs/mpi/Request.html
new file mode 100644
index 0000000..890662d
--- /dev/null
+++ b/doc/javadocs/mpi/Request.html
@@ -0,0 +1,639 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:29 PKT 2014 -->
+<title>Request</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Request";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Prequest.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/ShiftParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Request.html" target="_top">Frames</a></li>
+<li><a href="Request.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Request" class="title">Class Request</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Request</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<dl>
+<dt>Direct Known Subclasses:</dt>
+<dd><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></dd>
+</dl>
+<hr>
+<br>
+<pre>public class <span class="strong">Request</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>mpjdev.Request</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#req">req</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/Request.html#Request(mpjdev.Request)">Request</a></strong>(mpjdev.Request req)</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Cancel()">Cancel</a></strong>()</code>
+<div class="block">Mark a pending nonblocking communication for cancellation.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#finalize()">finalize</a></strong>()</code> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Is_null()">Is_null</a></strong>()</code>
+<div class="block">Test if request object is void.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Test()">Test</a></strong>()</code>
+<div class="block">Returns a status object if the operation identified by the request is
+ complete, or a null reference otherwise.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a>[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Testall(mpi.Request[])">Testall</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Tests for completion of <em>all</em> of the operations associated with
+ active requests.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Testany(mpi.Request[])">Testany</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Tests for completion of either one or none of the operations associated
+ with active requests.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a>[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Testsome(mpi.Request[])">Testsome</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Behaves like <tt>Waitsome</tt>, except that it returns immediately.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code><a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Wait()">Wait</a></strong>()</code>
+<div class="block">Blocks until the operation identified by the request is complete.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a>[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Waitall(mpi.Request[])">Waitall</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Blocks until all of the operations associated with the active requests in
+ the array have completed.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a></code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Waitany(mpi.Request[])">Waitany</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Blocks until one of the operations associated with the active requests in
+ the array has completed.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="../mpi/Status.html" title="class in mpi">Status</a>[]</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Request.html#Waitsome(mpi.Request[])">Waitsome</a></strong>(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)</code>
+<div class="block">Blocks until at least one of the operations associated with the active
+ requests in the array has completed.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="req">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>req</h4>
+<pre>public mpjdev.Request req</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="Request(mpjdev.Request)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Request</h4>
+<pre>public Request(mpjdev.Request req)</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Wait()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Wait</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Wait()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocks until the operation identified by the request is complete.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WAIT</tt>.
+ <p>
+ After the call returns, the request object becomes inactive.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Test()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Test</h4>
+<pre>public <a href="../mpi/Status.html" title="class in mpi">Status</a> Test()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Returns a status object if the operation identified by the request is
+ complete, or a null reference otherwise.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object or null reference
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TEST</tt>.
+ <p>
+ After the call, if the operation is complete (ie, if the return value is
+ non-null), the request object becomes inactive.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Testany(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Testany</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a> Testany(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Tests for completion of either one or none of the operations associated
+ with active requests.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object or null reference
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TESTANY</tt>.
+ <p>
+ If some request completed, the index in <tt>array_of_requests</tt> for that
+ request can be obtained from the returned status object through the. The
+ corresponding element of <tt>array_of_requests</tt> becomes inactive. If no
+ request completed, <tt>Testany</tt> returns a null reference.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="finalize()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>finalize</h4>
+<pre>public void finalize()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<dl>
+<dt><strong>Overrides:</strong></dt>
+<dd><code>finalize</code> in class <code>java.lang.Object</code></dd>
+<dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Is_null()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Is_null</h4>
+<pre>public boolean Is_null()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Test if request object is void.
+ <p>
+ <table>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>true if the request object is void, false otherwise
+ </tr>
+ </table></div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Waitall(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Waitall</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a>[] Waitall(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocks until all of the operations associated with the active requests in
+ the array have completed.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>array of status objects
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WAITALL</tt>.
+ <p>
+ The result array will be the same size as <tt>array_of_requests</tt>. On
+ exit, requests become inactive. If the <em>input</em> value of
+ <tt>arrayOfRequests</tt> contains inactive requests, corresponding elements
+ of the result array will contain null status references.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Waitany(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Waitany</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a> Waitany(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocks until one of the operations associated with the active requests in
+ the array has completed.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>status object
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WAITANY</tt>.
+ <p>
+ The index in <tt>array_of_requests</tt> for the request that completed can
+ be obtained from the returned status object through the
+ <tt>Status.index</tt> field. The corresponding element of
+ <tt>array_of_requests</tt> becomes inactive.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Testall(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Testall</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a>[] Testall(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Tests for completion of <em>all</em> of the operations associated with
+ active requests.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>array of status objects
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TESTALL</tt>.
+ <p>
+ If all operations have completed, the exit value of the argument array and
+ the result array are as for <tt>Waitall</tt>. If any operation has not
+ completed, the result value is null and no element of the argument array is
+ modified.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Waitsome(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Waitsome</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a>[] Waitsome(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Blocks until at least one of the operations associated with the active
+ requests in the array has completed.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>array of status objects
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_WAITSOME</tt>.
+ <p>
+ The size of the result array will be the number of operations that
+ completed. The index in <tt>array_of_requests</tt> for each request that
+ completed can be obtained from the returned status objects through the
+ <tt>Status.index</tt> field. The corresponding element in
+ <tt>array_of_requests</tt> becomes inactive.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Testsome(mpi.Request[])">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Testsome</h4>
+<pre>public static <a href="../mpi/Status.html" title="class in mpi">Status</a>[] Testsome(<a href="../mpi/Request.html" title="class in mpi">Request</a>[] r)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Behaves like <tt>Waitsome</tt>, except that it returns immediately.
+ <p>
+ <table>
+ <tr>
+ <td><tt> array_of_requests </tt></td>
+ <td>array of requests
+ </tr>
+ <tr>
+ <td><em> returns: </em></td>
+ <td>array of status objects
+ </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TESTSOME</tt>.
+ <p>
+ If no operation has completed, <tt>TestSome</tt> returns an array of length
+ zero and elements of <tt>array_of_requests</tt> are unchanged. Otherwise,
+ arguments and return value are as for <tt>Waitsome</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Cancel()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Cancel</h4>
+<pre>public void Cancel()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Mark a pending nonblocking communication for cancellation. Java binding of
+ the MPI operation <tt>MPI_CANCEL</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Prequest.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/ShiftParms.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Request.html" target="_top">Frames</a></li>
+<li><a href="Request.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/ShiftParms.html b/doc/javadocs/mpi/ShiftParms.html
new file mode 100644
index 0000000..ee5715f
--- /dev/null
+++ b/doc/javadocs/mpi/ShiftParms.html
@@ -0,0 +1,239 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>ShiftParms</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="ShiftParms";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Request.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Status.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/ShiftParms.html" target="_top">Frames</a></li>
+<li><a href="ShiftParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class ShiftParms" class="title">Class ShiftParms</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.ShiftParms</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">ShiftParms</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- =========== FIELD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_summary">
+<!-- -->
+</a>
+<h3>Field Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Field Summary table, listing fields, and an explanation">
+<caption><span>Fields</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Field and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/ShiftParms.html#rank_dest">rank_dest</a></strong></code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/ShiftParms.html#rank_source">rank_source</a></strong></code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ============ FIELD DETAIL =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="field_detail">
+<!-- -->
+</a>
+<h3>Field Detail</h3>
+<a name="rank_source">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>rank_source</h4>
+<pre>public int rank_source</pre>
+</li>
+</ul>
+<a name="rank_dest">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>rank_dest</h4>
+<pre>public int rank_dest</pre>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Request.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/Status.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/ShiftParms.html" target="_top">Frames</a></li>
+<li><a href="ShiftParms.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li><a href="#field_summary">Field</a> | </li>
+<li>Constr | </li>
+<li><a href="#methods_inherited_from_class_java.lang.Object">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li><a href="#field_detail">Field</a> | </li>
+<li>Constr | </li>
+<li>Method</li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/Status.html b/doc/javadocs/mpi/Status.html
new file mode 100644
index 0000000..b6315b4
--- /dev/null
+++ b/doc/javadocs/mpi/Status.html
@@ -0,0 +1,354 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>Status</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Status";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/ShiftParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/User_function.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Status.html" target="_top">Frames</a></li>
+<li><a href="Status.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class Status" class="title">Class Status</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpjdev.Status</li>
+<li>
+<ul class="inheritance">
+<li>mpi.Status</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public class <span class="strong">Status</span>
+extends mpjdev.Status</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/Status.html#Status()">Status</a></strong>()</code>
+<div class="block">Constructor</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colOne"><code><strong><a href="../mpi/Status.html#Status(mpjdev.Status)">Status</a></strong>(mpjdev.Status s)</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Status.html#free()">free</a></strong>()</code> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Status.html#Get_count(mpi.Datatype)">Get_count</a></strong>(<a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)</code>
+<div class="block">Get the number of received entries.</div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>int</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Status.html#Get_elements(mpi.Datatype)">Get_elements</a></strong>(<a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)</code>
+<div class="block">Retrieve number of basic elements from status.</div>
+</td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><code>boolean</code></td>
+<td class="colLast"><code><strong><a href="../mpi/Status.html#Test_cancelled()">Test_cancelled</a></strong>()</code>
+<div class="block">Test if communication was cancelled.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="Status(mpjdev.Status)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Status</h4>
+<pre>public Status(mpjdev.Status s)</pre>
+</li>
+</ul>
+<a name="Status()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Status</h4>
+<pre>public Status()</pre>
+<div class="block">Constructor</div>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Get_count(mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Get_count</h4>
+<pre>public int Get_count(<a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Get the number of received entries.
+ <p>
+ <table>
+ <tr><td><tt> datatype </tt></td><td> datatype of each item in receive
+ buffer </tr>
+ <tr><td><em> returns: </em></td><td> number of received entries </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GET_COUNT</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="Test_cancelled()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>Test_cancelled</h4>
+<pre>public boolean Test_cancelled()
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Test if communication was cancelled.
+ <p>
+ <table>
+ <tr><td><em> returns: </em></td><td> true if the operation was
+ succesfully cancelled,
+ false otherwise
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_TEST_CANCELLED</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+<a name="free()">
+<!-- -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>free</h4>
+<pre>public void free()</pre>
+</li>
+</ul>
+<a name="Get_elements(mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Get_elements</h4>
+<pre>public int Get_elements(<a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">Retrieve number of basic elements from status.
+ <p>
+ <table>
+ <tr><td><tt> datatype </tt></td><td> datatype used by receive
+ operation </tr>
+ <tr><td><em> returns: </em></td><td> number of received basic
+ elements </tr>
+ </table>
+ <p>
+ Java binding of the MPI operation <tt>MPI_GET_ELEMENTS</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/ShiftParms.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li><a href="../mpi/User_function.html" title="class in mpi"><span class="strong">Next Class</span></a></li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/Status.html" target="_top">Frames</a></li>
+<li><a href="Status.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/User_function.html b/doc/javadocs/mpi/User_function.html
new file mode 100644
index 0000000..7f282b8
--- /dev/null
+++ b/doc/javadocs/mpi/User_function.html
@@ -0,0 +1,283 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>User_function</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="User_function";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Status.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li>Next Class</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/User_function.html" target="_top">Frames</a></li>
+<li><a href="User_function.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<!-- ======== START OF CLASS DATA ======== -->
+<div class="header">
+<div class="subTitle">mpi</div>
+<h2 title="Class User_function" class="title">Class User_function</h2>
+</div>
+<div class="contentContainer">
+<ul class="inheritance">
+<li>java.lang.Object</li>
+<li>
+<ul class="inheritance">
+<li>mpi.User_function</li>
+</ul>
+</li>
+</ul>
+<div class="description">
+<ul class="blockList">
+<li class="blockList">
+<hr>
+<br>
+<pre>public abstract class <span class="strong">User_function</span>
+extends java.lang.Object</pre>
+</li>
+</ul>
+</div>
+<div class="summary">
+<ul class="blockList">
+<li class="blockList">
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_summary">
+<!-- -->
+</a>
+<h3>Constructor Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
+<caption><span>Constructors</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colOne" scope="col">Constructor and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colOne"><code><strong><a href="../mpi/User_function.html#User_function()">User_function</a></strong>()</code> </td>
+</tr>
+</table>
+</li>
+</ul>
+<!-- ========== METHOD SUMMARY =========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_summary">
+<!-- -->
+</a>
+<h3>Method Summary</h3>
+<table class="overviewSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
+<caption><span>Methods</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Modifier and Type</th>
+<th class="colLast" scope="col">Method and Description</th>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>abstract void</code></td>
+<td class="colLast"><code><strong><a href="../mpi/User_function.html#Call(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype)">Call</a></strong>(java.lang.Object invec,
+ int inoffset,
+ java.lang.Object inoutvec,
+ int inoutoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)</code>
+<div class="block">User-defined function for a new <tt>Op</tt>.</div>
+</td>
+</tr>
+</table>
+<ul class="blockList">
+<li class="blockList"><a name="methods_inherited_from_class_java.lang.Object">
+<!-- -->
+</a>
+<h3>Methods inherited from class java.lang.Object</h3>
+<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="details">
+<ul class="blockList">
+<li class="blockList">
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<ul class="blockList">
+<li class="blockList"><a name="constructor_detail">
+<!-- -->
+</a>
+<h3>Constructor Detail</h3>
+<a name="User_function()">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>User_function</h4>
+<pre>public User_function()</pre>
+</li>
+</ul>
+</li>
+</ul>
+<!-- ============ METHOD DETAIL ========== -->
+<ul class="blockList">
+<li class="blockList"><a name="method_detail">
+<!-- -->
+</a>
+<h3>Method Detail</h3>
+<a name="Call(java.lang.Object, int, java.lang.Object, int, int, mpi.Datatype)">
+<!-- -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>Call</h4>
+<pre>public abstract void Call(java.lang.Object invec,
+ int inoffset,
+ java.lang.Object inoutvec,
+ int inoutoffset,
+ int count,
+ <a href="../mpi/Datatype.html" title="class in mpi">Datatype</a> datatype)
+ throws <a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></pre>
+<div class="block">User-defined function for a new <tt>Op</tt>.
+ <p>
+ <table>
+ <tr><td><tt> invec </tt></td><td> array of values to combine with
+ <tt>inoutvec</tt> elements </tr>
+ <tr><td><tt> inoffset </tt></td><td> initial offset in
+ <tt>invec<tt> </tr>
+ <tr><td><tt> inoutvec </tt></td><td> in-out array of accumulator
+ locations </tr>
+ <tr><td><tt> inoutoffset </tt></td><td> initial offset in
+ <tt>inoutvec<tt> </tr>
+ <tr><td><tt> count </tt></td><td> number of items in arrays </tr>
+ <tr><td><tt> datatype </tt></td><td> type of each item </tr>
+ </table>
+ <p>
+ Java equivalent of the MPI <tt>USER_FUNCTION</tt>.</div>
+<dl><dt><span class="strong">Throws:</span></dt>
+<dd><code><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></code></dd></dl>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<!-- ========= END OF CLASS DATA ========= -->
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li class="navBarCell1Rev">Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li><a href="../mpi/Status.html" title="class in mpi"><span class="strong">Prev Class</span></a></li>
+<li>Next Class</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/User_function.html" target="_top">Frames</a></li>
+<li><a href="User_function.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<div>
+<ul class="subNavList">
+<li>Summary: </li>
+<li>Nested | </li>
+<li>Field | </li>
+<li><a href="#constructor_summary">Constr</a> | </li>
+<li><a href="#method_summary">Method</a></li>
+</ul>
+<ul class="subNavList">
+<li>Detail: </li>
+<li>Field | </li>
+<li><a href="#constructor_detail">Constr</a> | </li>
+<li><a href="#method_detail">Method</a></li>
+</ul>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/package-frame.html b/doc/javadocs/mpi/package-frame.html
new file mode 100644
index 0000000..b470656
--- /dev/null
+++ b/doc/javadocs/mpi/package-frame.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>mpi</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<h1 class="bar"><a href="../mpi/package-summary.html" target="classFrame">mpi</a></h1>
+<div class="indexContainer">
+<h2 title="Classes">Classes</h2>
+<ul title="Classes">
+<li><a href="Cartcomm.html" title="class in mpi" target="classFrame">Cartcomm</a></li>
+<li><a href="CartParms.html" title="class in mpi" target="classFrame">CartParms</a></li>
+<li><a href="Comm.html" title="class in mpi" target="classFrame">Comm</a></li>
+<li><a href="Datatype.html" title="class in mpi" target="classFrame">Datatype</a></li>
+<li><a href="Errhandler.html" title="class in mpi" target="classFrame">Errhandler</a></li>
+<li><a href="Graphcomm.html" title="class in mpi" target="classFrame">Graphcomm</a></li>
+<li><a href="GraphParms.html" title="class in mpi" target="classFrame">GraphParms</a></li>
+<li><a href="Group.html" title="class in mpi" target="classFrame">Group</a></li>
+<li><a href="Intercomm.html" title="class in mpi" target="classFrame">Intercomm</a></li>
+<li><a href="Intracomm.html" title="class in mpi" target="classFrame">Intracomm</a></li>
+<li><a href="MPI.html" title="class in mpi" target="classFrame">MPI</a></li>
+<li><a href="MPIException.html" title="class in mpi" target="classFrame">MPIException</a></li>
+<li><a href="Op.html" title="class in mpi" target="classFrame">Op</a></li>
+<li><a href="Prequest.html" title="class in mpi" target="classFrame">Prequest</a></li>
+<li><a href="Request.html" title="class in mpi" target="classFrame">Request</a></li>
+<li><a href="ShiftParms.html" title="class in mpi" target="classFrame">ShiftParms</a></li>
+<li><a href="Status.html" title="class in mpi" target="classFrame">Status</a></li>
+<li><a href="User_function.html" title="class in mpi" target="classFrame">User_function</a></li>
+</ul>
+</div>
+</body>
+</html>
diff --git a/doc/javadocs/mpi/package-summary.html b/doc/javadocs/mpi/package-summary.html
new file mode 100644
index 0000000..a2dfe9a
--- /dev/null
+++ b/doc/javadocs/mpi/package-summary.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>mpi</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="mpi";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev Package</li>
+<li>Next Package</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/package-summary.html" target="_top">Frames</a></li>
+<li><a href="package-summary.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 title="Package" class="title">Package mpi</h1>
+</div>
+<div class="contentContainer">
+<ul class="blockList">
+<li class="blockList">
+<table class="packageSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
+<caption><span>Class Summary</span><span class="tabEnd"> </span></caption>
+<tr>
+<th class="colFirst" scope="col">Class</th>
+<th class="colLast" scope="col">Description</th>
+</tr>
+<tbody>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Cartcomm.html" title="class in mpi">Cartcomm</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/CartParms.html" title="class in mpi">CartParms</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Comm.html" title="class in mpi">Comm</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/Datatype.html" title="class in mpi">Datatype</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Errhandler.html" title="class in mpi">Errhandler</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/Graphcomm.html" title="class in mpi">Graphcomm</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/GraphParms.html" title="class in mpi">GraphParms</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/Group.html" title="class in mpi">Group</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Intercomm.html" title="class in mpi">Intercomm</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/Intracomm.html" title="class in mpi">Intracomm</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/MPI.html" title="class in mpi">MPI</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/MPIException.html" title="class in mpi">MPIException</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Op.html" title="class in mpi">Op</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/Prequest.html" title="class in mpi">Prequest</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Request.html" title="class in mpi">Request</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/ShiftParms.html" title="class in mpi">ShiftParms</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a href="../mpi/Status.html" title="class in mpi">Status</a></td>
+<td class="colLast"> </td>
+</tr>
+<tr class="rowColor">
+<td class="colFirst"><a href="../mpi/User_function.html" title="class in mpi">User_function</a></td>
+<td class="colLast"> </td>
+</tr>
+</tbody>
+</table>
+</li>
+</ul>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li><a href="package-tree.html">Tree</a></li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev Package</li>
+<li>Next Package</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/package-summary.html" target="_top">Frames</a></li>
+<li><a href="package-summary.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/mpi/package-tree.html b/doc/javadocs/mpi/package-tree.html
new file mode 100644
index 0000000..0e8f33f
--- /dev/null
+++ b/doc/javadocs/mpi/package-tree.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>mpi Class Hierarchy</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="mpi Class Hierarchy";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="navBarCell1Rev">Tree</li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/package-tree.html" target="_top">Frames</a></li>
+<li><a href="package-tree.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 class="title">Hierarchy For Package mpi</h1>
+</div>
+<div class="contentContainer">
+<h2 title="Class Hierarchy">Class Hierarchy</h2>
+<ul>
+<li type="circle">java.lang.Object
+<ul>
+<li type="circle">mpi.<a href="../mpi/CartParms.html" title="class in mpi"><span class="strong">CartParms</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Comm.html" title="class in mpi"><span class="strong">Comm</span></a>
+<ul>
+<li type="circle">mpi.<a href="../mpi/Intercomm.html" title="class in mpi"><span class="strong">Intercomm</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Intracomm.html" title="class in mpi"><span class="strong">Intracomm</span></a>
+<ul>
+<li type="circle">mpi.<a href="../mpi/Cartcomm.html" title="class in mpi"><span class="strong">Cartcomm</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Graphcomm.html" title="class in mpi"><span class="strong">Graphcomm</span></a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="../mpi/Datatype.html" title="class in mpi"><span class="strong">Datatype</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Errhandler.html" title="class in mpi"><span class="strong">Errhandler</span></a></li>
+<li type="circle">mpi.<a href="../mpi/GraphParms.html" title="class in mpi"><span class="strong">GraphParms</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Group.html" title="class in mpi"><span class="strong">Group</span></a></li>
+<li type="circle">mpi.<a href="../mpi/MPI.html" title="class in mpi"><span class="strong">MPI</span></a></li>
+<li type="circle">MPJDevException
+<ul>
+<li type="circle">mpi.<a href="../mpi/MPIException.html" title="class in mpi"><span class="strong">MPIException</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="../mpi/Op.html" title="class in mpi"><span class="strong">Op</span></a></li>
+<li type="circle">mpi.<a href="../mpi/Request.html" title="class in mpi"><span class="strong">Request</span></a>
+<ul>
+<li type="circle">mpi.<a href="../mpi/Prequest.html" title="class in mpi"><span class="strong">Prequest</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="../mpi/ShiftParms.html" title="class in mpi"><span class="strong">ShiftParms</span></a></li>
+<li type="circle">mpjdev.Status
+<ul>
+<li type="circle">mpi.<a href="../mpi/Status.html" title="class in mpi"><span class="strong">Status</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="../mpi/User_function.html" title="class in mpi"><span class="strong">User_function</span></a></li>
+</ul>
+</li>
+</ul>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="../mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="navBarCell1Rev">Tree</li>
+<li><a href="../deprecated-list.html">Deprecated</a></li>
+<li><a href="../index-all.html">Index</a></li>
+<li><a href="../help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="../index.html?mpi/package-tree.html" target="_top">Frames</a></li>
+<li><a href="package-tree.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="../allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/overview-tree.html b/doc/javadocs/overview-tree.html
new file mode 100644
index 0000000..3b95142
--- /dev/null
+++ b/doc/javadocs/overview-tree.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- NewPage -->
+<html lang="en">
+<head>
+<!-- Generated by javadoc (version 1.7.0_25) on Fri May 09 20:51:30 PKT 2014 -->
+<title>Class Hierarchy</title>
+<meta name="date" content="2014-05-09">
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
+</head>
+<body>
+<script type="text/javascript"><!--
+ if (location.href.indexOf('is-external=true') == -1) {
+ parent.document.title="Class Hierarchy";
+ }
+//-->
+</script>
+<noscript>
+<div>JavaScript is disabled on your browser.</div>
+</noscript>
+<!-- ========= START OF TOP NAVBAR ======= -->
+<div class="topNav"><a name="navbar_top">
+<!-- -->
+</a><a href="#skip-navbar_top" title="Skip navigation links"></a><a name="navbar_top_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="navBarCell1Rev">Tree</li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?overview-tree.html" target="_top">Frames</a></li>
+<li><a href="overview-tree.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_top">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_top");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_top">
+<!-- -->
+</a></div>
+<!-- ========= END OF TOP NAVBAR ========= -->
+<div class="header">
+<h1 class="title">Hierarchy For All Packages</h1>
+<span class="strong">Package Hierarchies:</span>
+<ul class="horizontal">
+<li><a href="mpi/package-tree.html">mpi</a></li>
+</ul>
+</div>
+<div class="contentContainer">
+<h2 title="Class Hierarchy">Class Hierarchy</h2>
+<ul>
+<li type="circle">java.lang.Object
+<ul>
+<li type="circle">mpi.<a href="mpi/CartParms.html" title="class in mpi"><span class="strong">CartParms</span></a></li>
+<li type="circle">mpi.<a href="mpi/Comm.html" title="class in mpi"><span class="strong">Comm</span></a>
+<ul>
+<li type="circle">mpi.<a href="mpi/Intercomm.html" title="class in mpi"><span class="strong">Intercomm</span></a></li>
+<li type="circle">mpi.<a href="mpi/Intracomm.html" title="class in mpi"><span class="strong">Intracomm</span></a>
+<ul>
+<li type="circle">mpi.<a href="mpi/Cartcomm.html" title="class in mpi"><span class="strong">Cartcomm</span></a></li>
+<li type="circle">mpi.<a href="mpi/Graphcomm.html" title="class in mpi"><span class="strong">Graphcomm</span></a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="mpi/Datatype.html" title="class in mpi"><span class="strong">Datatype</span></a></li>
+<li type="circle">mpi.<a href="mpi/Errhandler.html" title="class in mpi"><span class="strong">Errhandler</span></a></li>
+<li type="circle">mpi.<a href="mpi/GraphParms.html" title="class in mpi"><span class="strong">GraphParms</span></a></li>
+<li type="circle">mpi.<a href="mpi/Group.html" title="class in mpi"><span class="strong">Group</span></a></li>
+<li type="circle">mpi.<a href="mpi/MPI.html" title="class in mpi"><span class="strong">MPI</span></a></li>
+<li type="circle">MPJDevException
+<ul>
+<li type="circle">mpi.<a href="mpi/MPIException.html" title="class in mpi"><span class="strong">MPIException</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="mpi/Op.html" title="class in mpi"><span class="strong">Op</span></a></li>
+<li type="circle">mpi.<a href="mpi/Request.html" title="class in mpi"><span class="strong">Request</span></a>
+<ul>
+<li type="circle">mpi.<a href="mpi/Prequest.html" title="class in mpi"><span class="strong">Prequest</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="mpi/ShiftParms.html" title="class in mpi"><span class="strong">ShiftParms</span></a></li>
+<li type="circle">mpjdev.Status
+<ul>
+<li type="circle">mpi.<a href="mpi/Status.html" title="class in mpi"><span class="strong">Status</span></a></li>
+</ul>
+</li>
+<li type="circle">mpi.<a href="mpi/User_function.html" title="class in mpi"><span class="strong">User_function</span></a></li>
+</ul>
+</li>
+</ul>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->
+<div class="bottomNav"><a name="navbar_bottom">
+<!-- -->
+</a><a href="#skip-navbar_bottom" title="Skip navigation links"></a><a name="navbar_bottom_firstrow">
+<!-- -->
+</a>
+<ul class="navList" title="Navigation">
+<li><a href="mpi/package-summary.html">Package</a></li>
+<li>Class</li>
+<li class="navBarCell1Rev">Tree</li>
+<li><a href="deprecated-list.html">Deprecated</a></li>
+<li><a href="index-all.html">Index</a></li>
+<li><a href="help-doc.html">Help</a></li>
+</ul>
+</div>
+<div class="subNav">
+<ul class="navList">
+<li>Prev</li>
+<li>Next</li>
+</ul>
+<ul class="navList">
+<li><a href="index.html?overview-tree.html" target="_top">Frames</a></li>
+<li><a href="overview-tree.html" target="_top">No Frames</a></li>
+</ul>
+<ul class="navList" id="allclasses_navbar_bottom">
+<li><a href="allclasses-noframe.html">All Classes</a></li>
+</ul>
+<div>
+<script type="text/javascript"><!--
+ allClassesLink = document.getElementById("allclasses_navbar_bottom");
+ if(window==top) {
+ allClassesLink.style.display = "block";
+ }
+ else {
+ allClassesLink.style.display = "none";
+ }
+ //-->
+</script>
+</div>
+<a name="skip-navbar_bottom">
+<!-- -->
+</a></div>
+<!-- ======== END OF BOTTOM NAVBAR ======= -->
+</body>
+</html>
diff --git a/doc/javadocs/package-list b/doc/javadocs/package-list
new file mode 100644
index 0000000..1a6f598
--- /dev/null
+++ b/doc/javadocs/package-list
@@ -0,0 +1 @@
+mpi
diff --git a/doc/javadocs/resources/background.gif b/doc/javadocs/resources/background.gif
new file mode 100644
index 0000000..f471940
Binary files /dev/null and b/doc/javadocs/resources/background.gif differ
diff --git a/doc/javadocs/resources/tab.gif b/doc/javadocs/resources/tab.gif
new file mode 100644
index 0000000..1a73a83
Binary files /dev/null and b/doc/javadocs/resources/tab.gif differ
diff --git a/doc/javadocs/resources/titlebar.gif b/doc/javadocs/resources/titlebar.gif
new file mode 100644
index 0000000..17443b3
Binary files /dev/null and b/doc/javadocs/resources/titlebar.gif differ
diff --git a/doc/javadocs/resources/titlebar_end.gif b/doc/javadocs/resources/titlebar_end.gif
new file mode 100644
index 0000000..3ad78d4
Binary files /dev/null and b/doc/javadocs/resources/titlebar_end.gif differ
diff --git a/doc/javadocs/stylesheet.css b/doc/javadocs/stylesheet.css
new file mode 100644
index 0000000..0aeaa97
--- /dev/null
+++ b/doc/javadocs/stylesheet.css
@@ -0,0 +1,474 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+body {
+ background-color:#ffffff;
+ color:#353833;
+ font-family:Arial, Helvetica, sans-serif;
+ font-size:76%;
+ margin:0;
+}
+a:link, a:visited {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a:hover, a:focus {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+a:active {
+ text-decoration:none;
+ color:#4c6b87;
+}
+a[name] {
+ color:#353833;
+}
+a[name]:hover {
+ text-decoration:none;
+ color:#353833;
+}
+pre {
+ font-size:1.3em;
+}
+h1 {
+ font-size:1.8em;
+}
+h2 {
+ font-size:1.5em;
+}
+h3 {
+ font-size:1.4em;
+}
+h4 {
+ font-size:1.3em;
+}
+h5 {
+ font-size:1.2em;
+}
+h6 {
+ font-size:1.1em;
+}
+ul {
+ list-style-type:disc;
+}
+code, tt {
+ font-size:1.2em;
+}
+dt code {
+ font-size:1.2em;
+}
+table tr td dt code {
+ font-size:1.2em;
+ vertical-align:top;
+}
+sup {
+ font-size:.6em;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+ clear:both;
+ height:0px;
+ overflow:hidden;
+}
+.aboutLanguage {
+ float:right;
+ padding:0px 21px;
+ font-size:.8em;
+ z-index:200;
+ margin-top:-7px;
+}
+.legalCopy {
+ margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+ color:#bb7a2a;
+}
+.tab {
+ background-color:#0066FF;
+ background-image:url(resources/titlebar.gif);
+ background-position:left top;
+ background-repeat:no-repeat;
+ color:#ffffff;
+ padding:8px;
+ width:5em;
+ font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ padding:.8em .5em .4em .8em;
+ height:auto;/*height:1.8em;*/
+ font-size:1em;
+ margin:0;
+}
+.topNav {
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.bottomNav {
+ margin-top:10px;
+ background-image:url(resources/background.gif);
+ background-repeat:repeat-x;
+ color:#FFFFFF;
+ float:left;
+ padding:0;
+ width:100%;
+ clear:right;
+ height:2.8em;
+ padding-top:10px;
+ overflow:hidden;
+}
+.subNav {
+ background-color:#dee3e9;
+ border-bottom:1px solid #9eadc0;
+ float:left;
+ width:100%;
+ overflow:hidden;
+}
+.subNav div {
+ clear:left;
+ float:left;
+ padding:0 0 5px 6px;
+}
+ul.navList, ul.subNavList {
+ float:left;
+ margin:0 25px 0 0;
+ padding:0;
+}
+ul.navList li{
+ list-style:none;
+ float:left;
+ padding:3px 6px;
+}
+ul.subNavList li{
+ list-style:none;
+ float:left;
+ font-size:90%;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+ color:#FFFFFF;
+ text-decoration:none;
+}
+.topNav a:hover, .bottomNav a:hover {
+ text-decoration:none;
+ color:#bb7a2a;
+}
+.navBarCell1Rev {
+ background-image:url(resources/tab.gif);
+ background-color:#a88834;
+ color:#FFFFFF;
+ margin: auto 5px;
+ border:1px solid #c9aa44;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+ clear:both;
+ margin:0 20px;
+ padding:5px 0 0 0;
+}
+.indexHeader {
+ margin:10px;
+ position:relative;
+}
+.indexHeader h1 {
+ font-size:1.3em;
+}
+.title {
+ color:#2c4557;
+ margin:10px 0;
+}
+.subTitle {
+ margin:5px 0 0 0;
+}
+.header ul {
+ margin:0 0 25px 0;
+ padding:0;
+}
+.footer ul {
+ margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+ list-style:none;
+ font-size:1.2em;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+ background-color:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ margin:0 0 6px -8px;
+ padding:2px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+ padding:0;
+ margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+ padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+ clear:both;
+ padding:10px 20px;
+ position:relative;
+}
+.indexContainer {
+ margin:10px;
+ position:relative;
+ font-size:1.0em;
+}
+.indexContainer h2 {
+ font-size:1.1em;
+ padding:0 0 3px 0;
+}
+.indexContainer ul {
+ margin:0;
+ padding:0;
+}
+.indexContainer ul li {
+ list-style:none;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+ font-size:1.1em;
+ font-weight:bold;
+ margin:10px 0 0 0;
+ color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+ margin:10px 0 10px 20px;
+}
+.serializedFormContainer dl.nameValue dt {
+ margin-left:1px;
+ font-size:1.1em;
+ display:inline;
+ font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+ margin:0 0 0 1px;
+ font-size:1.1em;
+ display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+ display:inline;
+ font-size:0.9em;
+}
+ul.inheritance {
+ margin:0;
+ padding:0;
+}
+ul.inheritance li {
+ display:inline;
+ list-style:none;
+}
+ul.inheritance li ul.inheritance {
+ margin-left:15px;
+ padding-left:15px;
+ padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+ margin:10px 0 10px 0;
+ padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+ list-style:none;
+ margin-bottom:25px;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+ padding:0px 20px 5px 10px;
+ border:1px solid #9eadc0;
+ background-color:#f9f9f9;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+ padding:0 0 5px 8px;
+ background-color:#ffffff;
+ border:1px solid #9eadc0;
+ border-top:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+ margin-left:0;
+ padding-left:0;
+ padding-bottom:15px;
+ border:none;
+ border-bottom:1px solid #9eadc0;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+ list-style:none;
+ border-bottom:none;
+ padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+ margin-top:0;
+ margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.contentContainer table, .classUseContainer table, .constantValuesContainer table {
+ border-bottom:1px solid #9eadc0;
+ width:100%;
+}
+.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
+ width:100%;
+}
+.contentContainer .description table, .contentContainer .details table {
+ border-bottom:none;
+}
+.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
+ vertical-align:top;
+ padding-right:20px;
+}
+.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
+.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
+.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
+.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
+ padding-right:3px;
+}
+.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
+ position:relative;
+ text-align:left;
+ background-repeat:no-repeat;
+ color:#FFFFFF;
+ font-weight:bold;
+ clear:none;
+ overflow:hidden;
+ padding:0px;
+ margin:0px;
+}
+caption a:link, caption a:hover, caption a:active, caption a:visited {
+ color:#FFFFFF;
+}
+.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/titlebar.gif);
+ height:18px;
+}
+.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
+ width:10px;
+ background-image:url(resources/titlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+ul.blockList ul.blockList li.blockList table {
+ margin:0 0 12px 0px;
+ width:100%;
+}
+.tableSubHeadingColor {
+ background-color: #EEEEFF;
+}
+.altColor {
+ background-color:#eeeeef;
+}
+.rowColor {
+ background-color:#ffffff;
+}
+.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
+ background:#dee3e9;
+ border-top:1px solid #9eadc0;
+ border-bottom:1px solid #9eadc0;
+ text-align:left;
+ padding:3px 3px 3px 7px;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+ font-weight:bold;
+}
+td.colFirst, th.colFirst {
+ border-left:1px solid #9eadc0;
+ white-space:nowrap;
+}
+td.colLast, th.colLast {
+ border-right:1px solid #9eadc0;
+}
+td.colOne, th.colOne {
+ border-right:1px solid #9eadc0;
+ border-left:1px solid #9eadc0;
+}
+table.overviewSummary {
+ padding:0px;
+ margin-left:0px;
+}
+table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
+table.overviewSummary td.colOne, table.overviewSummary th.colOne {
+ width:25%;
+ vertical-align:middle;
+}
+table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
+ width:25%;
+ vertical-align:middle;
+}
+/*
+Content styles
+*/
+.description pre {
+ margin-top:0;
+}
+.deprecatedContent {
+ margin:0;
+ padding:10px 0;
+}
+.docSummary {
+ padding:0;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+ color:green;
+ padding:0 30px 0 0;
+}
+h1.hidden {
+ visibility:hidden;
+ overflow:hidden;
+ font-size:.9em;
+}
+.block {
+ display:block;
+ margin:3px 0 0 0;
+}
+.strong {
+ font-weight:bold;
+}
diff --git a/src/mpi/Band.java b/src/mpi/Band.java
new file mode 100644
index 0000000..3c32661
--- /dev/null
+++ b/src/mpi/Band.java
@@ -0,0 +1,37 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Band.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Band
+ extends Op {
+
+ Band() {
+ worker = new BandWorker();
+ this.opCode = mpjdev.Constants.BAND_CODE;
+ }
+}
diff --git a/src/mpi/BandByte.java b/src/mpi/BandByte.java
new file mode 100644
index 0000000..14f1c2c
--- /dev/null
+++ b/src/mpi/BandByte.java
@@ -0,0 +1,56 @@
+/* This file generated automatically from template BandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : BandByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BandByte extends Band {
+ byte [] arr = null;
+ BandByte() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (byte) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandChar.java b/src/mpi/BandChar.java
new file mode 100644
index 0000000..f066ded
--- /dev/null
+++ b/src/mpi/BandChar.java
@@ -0,0 +1,56 @@
+/* This file generated automatically from template BandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : BandChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BandChar extends Band {
+ char [] arr = null;
+ BandChar() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (char) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandInt.java b/src/mpi/BandInt.java
new file mode 100644
index 0000000..5ea5e53
--- /dev/null
+++ b/src/mpi/BandInt.java
@@ -0,0 +1,56 @@
+/* This file generated automatically from template BandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : BandInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BandInt extends Band {
+ int [] arr = null;
+ BandInt() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (int) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandLong.java b/src/mpi/BandLong.java
new file mode 100644
index 0000000..4451f24
--- /dev/null
+++ b/src/mpi/BandLong.java
@@ -0,0 +1,56 @@
+/* This file generated automatically from template BandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : BandLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BandLong extends Band {
+ long [] arr = null;
+ BandLong() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (long) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandShort.java b/src/mpi/BandShort.java
new file mode 100644
index 0000000..c9b19e0
--- /dev/null
+++ b/src/mpi/BandShort.java
@@ -0,0 +1,56 @@
+/* This file generated automatically from template BandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : BandShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BandShort extends Band {
+ short [] arr = null;
+ BandShort() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (short) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandType.java.in b/src/mpi/BandType.java.in
new file mode 100644
index 0000000..72a63c7
--- /dev/null
+++ b/src/mpi/BandType.java.in
@@ -0,0 +1,55 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : Band at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Band at Type@ extends Band {
+ @type@ [] arr = null;
+ Band at Type@() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = (@type@) (arr1[i] & arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count )
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BandWorker.java b/src/mpi/BandWorker.java
new file mode 100644
index 0000000..35a0f91
--- /dev/null
+++ b/src/mpi/BandWorker.java
@@ -0,0 +1,75 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : BandWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+public class BandWorker
+ implements OpWorker {
+ BandWorker() {}
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new BandByte();
+
+ case Datatype.CHAR:
+ return new BandChar();
+
+ case Datatype.SHORT:
+ return new BandShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.BAND is not valid for MPI.BOOLEAN" );
+
+ case Datatype.INT:
+ return new BandInt();
+
+ case Datatype.LONG:
+ return new BandLong();
+
+ case Datatype.FLOAT:
+ throw new MPIException("MPI.BAND is not valid for MPI.FLOAT" );
+
+ case Datatype.DOUBLE:
+ throw new MPIException("MPI.BAND is not valid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
+
diff --git a/src/mpi/BasicType.java b/src/mpi/BasicType.java
new file mode 100644
index 0000000..a1f9e50
--- /dev/null
+++ b/src/mpi/BasicType.java
@@ -0,0 +1,230 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BasicType.java
+ * Author : Sang Lim, Sung-Hoon Ko, Xinying Li, Bryan Carpenter,
+ * Aamir Shafi
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.13 $
+ * Updated : $Date: 2005/08/12 19:12:08 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer ;
+
+public class BasicType
+ extends Datatype {
+
+ int type;
+
+ BasicType(int type) {
+
+ // It is an error if type < 0 or type > Datatype.OBJECT.
+ // But since this constructor should not be called from user
+ // code we do not check for this condition.
+
+ this.type = type;
+
+ if (type == LB || type == UB) {
+ baseType = UNDEFINED;
+ size = 0;
+ byteSize = 0;
+ }
+ else {
+
+ baseType = type;
+
+ switch (type) {
+
+ case UNDEFINED:
+ size = 0;
+ byteSize = 0;
+ break;
+
+ case NULL:
+ size = 0;
+ byteSize = 0;
+ break;
+
+ case BYTE:
+ bufferType = mpjbuf.Type.BYTE;
+ byteSize = 1;
+ break;
+
+ case CHAR:
+ bufferType = mpjbuf.Type.CHAR;
+ byteSize = 2;
+ break;
+
+ case SHORT:
+ bufferType = mpjbuf.Type.SHORT;
+ byteSize = 2;
+ break;
+
+ case BOOLEAN:
+ bufferType = mpjbuf.Type.BOOLEAN;
+ byteSize = 1;
+ break;
+
+ case INT:
+ bufferType = mpjbuf.Type.INT;
+ byteSize = 4;
+ break;
+
+ case LONG:
+ bufferType = mpjbuf.Type.LONG;
+ byteSize = 8;
+ break;
+
+ case FLOAT:
+ bufferType = mpjbuf.Type.FLOAT;
+ byteSize = 4;
+ break;
+
+ case DOUBLE:
+ bufferType = mpjbuf.Type.DOUBLE;
+ byteSize = 8;
+ break;
+
+ case PACKED: //is this right ?
+
+ size = 0;
+ byteSize = 0;
+ break;
+
+ case OBJECT: //remember, object type is not copied onto static buffer.
+ bufferType = mpjbuf.Type.OBJECT;
+ size = 0;
+ byteSize = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ size = 1;
+ }
+
+ computeBounds();
+
+ }
+
+ private void computeBounds() {
+
+ // Compute `ub' and `lb', which define the `extent' of the new type.
+ // Also defines `ubSet', `lbSet' for this type.
+
+ switch (type) {
+ case LB:
+ lb = 0;
+ ub = 0;
+ lbSet = true;
+ ubSet = false;
+
+ break;
+
+ case UB:
+ lb = 0;
+ ub = 0;
+ lbSet = false;
+ ubSet = true;
+
+ break;
+
+ default: // **** what about PACKED? ****
+
+ lb = 0;
+ ub = 1;
+ lbSet = false;
+ ubSet = false;
+
+ break;
+ }
+
+ extent = ub - lb;
+ }
+
+ mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer, int messageSize) {
+ return new mpjbuf.Buffer(new NIOBuffer(messageSize, slicedBuffer),
+ MPI.BSEND_OVERHEAD, messageSize );
+ }
+
+ mpjbuf.Buffer createWriteBuffer(int count) throws MPIException {
+ int capacity = packedSize(count) + MPI.SEND_OVERHEAD ;
+ int offset = MPI.SEND_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer (rawBuffer, offset, capacity) ;
+
+ try {
+ wBuffer.putSectionHeader(this.bufferType); // need conversion
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return wBuffer;
+ }
+
+ mpjbuf.Buffer createReadBuffer(int count) {
+
+ int capacity = packedSize(count) + MPI.RECV_OVERHEAD ;
+ int offset = MPI.RECV_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer mpjbuf = new mpjbuf.Buffer(rawBuffer, offset, capacity) ;
+ return mpjbuf;
+
+ }
+
+
+ int packedSize(int count) {
+ int dataSize = count * byteSize;
+ int totalSize = 0;
+ int sectionHeader = 8; //what about multiple sections.
+ totalSize = sectionHeader + dataSize;
+ int padding = 0;
+
+ if (totalSize % 8 != 0)
+ padding = totalSize % 8;
+
+ return totalSize + padding;
+ }
+
+ void setPacker() {
+ packer = SimplePackerFactory.create(1, baseType);
+ }
+
+}
+
+// Things to do:
+//
+
diff --git a/src/mpi/Bor.java b/src/mpi/Bor.java
new file mode 100644
index 0000000..e92c3e8
--- /dev/null
+++ b/src/mpi/Bor.java
@@ -0,0 +1,49 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Bor.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Bor extends Op {
+
+ Bor() {
+ worker = new BorWorker();
+ this.opCode = mpjdev.Constants.BOR_CODE;
+ }
+}
diff --git a/src/mpi/BorByte.java b/src/mpi/BorByte.java
new file mode 100644
index 0000000..8c78bfc
--- /dev/null
+++ b/src/mpi/BorByte.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template BorType.java.in. */
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BorByte extends Bor {
+ byte [] arr = null;
+ BorByte() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (byte) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorChar.java b/src/mpi/BorChar.java
new file mode 100644
index 0000000..4ab55d6
--- /dev/null
+++ b/src/mpi/BorChar.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template BorType.java.in. */
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BorChar extends Bor {
+ char [] arr = null;
+ BorChar() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (char) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorInt.java b/src/mpi/BorInt.java
new file mode 100644
index 0000000..a6db80e
--- /dev/null
+++ b/src/mpi/BorInt.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template BorType.java.in. */
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BorInt extends Bor {
+ int [] arr = null;
+ BorInt() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (int) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorLong.java b/src/mpi/BorLong.java
new file mode 100644
index 0000000..d54e6a3
--- /dev/null
+++ b/src/mpi/BorLong.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template BorType.java.in. */
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BorLong extends Bor {
+ long [] arr = null;
+ BorLong() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (long) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorShort.java b/src/mpi/BorShort.java
new file mode 100644
index 0000000..b9eca16
--- /dev/null
+++ b/src/mpi/BorShort.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template BorType.java.in. */
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BorShort extends Bor {
+ short [] arr = null;
+ BorShort() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (short) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorType.java.in b/src/mpi/BorType.java.in
new file mode 100644
index 0000000..dd12a9e
--- /dev/null
+++ b/src/mpi/BorType.java.in
@@ -0,0 +1,69 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Bor at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Bor at Type@ extends Bor {
+ @type@ [] arr = null;
+ Bor at Type@() {
+ }
+
+ void perform (Object buf1, Object buf2, int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (@type@) (arr1[i] | arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/BorWorker.java b/src/mpi/BorWorker.java
new file mode 100644
index 0000000..d4745e8
--- /dev/null
+++ b/src/mpi/BorWorker.java
@@ -0,0 +1,80 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BorWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class BorWorker
+ implements OpWorker {
+
+ BorWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new BorByte();
+
+ case Datatype.CHAR:
+ return new BorChar();
+
+ case Datatype.SHORT:
+ return new BorShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.BOR is not valid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new BorInt();
+
+ case Datatype.LONG:
+ return new BorLong();
+
+ case Datatype.FLOAT:
+ throw new MPIException("MPI.BOR is not valid for MPI.FLOAT");
+
+ case Datatype.DOUBLE:
+ throw new MPIException("MPI.BOR is not valid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
+
diff --git a/src/mpi/Bxor.java b/src/mpi/Bxor.java
new file mode 100644
index 0000000..63fdd01
--- /dev/null
+++ b/src/mpi/Bxor.java
@@ -0,0 +1,48 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Bxor.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Bxor extends Op {
+
+ Bxor() {
+ worker = new BxorWorker();
+ this.opCode = mpjdev.Constants.BXOR_CODE;
+ }
+}
diff --git a/src/mpi/BxorByte.java b/src/mpi/BxorByte.java
new file mode 100644
index 0000000..3e51387
--- /dev/null
+++ b/src/mpi/BxorByte.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template BxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BxorByte extends Bxor {
+ byte [] arr = null;
+ BxorByte() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (byte) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorChar.java b/src/mpi/BxorChar.java
new file mode 100644
index 0000000..85e4e4b
--- /dev/null
+++ b/src/mpi/BxorChar.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template BxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BxorChar extends Bxor {
+ char [] arr = null;
+ BxorChar() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (char) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorInt.java b/src/mpi/BxorInt.java
new file mode 100644
index 0000000..4d8fd74
--- /dev/null
+++ b/src/mpi/BxorInt.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template BxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BxorInt extends Bxor {
+ int [] arr = null;
+ BxorInt() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (int) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorLong.java b/src/mpi/BxorLong.java
new file mode 100644
index 0000000..36e7dac
--- /dev/null
+++ b/src/mpi/BxorLong.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template BxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BxorLong extends Bxor {
+ long [] arr = null;
+ BxorLong() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (long) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorShort.java b/src/mpi/BxorShort.java
new file mode 100644
index 0000000..fcf30f8
--- /dev/null
+++ b/src/mpi/BxorShort.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template BxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class BxorShort extends Bxor {
+ short [] arr = null;
+ BxorShort() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (short) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorType.java.in b/src/mpi/BxorType.java.in
new file mode 100644
index 0000000..24a7fef
--- /dev/null
+++ b/src/mpi/BxorType.java.in
@@ -0,0 +1,68 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Bxor at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Bxor at Type@ extends Bxor {
+ @type@ [] arr = null;
+ Bxor at Type@() {
+ }
+
+ void perform(Object buf1, Object buf2, int count) throws MPIException {
+
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (@type@) (arr1[i] ^ arr[i]);
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/BxorWorker.java b/src/mpi/BxorWorker.java
new file mode 100644
index 0000000..0953ed8
--- /dev/null
+++ b/src/mpi/BxorWorker.java
@@ -0,0 +1,79 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BxorWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class BxorWorker
+ implements OpWorker {
+
+ BxorWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new BxorByte();
+
+ case Datatype.CHAR:
+ return new BxorChar();
+
+ case Datatype.SHORT:
+ return new BxorShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.BXOR is not valid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new BxorInt();
+
+ case Datatype.LONG:
+ return new BxorLong();
+
+ case Datatype.FLOAT:
+ throw new MPIException("MPI.BXOR is not valid for MPI.FLOAT");
+
+ case Datatype.DOUBLE:
+ throw new MPIException("MPI.BXOR is not valid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/CartParms.java b/src/mpi/CartParms.java
new file mode 100755
index 0000000..0175323
--- /dev/null
+++ b/src/mpi/CartParms.java
@@ -0,0 +1,52 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : CartParms.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+public class CartParms {
+
+ CartParms() {
+ }
+
+ public int[] dims;
+ public boolean[] periods;
+ public int[] coords; //coords[0] is x-axis, coords[1] is y-axis
+
+ //shouldn't it just be x and y ?
+ //public int x;
+ //public int y;
+}
+
diff --git a/src/mpi/Cartcomm.java b/src/mpi/Cartcomm.java
new file mode 100755
index 0000000..1eb93d2
--- /dev/null
+++ b/src/mpi/Cartcomm.java
@@ -0,0 +1,595 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Cartcomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.11 $
+ * Updated : $Date: 2005/09/28 13:33:59 $
+ */
+
+package mpi;
+
+public class Cartcomm
+ extends Intracomm {
+ CartParms cartParms = null;
+
+ //so the index of this cartParms will be the rank of that process
+
+ Cartcomm(int[] dims, boolean[] periods, boolean reorder,
+ mpjdev.Comm mpjdevComm, mpjdev.Group group) throws MPIException {
+ super(mpjdevComm,group) ;
+
+ int rank = group.rank();
+
+ //this.mpjdevComm = mpjdevComm;
+ //this.group = new Group(group);
+
+ cartParms = new CartParms();
+
+ /*
+ * Bug: Using 'copying by reference' technique to store dims and
+ * periods array in cartParms object. This is detrimental because if
+ * the value of dims or periods array is changed later, it also
+ * changes the value of stored dims or periods array.
+ * Identified by: Andre Vehreschild
+ * Fixed: Wed Sep 28 12:30:16 GMT 2005
+ */
+ cartParms.dims = new int[dims.length];
+ System.arraycopy(dims,0,cartParms.dims,0,dims.length);
+ //cartParms.dims = dims;
+
+ cartParms.periods = new boolean[periods.length];
+ System.arraycopy(periods,0,cartParms.periods,0,cartParms.periods.length);
+ //cartParms.periods = periods;
+
+ try {
+ cartParms.coords = Coords(rank);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ */
+ public Object clone () throws MPIException {
+ return this.Create_cart(cartParms.dims, cartParms.periods, false);
+ }
+
+ /**
+ * Translate logical process coordinates to process rank.
+ * <p>
+ * <table>
+ * <tr><td><tt> coords </tt></td><td> Cartesian coordinates of a
+ * process </tr>
+ * <tr><td><em> returns: </em></td><td> rank of the specified process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_RANK</tt>.
+ */
+ public int Rank(int[] coords) throws MPIException {
+ int factor = 1;
+ int rank = 0;
+ int i = cartParms.dims.length - 1;
+ int d = i; //d is basically dims index ....
+ int c = i; //c is coords index ...
+ int ord = 0;
+ int dim = 0;
+
+ for (; i >= 0; --i, --c, --d) {
+ dim = (cartParms.dims[i] > 0) ? cartParms.dims[i] :
+ - (cartParms.dims[i]);
+ ord = coords[c];
+
+ if ( (ord < 0) || (ord >= dim)) {
+
+ if (dim > 0) {
+ System.out.println("Error ");
+ }
+
+ System.out.println("ord "+ord);
+ System.out.println("dim "+dim);
+
+ ord %= dim;
+
+ if (ord < 0) {
+ ord += dim;
+ }
+ }
+
+ rank += factor * ord;
+ factor *= dim;
+ }
+
+ return rank;
+ }
+
+ /**
+ * Translate process rank to logical process coordinates.
+ * <p>
+ * <table>
+ * <tr><td><tt> rank </tt></td><td> rank of a process </tr>
+ * <tr><td><em> returns: </em></td><td> Cartesian coordinates of the
+ * specified process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_COORDS</tt>.
+ */
+ public int[] Coords(int rank) throws MPIException {
+ int dim = 0;
+ int nprocs = group.Size();
+ int remprocs = nprocs;
+ int orank = rank; //just for debugging
+ int[] coords = new int[cartParms.dims.length];
+
+ for (int i = 0; i < cartParms.dims.length; ++i) {
+ /*
+ dim = (cartParms.dims[i] > 0) ? cartParms.dims[i] :
+ -(cartParms.dims[i]); */
+ dim = cartParms.dims[i];
+ remprocs /= dim;
+ coords[i] = rank / remprocs;
+ rank %= remprocs;
+ }
+
+ /* temp printing ...
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("rank[" + orank + "]=");
+ for (int i = 0; i < cartParms.dims.length; i++) {
+ buffer.append("<coords[" + i + "]=" + coords[i] + ">");
+ }
+ //System.out.println(buffer.toString());
+ temp printing ...*/
+
+ return coords;
+ }
+
+ /**
+ * Compute source and destination ranks for ``shift'' communication.
+ * <p>
+ * <table>
+ * <tr><td><tt> direction </tt></td><td> coordinate dimension of shift </tr>
+ * <tr><td><tt> disp </tt></td><td> displacement </tr>
+ * <tr><td><em> returns: </em></td><td> object containing ranks of source
+ * and destination processes </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_SHIFT</tt>.
+ */
+ public ShiftParms Shift(int direction, int disp) throws MPIException {
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" Shift method called with args");
+ MPI.logger.debug(" direction "+direction);
+ MPI.logger.debug(" disp "+disp);
+ }
+
+ ShiftParms sParms = new ShiftParms();
+ int factor = 0;
+ int thisdim = 0;
+ int thisperiod = 0;
+ int ord = 0;
+ int srcord = 0;
+ int destord = 0;
+ int i = 0;
+ int p = 0;
+ int rank_src = 0;
+ int rank_dst = 0;
+
+ ord = this.group.Rank();
+
+ /*
+ * Naive case ...
+ */
+ if (disp == 0) {
+ rank_src = ord;
+ rank_dst = ord;
+ sParms.rank_source = rank_src;
+ sParms.rank_dest = rank_dst;
+ return sParms;
+ }
+
+ /* this is MPICH cloning */
+ boolean periodic = cartParms.periods[direction] ;
+ //save position ..dont understand this ...
+ int saved_position = cartParms.coords[direction] ;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("saved_position "+saved_position);
+ }
+ int dest_position, source_position ;
+ dest_position = source_position = saved_position ;
+
+ //Shift for the destination ...
+ dest_position += disp ;
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("dest_position "+dest_position);
+ }
+
+ if(dest_position >= cartParms.dims[direction] ) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("dest_position is >= dims[dir]");
+ }
+ if ( periodic )
+ dest_position %= cartParms.dims[direction];
+ else
+ dest_position = -1;
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("dest_position "+dest_position);
+ }
+ }
+ else if(dest_position < 0) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("dest_position is < 0");
+ }
+ if ( periodic )
+ dest_position += cartParms.dims[direction];
+ else
+ dest_position = -1;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("dest_position "+dest_position);
+ }
+ }
+
+ cartParms.coords[direction] = dest_position ;
+
+ if(dest_position != -1) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("cartParms.coords[0]=" + cartParms.coords[0] );
+ MPI.logger.debug("cartParms.coords[1]=" + cartParms.coords[1] );
+ }
+ rank_dst = Rank(cartParms.coords);
+ }
+ else {
+ rank_dst = -1;
+ }
+
+ //Shift for the source ..
+ source_position -= disp;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("source_position "+source_position);
+ }
+
+ if ( source_position >= cartParms.dims[direction] ) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("source_position >= cartParms.coords ");
+ }
+ if ( periodic ) {
+ source_position %= cartParms.dims[direction];
+ }
+ else
+ source_position = -1;
+ }
+ else if ( source_position < 0 ) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("source_position < 0");
+ }
+ if ( periodic ) {
+ source_position += cartParms.dims[direction];
+ //source_position = (source_position*-1);
+ }
+ else
+ source_position = -1;
+ }
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("source_position "+source_position);
+ }
+ cartParms.coords[direction] = source_position;
+
+ if(source_position != -1) {
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("cartParms.coords[0]=" + cartParms.coords[0] );
+ MPI.logger.debug("cartParms.coords[1]=" + cartParms.coords[1] );
+ }
+
+ rank_src = Rank(cartParms.coords);
+ }
+ else {
+ rank_src = -1;
+ }
+
+
+ //Restore my position ..
+ cartParms.coords[direction] = saved_position ;
+
+ /* MPICH cloning finishes */
+/*
+ * LAM/MPI cloning ...
+ factor = this.group.Size(); //number of processses ..
+ p = 0; //index to dims array ...
+
+ for (i = 0; (i < cartParms.dims.length)
+ && (i <= cartParms.dims[i]); ++i, ++p) {
+
+ if(cartParms.periods[p] == false ) {
+ thisperiod = 0;
+ thisdim = cartParms.dims[p];
+ }else {
+ thisperiod = 1;
+ thisdim = - (cartParms.dims[p]);
+ }
+ // the above code should be able to replace the below code ..
+
+ //if ( (thisdim = cartParms.dims[p]) > 0) {
+ // thisperiod = 0;
+ //}
+ //else {
+ // thisperiod = 1;
+ // thisdim = -thisdim;
+ //}
+
+ ord %= factor;
+ factor /= thisdim;
+ }
+
+ ord /= factor;
+
+ srcord = ord - disp;
+ destord = ord + disp;
+
+ if ( ( (destord < 0 || destord >= thisdim)) && (! (thisperiod == 1))) {
+ System.out.println("setting rank_dst to -1");
+ rank_dst = -1; //actually MPI_PROC_NULL
+ }
+ else {
+ destord %= thisdim;
+ if (destord < 0) destord += thisdim;
+ rank_dst = this.group.Rank() + ( (destord - ord) * factor);
+ }
+
+ if ( ( (srcord < 0) || (srcord >= thisdim)) && (! (thisperiod == 1))) {
+ System.out.println("setting rank_src to -1");
+ rank_src = -1; //actually MPI_PROC_NULL;
+ }
+ else {
+ srcord %= thisdim;
+ if (srcord < 0) srcord += thisdim;
+ rank_src = this.group.Rank() + ( (srcord - ord) * factor);
+ }
+*/
+
+ sParms.rank_source = rank_src;
+ sParms.rank_dest = rank_dst;
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" end of shift ");
+ MPI.logger.debug(" rank_src "+rank_src);
+ MPI.logger.debug(" rank_dst "+rank_dst);
+ }
+
+ return sParms;
+ }
+
+ /**
+ * Partition Cartesian communicator into subgroups of lower dimension.
+ * <p>
+ * <table>
+ * <tr><td><tt> remain_dims </tt></td><td> by dimension, <tt>true</tt> if
+ * dimension is to be kept,
+ * <tt>false</tt> otherwise </tr>
+ * <tr><td><em> returns: </em></td><td> communicator containing subgrid
+ * including this process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_SUB</tt>.
+ */
+ public Cartcomm Sub(boolean[] remain_dims) throws MPIException {
+ int color = 0;
+ int key = 0;
+ int keyfactor = 1;
+ int colfactor = 1;
+
+ int ndim = 0;
+ int dim = 0;
+ int allfalse = 0;
+ int i = cartParms.dims.length - 1;
+
+ for (; i >= 0; --i) {
+ /*dim = ( cartParms.dims[i] > 0 ) ? cartParms.dims[i] :
+ (-cartParms.dims[i]);*/
+ dim = cartParms.dims[i];
+
+ if (remain_dims[i] == false) {
+ color += colfactor * cartParms.coords[i];
+ colfactor *= dim;
+ }
+ else {
+ ++ndim;
+ key += keyfactor * (cartParms.coords[i]);
+ keyfactor *= dim;
+ }
+ }
+
+ /* special case ...comm with just yourself 'this' process init */
+ if (ndim == 0) {
+ color = this.group.Rank();
+ ndim = 1;
+ allfalse = 1;
+ //MPICH makes a dup of MPI_COMM_SELF and returns it.
+ }
+
+ /* split the communicator */
+ Intracomm newcomm = this.Split(color, key);
+
+ /* fill the comm with topology information */
+ /* and compute the callers coordinate ... */
+ if (newcomm != null) {
+ //get total number of processes in this comm ...
+ int nprocs = newcomm.Size();
+ int[] ndimsArray = new int[ndim];
+ boolean[] nperiods = new boolean[ndim];
+ /*
+ if(nprocs != ndim) {
+ System.out.println("nprocs is not equal to ndim, ERROR");
+ System.out.println("nprocs "+nprocs);
+ System.out.println("ndim "+ndim);
+ }*/
+
+ int index = 0;
+
+ if(allfalse == 1 ) {
+ ndimsArray[0] = 1;
+ } else {
+ for (int l = 0; l < cartParms.dims.length; l++) {
+ if (remain_dims[l] == true) {
+ ndimsArray[index] = cartParms.dims[l];
+ nperiods[index] = cartParms.periods[l];
+ index++;
+ }
+ }
+ }
+
+ return newcomm.Create_cart(ndimsArray, nperiods, false);
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * Compute an optimal placement.
+ * <p>
+ * <table>
+ * <tr><td><tt> dims </tt></td><td> the number of processes in each
+ * dimension </tr>
+ * <tr><td><tt> periods </tt></td><td> <tt>true</tt> if grid is periodic,
+ * <tt>false</tt> if not, in each
+ * dimension </tr>
+ * <tr><td><em> returns: </em></td><td> reordered rank of calling
+ * process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_MAP</tt>.
+ * <p>
+ * The number of dimensions is taken to be size of the <tt>dims</tt> argument.
+ */
+ public int Map(int[] dims, boolean[] periods) throws MPIException {
+ int procs = 1;
+
+ for (int i = 0; i < dims.length; i++) {
+ if (dims[i] < 0) {
+ throw new MPIException(" Error in Cartcomm.Map: dims["+i+"] is "+
+ "less than zero" );
+ }
+ procs *= dims[i];
+ }
+
+ int size = this.group.Size();
+ int rank = this.group.Rank();
+
+ if (procs > size) {
+ throw new MPIException(" Error in Cartcomm.Map: procs <"+procs+"> is "+
+ "greater than size <"+size+">");
+ }
+
+ return ( (rank < 0) || (rank >= procs)) ? -1 : rank; //-1 should UNDEF ...
+ }
+
+ /**
+ * Returns Cartesian topology information.
+ * <p>
+ * <table>
+ * <tr><td><em> returns: </em></td><td> object containing dimensions,
+ * periods and local coordinates </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operations <tt>MPI_CARTDIM_GET</tt> and
+ * <tt>MPI_CART_GET</tt>.
+ * <p>
+ * The number of dimensions can be obtained from the size of (eg)
+ * <tt>dims</tt> field of the returned object.
+ */
+ public CartParms Get() throws MPIException {
+ return cartParms;
+ }
+
+ public int Topo_test() throws MPIException {
+ return MPI.CART; //this means no topology ....
+ }
+
+ /**
+ * Select a balanced distribution of processes per coordinate direction.
+ * <p>
+ * <table>
+ * <tr><td><tt> nnodes </tt></td><td> number of nodes in a grid </tr>
+ * <tr><td><tt> ndims </tt></td><td> number of dimensions of grid </tr>
+ * <tr><td><tt> dims </tt></td><td> array specifying the number of nodes
+ * in each dimension </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_DIMS_CREATE</tt>.
+ * <p>
+ * Size <tt>dims</tt> should be <tt>ndims</tt>. Note that
+ * <tt>dims</tt> is an <em>inout</em> parameter.
+ */
+ public static void Dims_create(int nnodes, int[] dims) throws MPIException {
+
+ //int size = 1 ;
+ int rank = dims.length ;
+
+ while(rank > 0) {
+
+ int ext = root(nnodes, rank) ;
+ rank-- ;
+ nnodes /= ext ;
+ dims [rank] = ext ;
+ //size *= ext ;
+ }
+ }
+
+ static int root(int n, int d) {
+
+ switch(d) {
+ case 1 :
+ return n ;
+ case 2 :
+ return (int) Math.sqrt(n) ;
+ default :
+ int ceiling = 1 ;
+ int power = 1 ;
+ while(power < n) {
+ ceiling++ ;
+ power = ceiling ;
+ for(int i = 1 ; i < d ; i++)
+ power *= ceiling ;
+ }
+ if(power == n)
+ return ceiling ;
+ else
+ return ceiling - 1 ;
+ }
+ }
+
+
+}
+
diff --git a/src/mpi/Comm.java b/src/mpi/Comm.java
new file mode 100755
index 0000000..73adaff
--- /dev/null
+++ b/src/mpi/Comm.java
@@ -0,0 +1,2469 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Comm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.60 $
+ * Updated : $Date: 2014/03/11 13:36:40 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+import java.util.Hashtable;
+import java.nio.ByteBuffer;
+
+public class Comm {
+
+ Hashtable attrTable = new Hashtable();
+ public mpi.Group group = null;
+ mpi.Group localgroup = null;
+ public mpjdev.Comm mpjdevComm = null;
+ boolean intercomm = false;
+ static final int NULL = 2;
+ int code = -1;
+
+ Comm() {
+ }
+
+ Comm(int code) {
+ this.code = code;
+ }
+
+ /**
+ * Size of group of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>number of processors in the group of this communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_SIZE</tt>.
+ */
+ public int Size() throws MPIException {
+ return (intercomm ? this.localgroup.Size() : this.group.Size());
+ }
+
+ /**
+ * Rank of this process in group of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>rank of the calling process in the group of this communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_RANK</tt>.
+ */
+ public int Rank() throws MPIException {
+ return (intercomm ? this.localgroup.Rank() : this.group.Rank());
+ }
+
+ /**
+ * Return group associated with a communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>group corresponding to this communicator group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_GROUP</tt>.
+ */
+ public Group Group() throws MPIException {
+ return (intercomm ? this.localgroup : this.group);
+ }
+
+ /**
+ * Compare two communicators.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> comm1 </tt></td>
+ * <td>first communicator
+ * </tr>
+ * <tr>
+ * <td><tt> comm2 </tt></td>
+ * <td>second communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>result
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ * <p>
+ * <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ * references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ * <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ * but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ * the underlying groups are similar but the communicators differ by context.
+ * <tt>MPI.UNEQUAL</tt>(2) results otherwise.
+ */
+
+ public static int Compare(Comm comm1, Comm comm2) throws MPIException {
+
+ if (Constants.isNative) {
+ // in case of native
+ return mpi.NativeIntracomm.Compare(comm1, comm2);
+ }
+
+ // put in a new condition check which produces an error messages if both
+ // the comms are not of the same type, i.e by type i mean intra/inter comms
+ if (!comm1.intercomm && !comm2.intercomm) {
+ // what about collective context ..?
+ int val = 0;
+ val = Group.Compare(comm1.group, comm2.group);
+
+ /*
+ * if the return val is IDENT ..then we need to compare the contexts ...if
+ * the contexts are equal ...then IDENT else CONGRUENT ...
+ */
+
+ if (val == MPI.IDENT) {
+ if (comm1.mpjdevComm.sendctxt == comm2.mpjdevComm.sendctxt) {
+ return MPI.IDENT;
+ } else {
+ return MPI.CONGRUENT;
+ }
+ }
+
+ /*
+ * if UNEQUAL, then just return MPI.UNEQ.. if SIMILAR ..then just return
+ * MPI.SIMILAR ..
+ */
+ return val;
+ } else {
+ int val1, val2;
+ val1 = Group.Compare(comm1.group, comm1.group);
+ val2 = Group.Compare(comm1.localgroup, comm1.localgroup);
+
+ if (val1 == MPI.IDENT && val2 == MPI.IDENT) {
+ if ((comm1.mpjdevComm.sendctxt == comm2.mpjdevComm.sendctxt)
+ && (comm1.mpjdevComm.recvctxt == comm2.mpjdevComm.recvctxt)) {
+ return MPI.IDENT;
+ } else {
+ return MPI.CONGRUENT;
+ }
+
+ } else if (val1 == val2) {
+ return val1;
+ } else if (val1 == MPI.SIMILAR && val2 == MPI.SIMILAR) {
+ return MPI.SIMILAR;
+ }
+
+ return MPI.UNEQUAL;
+ }
+ }
+
+ /**
+ * Destroy this communicator.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_FREE</tt>.
+ */
+ public void Free() throws MPIException {
+ }
+
+ /**
+ * Test if this communicator is an inter-communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td> <tt>true</tt> if this is an inter-communicator, <tt>false</tt>
+ * otherwise
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_TEST_INTER</tt>.
+ */
+ public boolean Test_inter() throws MPIException {
+ return intercomm;
+ }
+
+ /**
+ * Create an inter-communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> local_comm </tt></td>
+ * <td>local intra-communicator
+ * </tr>
+ * <tr>
+ * <td><tt> local_leader </tt></td>
+ * <td>rank of local group leader in <tt>localComm</tt>
+ * </tr>
+ * <tr>
+ * <td><tt> remote_leader </tt></td>
+ * <td>rank of remote group leader in this communictor
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>``safe'' tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new inter-communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_INTERCOMM_CREATE</tt>.
+ * <p>
+ * (This operation is defined as a method on the ``peer communicator'', making
+ * it analogous to a <tt>send</tt> or <tt>recv</tt> communication with the
+ * remote group leader.)
+ */
+ public Intercomm Create_intercomm(mpi.Comm local_comm, int local_leader,
+ int remote_leader, int tag) throws MPIException {
+
+ if (local_comm.Rank() == -1) {
+ throw new MPIException(" Error in Create_intercomm: " + " rank <"
+ + local_comm.Rank() + "> is -1");
+ }
+
+ mpjdev.Comm newIntercomm = null;
+
+ try {
+ newIntercomm = mpjdevComm.create(local_comm.mpjdevComm,
+ this.group.mpjdevGroup, local_leader, remote_leader, tag);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return new Intercomm(newIntercomm, newIntercomm.localgroup,
+ newIntercomm.group, this, local_leader, remote_leader, local_comm);
+ }
+
+ /**
+ * Retrieves attribute value by key.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> keyval </tt></td>
+ * <td>one of the key values predefined by the implementation
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>attribute value
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ATTR_GET</tt>.
+ */
+ public Object Attr_get(int keyval) throws MPIException {
+ Object value = attrTable.get(new Integer(keyval));
+
+ if (value != null) {
+ return value;
+ } else {
+ throw new MPIException(" Error in Attr_get: No corresponding value "
+ + "to key <" + keyval + ">");
+ }
+
+ }
+
+ /**
+ * Retrieves attribute value by key.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> keyval </tt></td>
+ * <td>one of the key values predefined by the implementation
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>attribute value
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ATTR_GET</tt>.
+ */
+ public void Attr_delete(int keyval) throws MPIException {
+ try {
+ attrTable.remove(new Integer(keyval));
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Attribute put method which can be used to add attributed to this
+ * communicator ... find out why is it not part of API? and if it should be
+ * part of it?
+ */
+ void Attr_put(int key, int val) throws MPIException {
+ try {
+ attrTable.put(new Integer(key), new Integer(val));
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Blocking send operation.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SEND</tt>.
+ * <p>
+ * The actual argument associated with <tt>buf</tt> must be one-dimensional
+ * array. The value <tt>offset</tt> is a subscript in this array, defining the
+ * position of the first item of the message.
+ * <p>
+ * If the <tt>datatype</tt> argument represents an MPI basic type, its value
+ * must agree with the element type of <tt>buf</tt>---either a primitive type
+ * or a reference (object) type. If the <tt>datatype</tt> argument represents
+ * an MPI derived type, its <em>base type</em> must agree with the element
+ * type of <tt>buf</tt>
+ */
+ public void Send(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ send(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected void send(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+ mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ try {
+ mpjbuf.commit();
+ mpjdevComm.send(mpjbuf, dest, tag, pt2pt);
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ return;
+ }
+
+ Packer packer = datatype.getPacker();
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+
+ try {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("count " + count);
+ MPI.logger.debug("offset" + offset);
+ MPI.logger.debug("buf"
+ + ((NIOBuffer) wBuffer.getStaticBuffer()).getBuffer());
+
+ }
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ mpjdevComm.send(wBuffer, dest, tag, pt2pt);
+ wBuffer.clear();
+ wBuffer.free(); // gadget memory leak fix?
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" destroying buffer ");
+ }
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Send in synchronous mode.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SSEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public void Ssend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ ssend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected void ssend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+ mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ try {
+ mpjbuf.commit();
+ mpjdevComm.ssend(mpjbuf, dest, tag, pt2pt);
+ mpjbuf.clear(); // bug-fix
+ mpjbuf.free(); // gadget memory leak fix?
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ return;
+ }
+
+ Packer packer = datatype.getPacker();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+
+ try {
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ mpjdevComm.ssend(wBuffer, dest, tag, pt2pt);
+ wBuffer.clear(); // bug-fix
+ wBuffer.free(); // gadget memory leak fix?
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" destroying buffer ");
+ }
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ /**
+ * Send in buffered mode.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BSEND</tt>.
+ * <p>
+ * This operation copies message into a buffer (mpi.Buffer) specified by
+ * MPI.Buffer_attach operation, and then sends using the standard mode of
+ * communication. Further comments as for <tt>Send</tt>.
+ */
+ public void Bsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ bsend(buf, offset, count, datatype, dest, tag, true);
+ }
+
+ protected void bsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ // in reality, this is not buffering the data ...
+ if (datatype.baseType == 9) {
+ mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ try {
+ mpjbuf.commit();
+ mpjdevComm.send(mpjbuf, dest, tag, pt2pt);
+ mpjbuf.clear(); // bug-fix
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ return;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Bsend--");
+ }
+
+ if (mpi.MPI.buffer == null) {
+ throw new MPIException(" Error in MPI.Bsend: "
+ + "No buffer has been attached ");
+ }
+
+ synchronized (mpi.MPI.buffer) {
+
+ // This follows the "model implementation" given in the MPI
+ // specification, quite literally.
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("calling clearFront ");
+ }
+ PendingMessage.clearFront();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" capacity " + mpi.MPI.buffer.capacity());
+ }
+ Packer packer = datatype.getPacker();
+ int messageSize = datatype.packedSize(count) + MPI.BSEND_OVERHEAD;
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("messageSize " + messageSize);
+ MPI.logger.debug("packer " + packer);
+ }
+
+ int ptr;
+
+ if (PendingMessage.tailPtr + messageSize <= mpi.MPI.buffer.capacity()) {
+ // Put after queue tail
+ ptr = PendingMessage.tailPtr;
+ } else {
+ // No space after queue tail. Try start of buffer.
+ if (messageSize <= PendingMessage.headPtr) {
+ ptr = 0;
+ // ptr = PendingMessage.headPtr - messageSize ;
+ } else {
+ throw new MPIException("Error in MPI.Bsend: "
+ + "No space left in buffer.");
+ }
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ ByteBuffer slicedBuffer = null;
+ MPI.buffer.position(ptr);
+ MPI.buffer.limit(messageSize);
+ slicedBuffer = MPI.buffer.slice();
+
+ mpjbuf.Buffer mpjbuf = datatype.createWriteBuffer(slicedBuffer,
+ messageSize);
+
+ try {
+ mpjbuf.putSectionHeader(datatype.bufferType);
+ packer.pack(mpjbuf, buf, offset, count);
+ mpjbuf.commit();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ PendingMessage pending = new PendingMessage();
+
+ try {
+ pending.request = new Request(
+ mpjdevComm.isend(mpjbuf, dest, tag, pt2pt));
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ pending.ptr = ptr;
+ pending.len = messageSize;
+ pending.mpjbuf = mpjbuf;
+
+ synchronized (MPI.pendingRequests) {
+ MPI.pendingRequests.add(pending.request);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("added pending " + pending.request + "to "
+ + MPI.pendingRequests);
+ }
+ }
+
+ PendingMessage.add(pending);
+
+ } // end synchronized ()()()
+
+ } // Bsend_finishes ...
+
+ // Unclear following class is very well factored...
+ static class PendingMessage {
+
+ static void add(PendingMessage pending) {
+ if (back != null) {
+ back.next = pending;
+ back = pending;
+ tailPtr += back.len;
+ } else {
+ front = pending;
+ back = pending;
+ tailPtr = pending.len;
+ pending.next = null;
+ // tailPtr = len ; (Original line)
+ }
+
+ queue_size++;
+
+ }
+
+ static void clearFront() {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" tailPtr " + tailPtr);
+ MPI.logger.debug(" headPtr " + headPtr);
+ }
+ PendingMessage pending = front;
+
+ while (pending != null) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("calling test on pending ");
+ if (pending.request.Test() != null) {
+ // pending.mpjbuf.free(); (breaking bsend!-aamir)a
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.pendingRequests.remove(pending.request);
+ MPI.logger.debug("removed pending " + pending.request + "from "
+ + MPI.pendingRequests);
+ MPI.logger.debug(" freeing the buffer related to this ");
+ }
+
+ pending = pending.next;
+
+ if (pending != null) {
+ tailPtr = pending.tailPtr;
+ } else {
+ tailPtr = 0;
+ front = null;
+ back = null;
+ headPtr = 0;
+ }
+ queue_size--;
+ } else {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("message is still pending ");
+ front = pending;
+ headPtr = front.ptr;
+ }
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" tailPtr " + tailPtr);
+ MPI.logger.debug(" headPtr " + headPtr);
+ }
+
+ // can't seem to understand why are we doing this? maybe the last two
+ // makes sense when this is the first pending message?
+ // front = null;
+ // back = null;
+ // headPtr = 0;
+ // tailPtr = 0;
+ }
+
+ mpi.Request request;
+ mpjbuf.Buffer mpjbuf;
+ int ptr, len;
+ PendingMessage next;
+
+ public static int queue_size = 0;
+
+ static int headPtr = 0, tailPtr = 0;
+ static PendingMessage front = null, back = null;
+
+ }
+
+ /**
+ * Send in ready mode.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_RSEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public void Rsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ rsend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected void rsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+ mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ try {
+ mpjbuf.commit();
+ mpjdevComm.send(mpjbuf, dest, tag, pt2pt);
+ mpjbuf.clear(); // bug-fix
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ return;
+ }
+
+ Packer packer = datatype.getPacker();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+
+ try {
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ mpjdevComm.send(wBuffer, dest, tag, pt2pt);
+ wBuffer.clear(); // bug-fix
+ wBuffer.free();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" destroying buffer ");
+ }
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Start a standard mode, nonblocking send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ISEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Request Isend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ return isend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected Request isend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+
+ final mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Request request = null;
+
+ try {
+ mpjbuf.commit();
+ request = mpjdevComm.isend(mpjbuf, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ });
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Isend finishes ....--" + tag);
+ }
+ return new mpi.Request(request);
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Isend--" + tag);
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ Packer packer = datatype.getPacker();
+ final mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+ // System.out.println (" creatingBuffer (isend) " + wBuffer );
+ mpjdev.Request request = null;
+ final int t = tag;
+ final int d = dest;
+
+ try {
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ request = mpjdevComm.isend(wBuffer, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("registering completion handler");
+ }
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("executing handler for tag <" + t + "> and ");
+ MPI.logger.debug(" and dest <" + d + ">");
+ }
+ try {
+ wBuffer.clear();
+ wBuffer.free();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" destroying buffer ");
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ // System.out.println (" destroying buffer (isend) " + wBuffer );
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("executed handler for tag <" + t + "> and ");
+ MPI.logger.debug(" and dest <" + d + ">");
+ }
+ }
+ });
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Isend finishes ....--" + tag);
+ return new mpi.Request(request);
+ }
+
+ /**
+ * Start a buffered mode, nonblocking send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_IBSEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Request Ibsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ return ibsend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected Request ibsend(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag, boolean pt2pt) throws MPIException {
+
+ /* this is MPI.PACKED case */
+ // really its not buffering the message! ...
+
+ if (datatype.baseType == 9) {
+
+ final mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Request request = null;
+
+ try {
+ mpjbuf.commit();
+ request = mpjdevComm.isend(mpjbuf, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ });
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Isend finishes ....--" + tag);
+ return new mpi.Request(request);
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Ibsend--");
+
+ if (mpi.MPI.buffer == null) {
+ throw new MPIException("Error:No buffer has been attached,"
+ + "can't use Bsend");
+ }
+
+ synchronized (mpi.MPI.buffer) {
+
+ // This follows the "model implementation" given in the MPI
+ // specification, quite literally.
+
+ PendingMessage.clearFront();
+
+ Packer packer = datatype.getPacker();
+ int messageSize = datatype.packedSize(count) + MPI.BSEND_OVERHEAD;
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("messageSize " + messageSize);
+ MPI.logger.debug("packer " + packer);
+ }
+
+ int ptr;
+
+ if (PendingMessage.tailPtr + messageSize <= mpi.MPI.buffer.capacity()) {
+
+ // Put after queue tail
+ ptr = PendingMessage.tailPtr;
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" message can fit into the buffer ");
+ MPI.logger.debug(" ptr " + ptr);
+ MPI.logger.debug(" PendingMessage.tailPtr " + PendingMessage.tailPtr);
+ }
+
+ } else {
+
+ // No space after queue tail. Try start of buffer.
+ // If this sufficient ..think of first message longer than total buffer
+ // size ..i guess it may not work!
+ if (messageSize <= PendingMessage.headPtr) {
+ ptr = 0;
+ } else {
+ throw new MPIException("No space left in buffer.");
+ }
+
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("Allocating buffer at offset " + ptr);
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ ByteBuffer slicedBuffer = null;
+ MPI.buffer.position(ptr);
+ MPI.buffer.limit(messageSize);
+ slicedBuffer = MPI.buffer.slice();
+
+ mpjbuf.Buffer mpjbuf = datatype.createWriteBuffer(slicedBuffer,
+ messageSize);
+
+ try {
+ mpjbuf.putSectionHeader(datatype.bufferType);
+ packer.pack(mpjbuf, buf, offset, count);
+ mpjbuf.commit();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ PendingMessage pending = new PendingMessage();
+
+ try {
+ pending.request = new Request(
+ mpjdevComm.isend(mpjbuf, dest, tag, pt2pt));
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ pending.ptr = ptr;
+ pending.len = messageSize;
+ pending.mpjbuf = mpjbuf;
+ synchronized (MPI.pendingRequests) {
+ MPI.pendingRequests.add(pending.request);
+ }
+
+ PendingMessage.add(pending);
+ // Request r = new Request() ;
+ // r.isNull = true ;
+ // return r;
+ return pending.request;
+
+ } // end synchronized ()()()
+
+ }
+
+ /**
+ * Start a synchronous mode, nonblocking send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ISSEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Request Issend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ return issend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected Request issend(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag, boolean pt2pt) throws MPIException {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Issend-- " + tag);
+ }
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+
+ final mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Request request = null;
+
+ try {
+ mpjbuf.commit();
+ request = mpjdevComm.issend(mpjbuf, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ });
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Isend finishes ....--" + tag);
+ }
+ return new mpi.Request(request);
+ }
+
+ Packer packer = datatype.getPacker();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" creatingBuffer ");
+ }
+ final mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+ // System.out.println("createdBuffer(issend) "+wBuffer);
+ mpjdev.Request request = null;
+
+ try {
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ request = mpjdevComm.issend(wBuffer, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ wBuffer.clear();
+ wBuffer.free();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" destroying buffer ");
+ // System.out.println("destroying buffer (issend) "+wBuffer );
+ }
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+ });
+
+ return new mpi.Request(request);
+
+ }
+
+ /**
+ * Start a ready mode, nonblocking send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_IRSEND</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Request Irsend(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag) throws MPIException {
+ try {
+ return irsend(buf, offset, count, datatype, dest, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected Request irsend(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag, boolean pt2pt) throws MPIException {
+ /* this is MPI.PACKED case */
+ if (datatype.baseType == 9) {
+
+ final mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Request request = null;
+
+ try {
+ mpjbuf.commit();
+ request = mpjdevComm.isend(mpjbuf, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ });
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Isend finishes ....--" + tag);
+ return new mpi.Request(request);
+ }
+
+ Packer packer = datatype.getPacker();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" creatingBuffer ");
+ final mpjbuf.Buffer wBuffer = datatype.createWriteBuffer(count);
+ mpjdev.Request request = null;
+
+ try {
+ packer.pack(wBuffer, buf, offset, count);
+ wBuffer.commit();
+ request = mpjdevComm.isend(wBuffer, dest, tag, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ try {
+ wBuffer.clear();
+ wBuffer.free();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" destroying buffer ");
+ BufferFactory.destroy(wBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+ });
+
+ return new mpi.Request(request);
+
+ }
+
+ /**
+ * Blocking receive operation.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_RECV</tt>.
+ * <p>
+ * The actual argument associated with <tt>buf</tt> must be one-dimensional
+ * array. The value <tt>offset</tt> is a subscript in this array, defining the
+ * position into which the first item of the incoming message will be copied.
+ * <p>
+ * If the <tt>datatype</tt> argument represents an MPI basic type, its value
+ * must agree with the element type of <tt>buf</tt>---either a primitive type
+ * or a reference (object) type. If the <tt>datatype</tt> argument represents
+ * an MPI derived type, its <em>base type</em> must agree with the element
+ * type of <tt>buf</tt>
+ */
+
+ public Status Recv(Object buf, int offset, int count, Datatype datatype,
+ int source, int tag) throws MPIException {
+ try {
+ return recv(buf, offset, count, datatype, source, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw new MPIException(mpie);
+ }
+ }
+
+ protected Status recv(Object buf, int offset, int count, Datatype datatype,
+ int source, int tag, boolean pt2pt) throws MPIException {
+
+ /* MPI.PACK will have to be re-done */
+ if (datatype.baseType == 9) {
+ mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Status status1 = null;
+ try {
+ status1 = mpjdevComm.recv(mpjbuf, source, tag, pt2pt);
+ mpjbuf.commit();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ mpi.Status st = new mpi.Status(status1);
+ // set status.count and status.elements to undefined?
+ return st;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Recv--" + tag);
+ }
+
+ mpjbuf.Buffer rBuffer = datatype.createReadBuffer(count);
+ Packer packer = datatype.getPacker();
+ mpjdev.Status status = null;
+ int count_received = 0;
+
+ try {
+ status = mpjdevComm.recv(rBuffer, source, tag, pt2pt);
+ rBuffer.commit();
+ // count_received = rBuffer.getSectionHeader(datatype.bufferType);
+ Type receivedType = rBuffer.getSectionHeader();
+ // may be a check to see if we type sent is equal to what the user
+ // is trying to access ..
+ count_received = rBuffer.getSectionSize();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("count_received " + count_received);
+ MPI.logger.debug("count " + count);
+ }
+ // System.out.println("recv: unpack : count_received = "+count_received+" count = "+count+" tag = "+tag
+ // );
+ packer.unpack(rBuffer, count_received, buf, offset, count);
+ rBuffer.clear();
+ rBuffer.free();
+ BufferFactory.destroy(rBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("exception " + e.getMessage());
+ MPI.logger.debug("count_received " + count_received);
+ MPI.logger.debug("count " + count);
+ }
+ throw new MPIException(e);
+ }
+
+ mpi.Status st = new mpi.Status(status);
+ // brute-forcing numEls/count vals for status.
+
+ st.numEls = count_received;
+
+ if (datatype.size != 0) {
+ int temp = st.numEls / datatype.size;
+ if (temp * datatype.size == st.numEls) {
+ st.count = temp;
+ } else {
+ st.count = MPI.UNDEFINED;
+ }
+ } else {
+ st.count = count;
+ st.numEls = MPI.UNDEFINED; // according to MPI specs, this should be
+ // zero, but we are trusting our test-cases
+ // which are passed by LAM, MPICH, and mpiJava
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Recv completed--" + tag);
+ }
+
+ return st;
+ }
+
+ /**
+ * Start a nonblocking receive.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_IRECV</tt>.
+ * <p>
+ * Further comments as for <tt>Recv</tt>.
+ */
+ public Request Irecv(Object buf, int offset, int count, Datatype datatype,
+ int src, int tag) throws MPIException {
+ try {
+ return irecv(buf, offset, count, datatype, src, tag, true);
+ }
+ catch (MPIException mpie) {
+ throw mpie;
+ }
+ }
+
+ protected Request irecv(Object buf, int offset, int count, Datatype datatype,
+ int src, int tag, boolean pt2pt) throws MPIException {
+
+ if (datatype.baseType == 9) {
+ final mpjbuf.Buffer mpjbuf = (mpjbuf.Buffer) buf;
+ mpjdev.Request mpjdevRequest = null;
+ mpjdev.Status status = new mpjdev.Status(src, tag, -1);
+
+ try {
+ mpjdevRequest = mpjdevComm.irecv(mpjbuf, src, tag, status, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ mpjdevRequest.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ /*
+ * not sure, but at this stage for MPI.PACK, it is not possible to
+ * know count and numEls. This will be known when we call MPI.Unpack(
+ * .. ) method.
+ *
+ * status.type .. ?
+ */
+ status.count = MPI.UNDEFINED;
+ status.numEls = MPI.UNDEFINED;
+ try {
+ mpjbuf.clear();
+ mpjbuf.free();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ });
+
+ // mpi.Status st = new mpi.Status(status1);
+ // set status.count and status.elements to undefined?
+ mpi.Request req = new mpi.Request(mpjdevRequest);
+ return req;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Irecv--" + tag);
+ }
+ /* these final variables don't look pretty here though :( */
+ final mpjbuf.Buffer rBuffer = datatype.createReadBuffer(count);
+ // System.out.println("createdBuffer (irecv)"+rBuffer+" src <"+src);
+ final Packer packer = datatype.getPacker();
+ final int c = count;
+ final Object buf1 = buf;
+ final int off = offset;
+ final int source = src;
+ final int t = tag;
+ final Datatype dtype = datatype;
+ mpjdev.Request request = null;
+ mpjdev.Status status = new mpjdev.Status(src, tag, -1);
+
+ try {
+ request = mpjdevComm.irecv(rBuffer, src, tag, status, pt2pt);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("executing handler for tag <" + t + "> and ");
+ MPI.logger.debug(" and src <" + source + ">");
+ }
+ int count_received = 0;
+ try {
+
+ rBuffer.commit();
+ // count_received = rBuffer.getSectionHeader(dtype.bufferType);
+ Type recType = rBuffer.getSectionHeader();
+
+ count_received = rBuffer.getSectionSize();
+
+ packer.unpack(rBuffer, count_received, buf1, off, c);
+ rBuffer.clear();
+ rBuffer.free();
+ // System.out.println("destroying buffer (irecv) "+rBuffer );
+ BufferFactory.destroy(rBuffer.getStaticBuffer());
+ }
+ catch (Exception e) {
+ System.out.println(" tag <" + t + ">");
+ // System.out.println("the buffer was "+rBuffer);
+ throw new MPIException(e);
+ }
+
+ status.numEls = count_received;
+
+ if (dtype.size != 0) {
+
+ int temp = status.numEls / dtype.size;
+
+ if (temp * dtype.size == status.numEls) {
+ status.count = temp;
+ } else {
+ status.count = MPI.UNDEFINED;
+ }
+ }
+
+ else {
+ status.count = c;
+ status.numEls = MPI.UNDEFINED;
+ // according to MPI specs, this should be
+ // zero, but we are trusting our test-cases
+ // which are passed by LAM, MPICH, and mpiJava
+ }
+
+ status.type = dtype.bufferType;
+
+ /*
+ * This loop is trying to find the matching receive FIXME: TODO: This
+ * loop shoud be moved to xdev level. Xdev has all of this information
+ * available with it. On the other side, native device (natmpjdev) would
+ * set the value of status in the C MPI library code. Basically status
+ * is passed as an argument to Irecv() and when this method returns, the
+ * value of source is set.
+ */
+ if (Constants.isNative == false) { // Is is only for javampjdev
+ for (int j = 0; j < mpjdevComm.group.ids.length; j++) {
+ if (mpjdevComm.group.ids[j].uuid().equals(status.srcID)) {
+ status.source = j;
+ break;
+ }
+ }
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("executed handler for tag <" + t + "> and ");
+ MPI.logger.debug(" and src <" + source + ">");
+ }
+ }
+ });
+
+ mpi.Request req = new mpi.Request(request);
+ req.datatype = datatype;
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Irecv Ends--" + tag);
+ }
+ return req;
+
+ }
+
+ /**
+ * Check if there is an incoming message matching the pattern specified.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object or null handle
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_IPROBE</tt>.
+ * <p>
+ * If such a message is currently available, a status object similar to the
+ * return value of a matching <tt>Recv</tt> operation is returned. Otherwise a
+ * null handle is returned.
+ */
+ public Status Iprobe(int source, int tag) throws MPIException {
+ mpjdev.Status mpjdevStatus = null;
+ mpi.Status status = null;
+ try {
+ mpjdevStatus = mpjdevComm.iprobe(source, tag);
+
+ if (mpjdevStatus == null) {
+ // || mpjdevStatus.type == null) { Probe does not necessarily
+ // knows the type ..it knows the type in niodev ..but not
+ // in mxdev ...
+ return null;
+ } else {
+ status = new Status(mpjdevStatus);
+ // System.out.println("mpjdevStatus.numEls = "+mpjdevStatus.numEls);
+ // for native mode this is zero
+ status.count = mpjdevStatus.numEls;
+ status.numEls = status.count;
+ // status.numEls = status.count * status.type.size ;
+ // status.numEls is the count of number of primitive-datatypes ...
+ return status;
+ }
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Wait until there is an incoming message matching the pattern specified.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_PROBE</tt>.
+ * <p>
+ * Returns a status object similar to the return value of a matching
+ * <tt>Recv</tt> operation.
+ */
+ public Status Probe(int source, int tag) throws MPIException {
+
+ mpjdev.Status mpjdevStatus = null;
+ mpi.Status status = null;
+ try {
+ mpjdevStatus = mpjdevComm.probe(source, tag);
+
+ if (mpjdevStatus == null) {
+ // || mpjdevStatus.type == null) {
+ return null;
+ } else {
+ status = new Status(mpjdevStatus);
+ status.count = mpjdevStatus.numEls;
+ status.numEls = mpjdevStatus.numEls;
+ // status.numEls = status.count * status.type.size ;
+ // status.numEls is 'number of primitive-elements'
+ return status;
+ }
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ /**
+ * Returns an upper bound on the increment of <tt>position</tt> effected by
+ * <tt>pack</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> incount </tt></td>
+ * <td>number of items in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in input buffer
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>upper bound on size of packed message
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_PACK_SIZE</tt>.
+ * <p>
+ * <em>It is an error to call this function if the base type of
+ * <tt>datatype</tt> is <tt>MPI.OBJECT</tt></em>.
+ */
+ public int Pack_size(int incount, Datatype datatype) throws MPIException {
+ return datatype.packedSize(incount);
+ }
+
+ /**
+ * Packs message in send buffer <tt>inbuf</tt> into space specified in
+ * <tt>outbuf</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> inbuf </tt></td>
+ * <td>input buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> incount </tt></td>
+ * <td>number of items in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> outbuf </tt></td>
+ * <td>output buffer
+ * </tr>
+ * <tr>
+ * <td><tt> position </tt></td>
+ * <td>initial position in output buffer
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>final position in output buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_PACK</tt>.
+ * <p>
+ * The return value is the output value of <tt>position</tt> - the inital
+ * value incremented by the number of bytes written.
+ */
+
+ public int Pack(Object inbuf, int offset, int incount, Datatype datatype,
+ mpjbuf.Buffer outbuf, int position) throws MPIException {
+
+ outbuf.setSize(position);
+ Packer packer = datatype.getPacker();
+ int messageSize = datatype.packedSize(incount);
+
+ try {
+ outbuf.putSectionHeader(datatype.bufferType);
+ packer.pack(outbuf, inbuf, offset, incount);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return outbuf.getSize();
+
+ }
+
+ /**
+ * Unpacks message in receive buffer <tt>outbuf</tt> into space specified in
+ * <tt>inbuf</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> inbuf </tt></td>
+ * <td>input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> position </tt></td>
+ * <td>initial position in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> outbuf </tt></td>
+ * <td>output buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in output buffer
+ * </tr>
+ * <tr>
+ * <td><tt> outcount </tt></td>
+ * <td>number of items in output buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in output buffer
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>final position in input buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_UNPACK</tt>.
+ * <p>
+ * The return value is the output value of <tt>position</tt> - the inital
+ * value incremented by the number of bytes read.
+ */
+ public int Unpack(mpjbuf.Buffer inbuf, int position, Object outbuf,
+ int offset, int outcount, Datatype datatype) throws MPIException {
+
+ int expectedSize = MPI.COMM_WORLD.Pack_size(outcount, datatype);
+ inbuf.setSize(expectedSize + position);
+
+ try {
+ Packer packer = datatype.getPacker();
+ // int count_received = inbuf.getSectionHeader(datatype.bufferType);
+ Type recType = inbuf.getSectionHeader();
+ int count_received = inbuf.getSectionSize();
+ packer.unpack(inbuf, count_received, outbuf, offset, outcount);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return inbuf.getSize();
+
+ }
+
+ /**
+ * Creates a persistent communication request for a buffered mode send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>persistent communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BSEND_INIT</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Prequest Bsend_init(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag) throws MPIException {
+ Prequest preq = new Prequest(buf, offset, count, datatype, dest, tag,
+ MPI.OP_BSEND, this);
+ return preq;
+ }
+
+ /**
+ * Creates a persistent communication request for a standard mode send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>persistent communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SEND_INIT</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Prequest Send_init(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag) throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("-- Send_init --");
+ MPI.logger.debug("buf " + buf);
+ MPI.logger.debug("offset " + offset);
+ MPI.logger.debug(" count" + count);
+ MPI.logger.debug(" datatype " + datatype);
+ MPI.logger.debug(" dest " + dest);
+ MPI.logger.debug(" tag " + tag);
+ MPI.logger.debug("MPI.OP_SEND " + MPI.OP_SEND);
+ MPI.logger.debug(" this " + this);
+ }
+
+ Prequest preq = new Prequest(buf, offset, count, datatype, dest, tag,
+ MPI.OP_SEND, this);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("-- Send_init ends --");
+ }
+ return preq;
+ }
+
+ /**
+ * Creates a persistent communication request for a synchronous mode send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>persistent communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SSEND_INIT</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Prequest Ssend_init(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag) throws MPIException {
+ Prequest preq = new Prequest(buf, offset, count, datatype, dest, tag,
+ MPI.OP_SSEND, this);
+ return preq;
+ }
+
+ /**
+ * Creates a persistent communication request for a ready mode send.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>persistent communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_RSEND_INIT</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt>.
+ */
+ public Prequest Rsend_init(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag) throws MPIException {
+ Prequest preq = new Prequest(buf, offset, count, datatype, dest, tag,
+ MPI.OP_RSEND, this);
+ return preq;
+ }
+
+ /**
+ * Creates a persistent communication request for a receive operation.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> tag </tt></td>
+ * <td>message tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>communication request
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_RECV_INIT</tt>.
+ * <p>
+ * Further comments as for <tt>Recv</tt>.
+ */
+ public Prequest Recv_init(Object buf, int offset, int count,
+ Datatype datatype, int dest, int tag) throws MPIException {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("-- Recv_init --");
+ MPI.logger.debug(" buf " + buf);
+ MPI.logger.debug(" offset " + offset);
+ MPI.logger.debug(" count" + count);
+ MPI.logger.debug(" datatype " + datatype);
+ MPI.logger.debug(" dest " + dest);
+ MPI.logger.debug(" tag " + tag);
+ MPI.logger.debug(" MPI.OP_RECV " + MPI.OP_RECV);
+ MPI.logger.debug(" this " + this);
+ }
+
+ Prequest preq = new Prequest(buf, offset, count, datatype, dest, tag,
+ MPI.OP_RECV, this);
+
+ return preq;
+ }
+
+ /**
+ * Execute a blocking send and receive operation.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> sendtag </tt></td>
+ * <td>send tag
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> recvtag </tt></td>
+ * <td>receive tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SENDRECV</tt>.
+ * <p>
+ * Further comments as for <tt>Send</tt> and <tt>Recv</tt>.
+ */
+ public Status Sendrecv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, int dest, int sendtag, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int source, int recvtag)
+ throws MPIException {
+ /*
+ * Request request = Isend(sendbuf, sendoffset, sendcount, sendtype, dest,
+ * sendtag); Status status = Recv(recvbuf, recvoffset, recvcount, recvtype,
+ * source, recvtag); request.Wait(); return status;
+ */
+ /*
+ * final Object rbuf = recvbuf ; final int roffset = recvoffset ; final int
+ * rcount = recvcount ; final Datatype rtype = recvtype ; final int s =
+ * source ; final int rtag = recvtag ;
+ *
+ * Thread threadA = null ; Thread threadB = null;
+ *
+ * Request request = Isend(sendbuf, sendoffset, sendcount, sendtype, dest,
+ * sendtag);
+ *
+ * Runnable senderThreadB = new Runnable() { public void run() { Status
+ * status = Recv(rbuf, roffset, rcount, rtype, s, rtag); } };
+ *
+ * threadB = new Thread(senderThreadB); threadB.start(); request.Wait() ;
+ *
+ * try { threadB.join(); } catch(Exception e) { e.printStackTrace() ; }
+ *
+ * return new Status() ;
+ */
+
+ Status status = null;
+ Request recvRequest = null;
+ Request request = null;
+
+ recvRequest = Irecv(recvbuf, recvoffset, recvcount, recvtype, source,
+ recvtag);
+
+ request = Isend(sendbuf, sendoffset, sendcount, sendtype, dest, sendtag);
+
+ status = recvRequest.Wait();
+
+ request.Wait();
+
+ return status;
+
+ }
+
+ /**
+ * Execute a blocking send and receive operation, receiving message into send
+ * buffer.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> type </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> dest </tt></td>
+ * <td>rank of destination
+ * </tr>
+ * <tr>
+ * <td><tt> sendtag </tt></td>
+ * <td>send tag
+ * </tr>
+ * <tr>
+ * <td><tt> source </tt></td>
+ * <td>rank of source
+ * </tr>
+ * <tr>
+ * <td><tt> recvtag </tt></td>
+ * <td>receive tag
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Further comments as for <tt>Send</tt> and <tt>Recv</tt>.
+ */
+ public Status Sendrecv_replace(Object buf, int offset, int count,
+ Datatype datatype, int dest, int sendtag, int source, int recvtag)
+ throws MPIException {
+ Request request = Isend(buf, offset, count, datatype, dest, sendtag);
+ Status status = Recv(buf, offset, count, datatype, source, recvtag);
+ request.Wait();
+ return status;
+ }
+
+ protected Status sendrecv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, int dest, int sendtag, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int source, int recvtag)
+ throws MPIException {
+ Request recvRequest = Irecv(recvbuf, recvoffset, recvcount, recvtype,
+ source, recvtag);
+ Request request = Isend(sendbuf, sendoffset, sendcount, sendtype, dest,
+ sendtag);
+ request.Wait();
+ Status status = recvRequest.Wait();
+ return status;
+ }
+
+ /**
+ * Returns the type of topology associated with the communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>topology type of communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TOPO_TEST</tt>.
+ * <p>
+ * The return value will be one of <tt>MPI.GRAPH</tt>, <tt>MPI.CART</tt> or
+ * <tt>MPI.UNDEFINED</tt>.
+ */
+ public int Topo_test() throws MPIException {
+ // -1 represents no topology ...
+ return -1;
+ }
+
+ /**
+ * Abort MPI.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> errorcode </tt></td>
+ * <td>error code for Unix or POSIX environments
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ABORT</tt>.
+ */
+ public void Abort(int errorcode) throws MPIException {
+ }
+
+ /**
+ * Duplicate this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>copy of this communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_DUP</tt>.
+ * <p>
+ * The new communicator is ``congruent'' to the old one, but has a different
+ * context.
+ */
+ public Object clone() throws MPIException {
+ return this;
+ // this method is over-written in both Intracomm/Intercomm
+ }
+
+}
diff --git a/src/mpi/Contiguous.java b/src/mpi/Contiguous.java
new file mode 100644
index 0000000..8c76104
--- /dev/null
+++ b/src/mpi/Contiguous.java
@@ -0,0 +1,241 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2007)
+ 4. Bryan Carpenter (2005 - 2007)
+ 5. Mark Baker (2005 - 2007)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Contiguous.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.14 $
+ * Updated : $Date: 2005/08/12 19:12:08 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer ;
+
+/**
+ * Subclass of `Datatype' representing a derived datatype created using
+ * `Contiguous()'.
+ */
+public class Contiguous
+ extends Datatype {
+
+ private int count, oldSize;
+ private Datatype oldType;
+
+ Contiguous(int count, Datatype oldType) throws MPIException {
+ bufferType = oldType.bufferType;
+
+ if (count < 0) {
+ throw new MPIException(
+ "Count argument of Contiguous must be non-negative");
+ }
+
+ this.oldType = oldType;
+ this.count = count;
+ baseType = oldType.baseType;
+ this.oldSize = oldType.Size();
+ size = count * this.oldSize;
+ byteSize = count * oldType.byteSize;
+ computeBounds();
+
+ }
+
+ private void computeBounds() {
+
+ // Compute `ub' and `lb', which define the `extent' of the new type.
+ // Also defines `ubSet', `lbSet' for this type.
+ int oldExtent; //aamir
+
+ ubSet = count > 0 && oldType.ubSet;
+ lbSet = count > 0 && oldType.lbSet;
+
+ lb = Integer.MAX_VALUE;
+ ub = Integer.MIN_VALUE;
+ extent = 0; // Follow MPICH in defining extent to be zero if
+ // bounds are undefined (i.e. empty type).
+ //if the oldtype is MPI.LB & MPI.UB, extent is zero.
+ //so, is this right ?
+
+ if (oldSize != 0 || oldType.lbSet || oldType.ubSet) {
+
+ // `oldType.ub', `oldType.lb', `oldType.extent' all well-defined.
+
+ if (count > 0) {
+
+ // Assume all extents are non-negative.
+ oldExtent = oldType.extent;
+ extent = count * oldExtent;
+ lb = oldType.lb;
+ ub = lb + extent;
+
+ /* Following "correct" according to standard, but
+ apparently disagrees with MPICH.
+
+ if(oldExtent > 0) {
+ lb = oldType.lb ;
+ ub = (count - 1) * oldExtent + oldType.ub ;
+ }
+ else {
+ lb = (count - 1) * oldExtent + oldType.lb ;
+ ub = oldType.ub ;
+ }
+
+ extent = ub - lb ;
+ */
+ }
+ }
+ }
+
+ mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer, int messageSize) {
+ return new mpjbuf.Buffer(new NIOBuffer( messageSize, slicedBuffer ),
+ MPI.BSEND_OVERHEAD , messageSize );
+ }
+
+ mpjbuf.Buffer createWriteBuffer(int count) throws MPIException {
+ int capacity = packedSize(count) + MPI.SEND_OVERHEAD ;
+ int offset = MPI.SEND_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer(rawBuffer, offset, capacity) ;
+
+ try {
+ wBuffer.putSectionHeader(this.bufferType); // need conversion
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return wBuffer;
+ }
+
+ mpjbuf.Buffer createReadBuffer(int count) {
+ int capacity = packedSize(count) + MPI.RECV_OVERHEAD ;
+ int offset = MPI.RECV_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer mpjbuf = new mpjbuf.Buffer(rawBuffer, offset, capacity) ;
+ return mpjbuf;
+ }
+
+ int packedSize(int count) {
+ int dataSize = count * byteSize;
+ int totalSize = 0;
+ int sectionHeader = 8; //what about multiple sections.
+ totalSize = sectionHeader + dataSize;
+ int padding = 0;
+
+ if (totalSize % 8 != 0)
+ padding = totalSize % 8;
+
+ return totalSize + padding;
+ }
+
+ void setPacker() {
+
+ Packer oldPacker = oldType.getPacker(); //giving it els to avoid errors.
+
+ if (oldPacker instanceof SimplePacker) {
+ int oldCount = ( (SimplePacker) oldPacker).numEls; //(aamir)
+ int newCount = count * oldCount;
+ packer = SimplePackerFactory.create(newCount, baseType);
+ }
+ else if (oldPacker instanceof MultistridedPacker) {
+ MultistridedPacker multiOldPacker = (MultistridedPacker) oldPacker;
+ int oldRank = multiOldPacker.rank; //(rank)
+ int[] oldIndexes = multiOldPacker.indexes; //indexes(aamir)
+ int oldExtent = multiOldPacker.rank; //extents is an array (aamir)
+
+ int rank = oldRank + 1;
+ int[] indexes = new int[2 * rank];
+ for (int i = 0; i < oldRank; i++)
+ indexes[i] = oldIndexes[i];
+ indexes[oldRank] = count;
+ for (int i = 0; i < oldRank; i++)
+ indexes[rank + i] = oldIndexes[oldRank + i];
+ indexes[rank + oldRank] = oldExtent;
+
+ packer = MultistridedPackerFactory.create(rank, indexes,
+ extent, size,
+ baseType);
+ }
+ else {
+ packer = new ContiguousPacker(count, oldType);
+ }
+ }
+
+ private class ContiguousPacker
+ extends GenericPacker {
+
+ Packer itemPacker;
+ int itemLen, itemSize;
+
+ ContiguousPacker(int count, Datatype oldType) {
+ super(Contiguous.this.extent, Contiguous.this.size);
+ this.itemPacker = oldType.getPacker();
+ this.itemLen = oldType.extent;
+ this.itemSize = oldType.size;
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ for (int i = 0; i < count; i++) {
+ itemPacker.pack(mpjbuf, buf, offset);
+ offset += itemLen;
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ for (int i = 0; i < count; i++) {
+ itemPacker.unpack(mpjbuf, buf, offset);
+ offset += itemLen;
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int numFull = length / itemSize;
+ for (int i = 0; i < numFull; i++) {
+ itemPacker.unpack(mpjbuf, buf, offset);
+ offset += itemLen;
+ }
+ int residue = length - numFull * itemSize;
+ if (residue > 0)
+ itemPacker.unpackPartial(mpjbuf, residue, buf, offset);
+ }
+ }
+
+}
+
+// Things to do:
+//
+
diff --git a/src/mpi/Datatype.java b/src/mpi/Datatype.java
new file mode 100644
index 0000000..049bafe
--- /dev/null
+++ b/src/mpi/Datatype.java
@@ -0,0 +1,444 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Datatype.java
+ * Author : Sang Lim, Sung-Hoon Ko, Xinying Li, Bryan Carpenter
+ * Aamir Shafi
+ * Created : Thu Apr 9 12:22:15 BST 1998
+ * Revision : $Revision: 1.15 $
+ * Updated : $Date: 2014/03/11 13:12:07 $
+ * Copyright: Northeast Parallel Architectures Center
+ * at Syracuse University 1998
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer;
+
+public abstract class Datatype implements Freeable {
+
+ mpjbuf.Type bufferType = mpjbuf.Type.UNDEFINED;
+
+ /*
+ * Make these a superset of `mpjdev.Buffer' type enumeration. create an
+ * enumberation here. Tried to create an ENUM, but if i declare it in
+ * MPI.java, and if its name is also MPI (aamir)
+ */
+
+ final static int UNDEFINED = -1;
+ final static int NULL = 0;
+ final static int BYTE = 1;
+ final static int CHAR = 2;
+ final static int SHORT = 3;
+ final static int BOOLEAN = 4;
+ final static int INT = 5;
+ final static int LONG = 6;
+ final static int FLOAT = 7;
+ final static int DOUBLE = 8;
+ final static int PACKED = 9;
+ final static int LB = 10;
+ final static int UB = 11;
+ final static int OBJECT = 12;
+
+ final static int SHORT2 = 3;
+ final static int INT2 = 5;
+ final static int LONG2 = 6;
+ final static int FLOAT2 = 7;
+ final static int DOUBLE2 = 8;
+
+ int numEls;
+ public int baseType = UNDEFINED;
+ int size;
+ int byteSize;
+ int lb, ub, extent;
+ boolean ubSet, lbSet;
+ // Flags set if MPI.UB, MPI.LB respectively appears as a component type.
+ Packer packer;
+
+ Packer getPacker() {
+
+ if (packer == null)
+ setPacker();
+
+ return packer;
+ }
+
+ // added for native MPI support
+ public int getType() {
+ return this.baseType;
+ }
+
+ // added for native MPI support
+ public int getByteSize() {
+ return this.byteSize;
+ }
+
+ abstract void setPacker();
+
+ /*
+ * offset will be 'MPI.SEND_OVERHEAD' size will be 'packedSize(count) +
+ * MPI.SEND_OVERHEAD '
+ */
+ abstract mpjbuf.Buffer createWriteBuffer(int count) throws MPIException;
+
+ /*
+ * messageSize will be 'packedSize(count)+MPI.BSEND_OVERHEAD' offset will be
+ * set in this method to 'MPI.BSEND_OVERHEAD '
+ */
+ abstract mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer,
+ int messageSize);
+
+ /*
+ * size is 'packedSize(count)+MPI.RECV_OVERHEAD' ; offset is
+ * 'MPI.RECV_OVERHEAD'
+ */
+ abstract mpjbuf.Buffer createReadBuffer(int count);
+
+ abstract int packedSize(int count);
+
+ /**
+ * Returns the extent of a datatype - the difference between upper and lower
+ * bound.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>datatype extent
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_EXTENT</tt>.
+ */
+
+ public int Extent() throws MPIException {
+ return extent;
+ }
+
+ /**
+ * Returns the total size of a datatype - the number of buffer elements it
+ * represents.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>datatype size
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_SIZE</tt>.
+ */
+
+ public int Size() throws MPIException {
+ return size;
+ }
+
+ /**
+ * Find the lower bound of a datatype - the least value in its displacement
+ * sequence.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>displacement of lower bound from origin
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_LB</tt>.
+ */
+
+ public int Lb() throws MPIException {
+ return lb;
+ }
+
+ /**
+ * Find the upper bound of a datatype - the greatest value in its displacement
+ * sequence.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>displacement of upper bound from origin
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_UB</tt>.
+ */
+
+ public int Ub() throws MPIException {
+ return ub;
+ }
+
+ /**
+ * Commit a derived datatype. Java binding of the MPI operation
+ * <tt>MPI_TYPE_COMMIT</tt>.
+ */
+
+ public void Commit() throws MPIException {
+ /*
+ * if(... something ...) commit() ;
+ */
+ }
+
+ public void finalize() throws MPIException {
+ /*
+ * synchronized(MPI.class) { MPI.freeList.addFirst(this) ; }
+ */
+ }
+
+ /**
+ * Construct new datatype representing replication of old datatype into
+ * contiguous locations.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>replication count
+ * </tr>
+ * <tr>
+ * <td><tt> oldtype </tt></td>
+ * <td>old datatype
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_CONTIGUOUS</tt>.
+ * <p>
+ * The base type of the new datatype is the same as the base type of
+ * <tt>oldtype</tt>.
+ */
+
+ public static Datatype Contiguous(int count, Datatype oldtype)
+ throws MPIException {
+ return new Contiguous(count, oldtype);
+ }
+
+ /**
+ * Construct new datatype representing replication of old datatype into
+ * locations that consist of equally spaced blocks.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of blocks
+ * </tr>
+ * <tr>
+ * <td><tt> blocklength </tt></td>
+ * <td>number of elements in each block
+ * </tr>
+ * <tr>
+ * <td><tt> stride </tt></td>
+ * <td>number of elements between start of each block
+ * </tr>
+ * <tr>
+ * <td><tt> oldtype </tt></td>
+ * <td>old datatype
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_VECTOR</tt>.
+ * <p>
+ * The base type of the new datatype is the same as the base type of
+ * <tt>oldtype</tt>.
+ */
+
+ public static Datatype Vector(int count, int blocklength, int stride,
+ Datatype oldtype) throws MPIException {
+
+ return new Vector(count, blocklength, stride, oldtype, true);
+ }
+
+ /**
+ * Identical to <tt>vector</tt> except that the stride is expressed directly
+ * in terms of the buffer index, rather than the units of the old type.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of blocks
+ * </tr>
+ * <tr>
+ * <td><tt> blocklength </tt></td>
+ * <td>number of elements in each block
+ * </tr>
+ * <tr>
+ * <td><tt> stride </tt></td>
+ * <td>number of elements between start of each block
+ * </tr>
+ * <tr>
+ * <td><tt> oldtype </tt></td>
+ * <td>old datatype
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_HVECTOR</tt>.
+ * <p>
+ * <em>Unlike other language bindings</em>, the value of <tt>stride</tt> is
+ * <em>not</em> measured in bytes.
+ */
+
+ public static Datatype Hvector(int count, int blocklength, int stride,
+ Datatype oldtype) throws MPIException {
+
+ return new Vector(count, blocklength, stride, oldtype, false);
+ }
+
+ /**
+ * Construct new datatype representing replication of old datatype into a
+ * sequence of blocks where each block can contain a different number of
+ * copies and have a different displacement.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_blocklengths </tt></td>
+ * <td>number of elements per block
+ * </tr>
+ * <tr>
+ * <td><tt> array_of_displacements </tt></td>
+ * <td>displacement of each block in units of old type
+ * </tr>
+ * <tr>
+ * <td><tt> oldtype </tt></td>
+ * <td>old datatype
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_INDEXED</tt>.
+ * <p>
+ * The number of blocks is taken to be size of the
+ * <tt>array_of_blocklengths</tt> argument. The second argument,
+ * <tt>array_of_displacements</tt>, should be the same size. The base type of
+ * the new datatype is the same as the base type of <tt>oldtype</tt>.
+ */
+
+ public static Datatype Indexed(int[] array_of_blocklengths,
+ int[] array_of_displacements, Datatype oldtype) throws MPIException {
+
+ return new Indexed(array_of_blocklengths, array_of_displacements, oldtype,
+ true);
+ }
+
+ /**
+ * Identical to <tt>indexed</tt> except that the displacements are expressed
+ * directly in terms of the buffer index, rather than the units of the old
+ * type.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_blocklengths </tt></td>
+ * <td>number of elements per block
+ * </tr>
+ * <tr>
+ * <td><tt> array_of_displacements </tt></td>
+ * <td>displacement in buffer for each block
+ * </tr>
+ * <tr>
+ * <td><tt> oldtype </tt></td>
+ * <td>old datatype
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_HINDEXED</tt>.
+ * <p>
+ * <em>Unlike other language bindings</em>, the values in
+ * <tt>array_of_displacements</tt> are <em>not</em> measured in bytes.
+ */
+
+ public static Datatype Hindexed(int[] array_of_blocklengths,
+ int[] array_of_displacements, Datatype oldtype) throws MPIException {
+ return new Indexed(array_of_blocklengths, array_of_displacements, oldtype,
+ false);
+ }
+
+ /**
+ * The most general type constructor.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_blocklengths </tt></td>
+ * <td>number of elements per block
+ * </tr>
+ * <tr>
+ * <td><tt> array_of_displacements </tt></td>
+ * <td>displacement in buffer for each block
+ * </tr>
+ * <tr>
+ * <td><tt> array_of_types </tt></td>
+ * <td>type of elements in each block
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new datatype
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TYPE_STRUCT</tt>.
+ * <p>
+ * The number of blocks is taken to be size of the
+ * <tt>array_of_blocklengths</tt> argument. The second and third arguments,
+ * <tt>array_of_displacements</tt>, and <tt>array_of_types</tt>, should be the
+ * same size. <em>Unlike other language bindings</em>, the values in
+ * <tt>array_of_displacements</tt> are <em>not</em> measured in bytes. All
+ * elements of <tt>array_of_types</tt> with definite base types
+ * <em>must have the <em>same</em> base type</em>: this will be the base type
+ * of new datatype.
+ */
+
+ public static Datatype Struct(int[] array_of_blocklengths,
+ int[] array_of_displacements, Datatype[] array_of_types)
+ throws MPIException {
+ return new Struct(array_of_blocklengths, array_of_displacements,
+ array_of_types);
+ }
+
+ public void free() {
+ }
+
+}
diff --git a/src/mpi/Errhandler.java b/src/mpi/Errhandler.java
new file mode 100755
index 0000000..a916642
--- /dev/null
+++ b/src/mpi/Errhandler.java
@@ -0,0 +1,55 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Errhandler.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/08/09 15:03:03 $
+ */
+
+/*
+ *@author Aamir Shafi, Bryan Carpenter
+ */
+
+package mpi;
+
+public class Errhandler {
+
+ static final int FATAL = 2;
+
+ static final int RETURN = 3;
+
+ int code ;
+
+ Errhandler(int code) {
+ this.code = code;
+ }
+
+}
diff --git a/src/mpi/Freeable.java b/src/mpi/Freeable.java
new file mode 100755
index 0000000..8cc2026
--- /dev/null
+++ b/src/mpi/Freeable.java
@@ -0,0 +1,42 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Freeable.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+interface Freeable {
+ public void free() throws MPIException ;
+}
+
diff --git a/src/mpi/GatherPackerBoolean.java b/src/mpi/GatherPackerBoolean.java
new file mode 100644
index 0000000..506f835
--- /dev/null
+++ b/src/mpi/GatherPackerBoolean.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerBoolean extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerBoolean(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((boolean []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((boolean []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((boolean []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerByte.java b/src/mpi/GatherPackerByte.java
new file mode 100644
index 0000000..89ea709
--- /dev/null
+++ b/src/mpi/GatherPackerByte.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerByte extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerByte(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((byte []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((byte []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((byte []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerChar.java b/src/mpi/GatherPackerChar.java
new file mode 100644
index 0000000..c690aa6
--- /dev/null
+++ b/src/mpi/GatherPackerChar.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerChar extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerChar(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((char []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((char []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((char []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerDouble.java b/src/mpi/GatherPackerDouble.java
new file mode 100644
index 0000000..8ee152b
--- /dev/null
+++ b/src/mpi/GatherPackerDouble.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerDouble extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerDouble(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((double []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((double []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((double []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerFactory.java b/src/mpi/GatherPackerFactory.java
new file mode 100644
index 0000000..a40ade0
--- /dev/null
+++ b/src/mpi/GatherPackerFactory.java
@@ -0,0 +1,95 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerFactory.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+public class GatherPackerFactory {
+
+ public static Packer create(int numBlocks, int[] displs,
+ int type, int extent) {
+
+ switch (type) {
+
+ case -1: //UNDEFINED (dont know what to do here)
+ break;
+
+ case 0: //NULL (dont know what to do here)
+ break;
+
+ case 1: //BYTE
+ return new GatherPackerByte(numBlocks, displs, extent);
+
+ case 2: //CHAR
+ return new GatherPackerChar(numBlocks, displs, extent);
+
+ case 3: //SHORT
+ return new GatherPackerShort(numBlocks, displs, extent);
+
+ case 4: //BOOLEAN
+ return new GatherPackerBoolean(numBlocks, displs, extent);
+
+ case 5: //INT
+ return new GatherPackerInt(numBlocks, displs, extent);
+
+ case 6: //LONG
+ return new GatherPackerLong(numBlocks, displs, extent);
+
+ case 7: //FLOAT
+ return new GatherPackerFloat(numBlocks, displs, extent);
+
+ case 8: //DOUBLE
+ return new GatherPackerDouble(numBlocks, displs, extent);
+
+ case 9: //PACKED
+ break;
+
+ case 10: //LB
+ break;
+
+ case 11: //UB
+ break;
+
+ case 12: //OBJECT
+ return new GatherPackerObject(numBlocks, displs, extent);
+
+ default:
+ break;
+ }
+
+ return null;
+ }
+}
diff --git a/src/mpi/GatherPackerFloat.java b/src/mpi/GatherPackerFloat.java
new file mode 100644
index 0000000..a909b5a
--- /dev/null
+++ b/src/mpi/GatherPackerFloat.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerFloat extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerFloat(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((float []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((float []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((float []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerInt.java b/src/mpi/GatherPackerInt.java
new file mode 100644
index 0000000..b3d088e
--- /dev/null
+++ b/src/mpi/GatherPackerInt.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerInt extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerInt(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((int []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((int []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((int []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerLong.java b/src/mpi/GatherPackerLong.java
new file mode 100644
index 0000000..f31880c
--- /dev/null
+++ b/src/mpi/GatherPackerLong.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerLong extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerLong(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((long []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((long []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((long []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerObject.java b/src/mpi/GatherPackerObject.java
new file mode 100644
index 0000000..ca9e164
--- /dev/null
+++ b/src/mpi/GatherPackerObject.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerObject.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerObject extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerObject(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).gather((Object []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).scatter((Object []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).scatter((Object []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerShort.java b/src/mpi/GatherPackerShort.java
new file mode 100644
index 0000000..a7a3bce
--- /dev/null
+++ b/src/mpi/GatherPackerShort.java
@@ -0,0 +1,85 @@
+/* This file generated automatically from template GatherPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPackerShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPackerShort extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPackerShort(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.gather((short []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((short []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.scatter((short []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GatherPackerType.java.in b/src/mpi/GatherPackerType.java.in
new file mode 100644
index 0000000..f535bff
--- /dev/null
+++ b/src/mpi/GatherPackerType.java.in
@@ -0,0 +1,84 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GatherPacker at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+ import mpjbuf.*;
+
+ public class GatherPacker at Type@ extends GenericPacker {
+
+ public int [] displacements ;
+
+ public GatherPacker at Type@(int numEls, int [] displacements, int extent) {
+ super(extent, numEls) ;
+ this.displacements = displacements ;
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @WRITEBUF(mpjbuf)@.gather((@type@ []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.scatter((@type@ []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.scatter((@type@ []) buf, size,
+ offset, displacements) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/GenericPacker.java b/src/mpi/GenericPacker.java
new file mode 100644
index 0000000..bae0842
--- /dev/null
+++ b/src/mpi/GenericPacker.java
@@ -0,0 +1,95 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : GenericPacker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.12 $
+ * Updated : $Date: 2005/08/02 13:07:05 $
+ */
+
+package mpi;
+
+public abstract class GenericPacker
+ implements Packer {
+
+ int extent, size;
+
+ public GenericPacker(int extent, int size) {
+ this.extent = extent;
+ this.size = size;
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset, int count) throws MPIException {
+ for (int i = 0; i < count; i++) {
+ pack(mpjbuf, buf, offset);
+ offset += extent;
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset, int count) throws MPIException {
+
+ if(size == 0 ) {
+ return;
+ }
+
+ if (count * size < length) {
+ throw new MPIException("Error in GenericPacker: count*size <"+
+ (count*size) + " is less than length <"+length+">");
+ }
+ else {
+ int numFull = length / size;
+ for (int i = 0; i < numFull; i++) {
+ unpack(mpjbuf, buf, offset);
+ offset += extent ;
+ }
+ int residue = length - numFull * size;
+ if (residue > 0) {
+ unpackPartial(mpjbuf, residue, buf, offset);
+ }
+ }
+ }
+
+ /**
+ * this method was not there, but putting it exactly as
+ * pack method above offcourse changing pack to unpack.
+ */
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset, int count) throws MPIException {
+ for (int i = 0; i < count; i++) {
+ unpack(mpjbuf, buf, offset);
+ offset += extent;
+ }
+ }
+}
+
diff --git a/src/mpi/GraphParms.java b/src/mpi/GraphParms.java
new file mode 100755
index 0000000..4a994cb
--- /dev/null
+++ b/src/mpi/GraphParms.java
@@ -0,0 +1,44 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : GraphParms.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+public class GraphParms {
+ public int[] index;
+ public int[] edges;
+}
+
diff --git a/src/mpi/Graphcomm.java b/src/mpi/Graphcomm.java
new file mode 100755
index 0000000..6f0cfb7
--- /dev/null
+++ b/src/mpi/Graphcomm.java
@@ -0,0 +1,155 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Graphcomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/28 13:33:59 $
+ */
+
+package mpi;
+
+public class Graphcomm
+ extends Intracomm {
+ GraphParms graphParms = null;
+
+ Graphcomm(int[] index, int[] edges, boolean reorder,
+ mpjdev.Comm mpjdevComm, mpjdev.Group group) throws MPIException {
+
+ super(mpjdevComm,group) ;
+
+ int rank = group.rank();
+ //this.mpjdevComm = mpjdevComm;
+ //this.group = new Group(group);
+ graphParms = new GraphParms();
+
+ graphParms.index = new int[index.length];
+ System.arraycopy(index,0,graphParms.index,0,index.length);
+ //graphParms.index = index;
+
+ graphParms.edges = new int[edges.length];
+ System.arraycopy(edges,0,graphParms.edges,0,edges.length);
+ //graphParms.edges = edges;
+ //nedges = index[index.length-1];
+ }
+
+ /**
+ */
+ public Object clone() throws MPIException {
+ return this.Create_graph(graphParms.index, graphParms.edges, false);
+ }
+
+ /**
+ * Returns graph topology information.
+ * <p>
+ * <table>
+ * <tr><td><em> returns: </em></td><td> object defining node degress and
+ * edges of graph </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GRAPHDIMS_GET</tt>.
+ * <p>
+ * The number of nodes and number of edges can be extracted
+ * from the sizes of the <tt>index</tt> and <tt>edges</tt> fields
+ * of the returned object.
+ */
+ public GraphParms Get() throws MPIException {
+ return graphParms;
+ }
+
+ /**
+ * Provides adjacency information for general graph topology.
+ * <p>
+ * <table>
+ * <tr><td><tt> rank </tt></td><td> rank of a process in the group
+ * of this communicator </tr>
+ * <tr><td><em> returns: </em></td><td> array of ranks of neighbouring
+ * processes to one specified </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operations <tt>MPI_GRAPH_NEIGHBOURS_COUNT</tt>
+ * and <tt>MPI_GRAPH_NEIGHBOURS</tt>.
+ * <p>
+ * The number of neighbours can be extracted from the size of the result.
+ */
+ public int[] Neighbours(int rank) throws MPIException {
+ int nnbrs = graphParms.index[rank];
+ int i = 0;
+ int p = 0; //index to graphParms edges
+
+ if (rank > 0) {
+ i = graphParms.index[rank - 1];
+ nnbrs -= i;
+ p = i;
+ }
+
+ int[] nbrs = new int[nnbrs]; //MPI says there is a need for maxnbrs here
+ //but mpiJava seems to get rid of it ..
+ //so discuss with Bryan, and if you introduce
+ //maxnbrs as an arg, then which ever is lesser
+ //(maxnbrs, or nnbrs) would be the size of
+ //nbrs array ...
+
+ for (i = 0; i < nnbrs; ++i, ++p) {
+ nbrs[i] = graphParms.edges[p];
+ }
+
+ return nbrs; //current maxnbrs can be obtained by
+ //nbrs.length ...
+
+ }
+
+ /**
+ * Compute an optimal placement.
+ * <p>
+ * <table>
+ * <tr><td><tt> index </tt></td><td> node degrees </tr>
+ * <tr><td><tt> edges </tt></td><td> graph edges </tr>
+ * <tr><td><em> returns: </em></td><td> reordered rank of calling
+ * process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GRAPH_MAP</tt>.
+ * <p>
+ * The number of nodes is taken to be size of the <tt>index</tt> argument.
+ */
+ public int Map(int[] index, int[] edges) throws MPIException {
+ int myrank = this.group.Rank();
+ //-1 in the next line is MPI.UNDEFINED ...
+ return ( (myrank < 0) || (myrank >= index.length)) ? -1 : myrank;
+ }
+
+ public int Topo_test() throws MPIException {
+ return MPI.GRAPH; //this means no topology ....
+ }
+
+}
+
diff --git a/src/mpi/Group.java b/src/mpi/Group.java
new file mode 100755
index 0000000..4c1d25d
--- /dev/null
+++ b/src/mpi/Group.java
@@ -0,0 +1,464 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Group.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.14 $
+ * Updated : $Date: 2014/03/11 13:24:14 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import java.util.UUID;
+import xdev.ProcessID;
+
+public class Group implements Freeable {
+
+ static final int NULL = 2;
+
+ // made public because of mpjdev.MPJDev.java
+ // where Constants.GROUP_EMPTY is initialized
+ public static final int EMPTY = 3;
+ // TODO remove public
+ public int code = -1;
+
+ public mpjdev.Group mpjdevGroup = null;
+
+ public Group(mpjdev.Group mpjdevGroup) {
+ if (mpjdevGroup == null) {
+ if (Constants.isNative == true) {
+ this.mpjdevGroup = new mpjdev.natmpjdev.Group(Group.EMPTY);
+ } else {
+ this.mpjdevGroup = new mpjdev.javampjdev.Group(new ProcessID[0], null,
+ -1);
+ }
+ } else {
+ this.mpjdevGroup = mpjdevGroup;
+ }
+ }
+
+ Group(int code) {
+ this.code = code;
+ }
+
+ /**
+ * This method frees this group object. Though automatic garbage collector
+ * will take care of it, but we mark this object for gc, by declaring it null
+ * implement at the end.
+ */
+ public void free() {
+ // this.group = null;
+ // this = null;
+ }
+
+ /**
+ * Size of group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>number of processors in the group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_SIZE</tt>.
+ */
+ public int Size() throws MPIException {
+ return (this.mpjdevGroup != null ? this.mpjdevGroup.size() : MPI.UNDEFINED);
+ }
+
+ /**
+ * Rank of this process in group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>rank of the calling process in the group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_RANK</tt>.
+ *
+ * Result value is <tt>MPI.UNDEFINED</tt> if this process is not a member of
+ * the group.
+ */
+ public int Rank() throws MPIException {
+ return this.mpjdevGroup.rank();
+ }
+
+ /**
+ * Translate ranks within one group to ranks within another.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group1 </tt></td>
+ * <td>a group
+ * </tr>
+ * <tr>
+ * <td><tt> ranks1 </tt></td>
+ * <td>array of valid ranks in <tt>group1</tt>
+ * </tr>
+ * <tr>
+ * <td><tt> group2 </tt></td>
+ * <td>another group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>array of corresponding ranks in <tt>group2</tt>
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_TRANSLATE_RANKS</tt>.
+ * <p>
+ * Result elements are <tt>MPI.UNDEFINED</tt> where no correspondence exists.
+ */
+ public static int[] Translate_ranks(Group group1, int[] ranks1, Group group2)
+ throws MPIException {
+ return mpjdev.Group.transRanks(group1.mpjdevGroup, ranks1,
+ group2.mpjdevGroup);
+ }
+
+ /**
+ * Compare two groups.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group1 </tt></td>
+ * <td>first group
+ * </tr>
+ * <tr>
+ * <td><tt> group2 </tt></td>
+ * <td>second group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>result
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_COMPARE</tt>.
+ * <p>
+ * <tt>MPI.IDENT</tt> results if the group members and group order are exactly
+ * the same in both groups. <tt>MPI.SIMILAR</tt> results if the group members
+ * are the same but the order is different. <tt>MPI.UNEQUAL</tt> results
+ * otherwise.
+ */
+ public static int Compare(Group group1, Group group2) throws MPIException {
+
+ // System.out.println("group1 code = "+ group1.code+" group2 code = "+
+ // group2.code);
+
+ if (group1 == null || group1 == null) {
+ throw new MPIException(" Group.Compare does not accept null " + "groups");
+ } else if (group1.code == EMPTY && group2.code == EMPTY) {
+ throw new MPIException("Group.Compare cannot compare empty groups");
+ } else if (group1.code == EMPTY) {
+ return MPI.UNEQUAL;
+ } else if (group2.code == EMPTY) {
+ return MPI.UNEQUAL;
+ } else if (group1.code == NULL && group2.code == NULL) {
+ throw new MPIException("Group.Compare cannot compare null groups");
+ } else if (group1.code == NULL) {
+ return MPI.UNEQUAL;
+ } else if (group2.code == NULL) {
+ return MPI.UNEQUAL;
+ } else
+ return mpjdev.Group.compare(group1.mpjdevGroup, group2.mpjdevGroup);
+ }
+
+ /**
+ * Set union of two groups.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group1 </tt></td>
+ * <td>first group
+ * </tr>
+ * <tr>
+ * <td><tt> group2 </tt></td>
+ * <td>second group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>union group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_UNION</tt>.
+ */
+
+ public static Group Union(Group group1, Group group2) throws MPIException {
+
+ if (group1 == null || group2 == null) {
+ throw new MPIException("Group.Union does not accept null groups as"
+ + "arguments");
+ }
+
+ else if (group1.code == NULL && group2.code == NULL) {
+ return MPI.GROUP_NULL;
+ }
+
+ else if (group2.code == NULL) {
+ return group1;
+ }
+
+ else if (group1.code == NULL) {
+ return group2;
+ }
+
+ else if (group1.code == EMPTY && group2.code == EMPTY) {
+ return MPI.GROUP_EMPTY;
+ }
+
+ else if (group2.code == EMPTY) {
+ return group1;
+ }
+
+ else if (group1.code == EMPTY) {
+ return group2;
+ }
+
+ return new Group(mpjdev.Group.union(group1.mpjdevGroup, group2.mpjdevGroup));
+ }
+
+ /**
+ * Set intersection of two groups.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group1 </tt></td>
+ * <td>first group
+ * </tr>
+ * <tr>
+ * <td><tt> group2 </tt></td>
+ * <td>second group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>intersection group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_INTERSECTION</tt>.
+ */
+ public static Group Intersection(Group group1, Group group2)
+ throws MPIException {
+ if (group1 == null || group2 == null) {
+ throw new MPIException("Group.Union does not accept null groups as"
+ + "arguments");
+ }
+
+ else if (group1.code == NULL || group2.code == NULL) {
+ return MPI.GROUP_NULL;
+ }
+
+ else if (group1.code == EMPTY || group2.code == EMPTY) {
+ return MPI.GROUP_EMPTY;
+ }
+
+ return new Group(mpjdev.Group.intersection(group1.mpjdevGroup,
+ group2.mpjdevGroup));
+ }
+
+ /**
+ * Result contains all elements of the first group that are not in the second
+ * group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group1 </tt></td>
+ * <td>first group
+ * </tr>
+ * <tr>
+ * <td><tt> group2 </tt></td>
+ * <td>second group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>difference group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_DIFFERENCE</tt>.
+ */
+ public static Group Difference(Group group1, Group group2)
+ throws MPIException {
+ if (group1 == null || group2 == null) {
+ throw new MPIException("Group.Union does not accept null groups as"
+ + "arguments");
+ }
+
+ if (group1.code == NULL) {
+ return MPI.GROUP_NULL;
+ }
+
+ if (group2.code == NULL) {
+ return group1;
+ }
+
+ if (group1.code == EMPTY) {
+ return MPI.GROUP_EMPTY;
+ }
+
+ if (group2.code == EMPTY) {
+ return group1;
+ }
+
+ return new Group(mpjdev.Group.difference(group1.mpjdevGroup,
+ group2.mpjdevGroup));
+ }
+
+ /**
+ * Create a subset group including specified processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> ranks </tt></td>
+ * <td>ranks from this group to appear in new group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_INCL</tt>.
+ */
+ public Group Incl(int[] ranks) throws MPIException {
+ if (ranks == null) {
+ throw new MPIException("Group.Incl does not accept a null integer "
+ + " array ");
+ }
+
+ if (ranks.length == 0) {
+ return MPI.GROUP_EMPTY;
+ }
+
+ return new Group(mpjdevGroup.incl(ranks));
+ }
+
+ /**
+ * Create a subset group excluding specified processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> ranks </tt></td>
+ * <td>ranks from this group <em>not</em> to appear in new group
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_EXCL</tt>.
+ */
+ public Group Excl(int[] ranks) throws MPIException {
+ if (ranks == null) {
+ throw new MPIException("Group.Excl does not accept a null integer "
+ + " array ");
+ }
+
+ if (ranks.length == 0) {
+ return this;
+ }
+
+ return new Group(mpjdevGroup.excl(ranks));
+ }
+
+ /**
+ * Create a subset group including processes specified by strided intervals of
+ * ranks.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> ranges </tt></td>
+ * <td>array of integer triplets
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_RANGE_INCL</tt>.
+ * <p>
+ * The triplets are of the form (first rank, last rank, stride) indicating
+ * ranks in this group to be included in the new group. The size of the first
+ * dimension of <tt>ranges</tt> is the number of triplets. The size of the
+ * second dimension is 3.
+ */
+ public Group Range_incl(int[][] ranges) throws MPIException {
+ if (ranges == null) {
+ throw new MPIException("Group.Range_incl does not accept null integer "
+ + "array as argument");
+ }
+ return new Group(mpjdevGroup.rangeIncl(ranges));
+ }
+
+ /**
+ * Create a subset group excluding processes specified by strided intervals of
+ * ranks.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> ranges </tt></td>
+ * <td>array of integer triplets
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new group
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_RANGE_EXCL</tt>.
+ * <p>
+ * Triplet array is defined as for <tt>Range_incl</tt>, the ranges indicating
+ * ranks in this group to be excluded from the new group.
+ */
+ public Group Range_excl(int[][] ranges) throws MPIException {
+ if (ranges == null) {
+ throw new MPIException("Group.Range_incl does not accept null integer "
+ + "array as argument");
+ }
+ return new Group(mpjdevGroup.rangeExcl(ranges));
+ }
+
+ /**
+ * Destructor.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GROUP_FREE</tt>.
+ */
+
+ public void finalize() throws MPIException {
+ }
+}
diff --git a/src/mpi/Indexed.java b/src/mpi/Indexed.java
new file mode 100644
index 0000000..3fdb44a
--- /dev/null
+++ b/src/mpi/Indexed.java
@@ -0,0 +1,299 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Indexed.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.18 $
+ * Updated : $Date: 2005/08/12 19:12:08 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer ;
+
+/**
+ * Subclass of `Datatype' representing a derived datatype created using
+ * `Indexed()' or `Hindexed()'.
+ */
+public class Indexed
+ extends Datatype {
+
+ private int[] blockLengths, displacements;
+ private boolean unitsOfOldExtent;
+ // true => Indexed, false => Hindexed.
+ private boolean unitBlocks;
+ // Case where all blocks have unit length is detected and
+ // treated specially.
+
+ private Datatype oldType;
+ int numBlocks; //(aamir)
+ int repetitions; //(aamir)
+
+ public Indexed(int[] array_of_blocklengths, int[] array_of_displacements,
+ Datatype oldType,
+ boolean unitsOfOldExtent) throws MPIException {
+
+ this.oldType = oldType;
+ this.bufferType = oldType.bufferType; //aamir
+ this.unitsOfOldExtent = unitsOfOldExtent;
+ int oldExtent = oldType.Extent();
+ numBlocks = array_of_blocklengths.length;
+ repetitions = 0;
+ unitBlocks = true;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int blockLength = array_of_blocklengths[i];
+ if (blockLength < 0) {
+ throw new MPIException(
+ "All block-lengths for Indexed/Hindexed must be non-negative");
+ }
+ repetitions += blockLength;
+ if (blockLength != 1) unitBlocks = false;
+ }
+
+ if (!unitBlocks) {
+ blockLengths = new int[numBlocks];
+ for (int i = 0; i < numBlocks; i++)
+ blockLengths[i] = array_of_blocklengths[i];
+ }
+
+ displacements = new int[numBlocks];
+ // We store the "real" displacements.
+
+ if (unitsOfOldExtent) {
+ for (int i = 0; i < numBlocks; i++)
+ displacements[i] = oldExtent * array_of_displacements[i];
+ }
+ else {
+ for (int i = 0; i < numBlocks; i++)
+ displacements[i] = array_of_displacements[i];
+ }
+
+ baseType = oldType.baseType;
+ int oldSize = oldType.Size();
+ size = repetitions * oldSize;
+ byteSize = repetitions * oldType.byteSize;
+
+ computeBounds(oldSize);
+
+ }
+
+ private void computeBounds(int oldSize) {
+
+ // Compute `ub' and `lb', which define the `extent' of the new type.
+ // Also defines `ubSet', `lbSet' for this type.
+
+ ubSet = repetitions > 0 && oldType.ubSet;
+ lbSet = repetitions > 0 && oldType.lbSet;
+
+ // Compute ub and lb, which define the extent of the new type.
+
+ lb = Integer.MAX_VALUE;
+ ub = Integer.MIN_VALUE;
+ extent = 0; // Follow MPICH in defining extent to be zero if
+ // bounds are undefined (i.e. empty type).
+
+ if (oldSize != 0 || oldType.lbSet || oldType.ubSet) {
+
+ // `oldType.ub', `oldType.lb', `oldType.extent' all well-defined.
+
+ int oldExtent = oldType.extent; //aamir
+ //int numBlocks = displacements.length; //aamir
+
+ // Assume all extents are non-negative.
+
+ for (int i = 0; i < numBlocks; i++) {
+ int blockLen = unitBlocks ? 1 : blockLengths[i];
+
+ if (blockLen > 0) {
+
+ int startBlock = displacements[i];
+
+ int max_ub = startBlock + (blockLen - 1) * oldExtent +
+ oldType.ub;
+ if (max_ub > ub)
+ ub = max_ub;
+
+ int min_lb = startBlock + oldType.lb;
+ if (min_lb < lb)
+ lb = min_lb;
+
+ /* Following "correct" according to standard, but likely to
+ cause compatibility problems with MPICH?
+ if(oldExtent > 0) {
+ int max_ub = startBlock + (blockLen - 1) * oldExtent +
+ oldType.ub ;
+ if (max_ub > ub)
+ ub = max_ub ;
+
+ int min_lb = startBlock + oldType.lb ;
+ if (min_lb < lb)
+ lb = min_lb ;
+ }
+ else {
+ int max_ub = startBlock + oldType.ub ;
+ if (max_ub > ub)
+ ub = max_ub ;
+
+ int min_lb = startBlock + (blockLen - 1) * oldExtent +
+ oldType.lb ;
+ if (min_lb < lb)
+ lb = min_lb ;
+ }
+ */
+ }
+ }
+
+ extent = ub - lb;
+ }
+ }
+
+ mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer, int messageSize) {
+ return new mpjbuf.Buffer( new NIOBuffer(messageSize, slicedBuffer),
+ MPI.BSEND_OVERHEAD , messageSize ) ;
+ }
+
+ mpjbuf.Buffer createWriteBuffer(int count) throws MPIException {
+ int capacity = packedSize(count) + MPI.SEND_OVERHEAD ;
+ int offset = MPI.SEND_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer(rawBuffer, offset, capacity);
+
+ try {
+ wBuffer.putSectionHeader(this.bufferType); // need conversion
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return wBuffer;
+ }
+
+ mpjbuf.Buffer createReadBuffer(int count) {
+ int capacity = packedSize(count) + MPI.RECV_OVERHEAD ;
+ int offset = MPI.RECV_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer mpjbuf = new mpjbuf.Buffer(rawBuffer, offset, capacity);
+ return mpjbuf;
+ }
+
+ int packedSize(int count) {
+ int dataSize = count * byteSize;
+ int totalSize = 0;
+ int sectionHeader = 8; //what about multiple sections.
+ totalSize = sectionHeader + dataSize;
+ int padding = 0;
+
+ if (totalSize % 8 != 0)
+ padding = totalSize % 8;
+
+ return totalSize + padding;
+ }
+
+ void setPacker() {
+
+ if (oldType instanceof BasicType && unitBlocks) {
+ packer = GatherPackerFactory.create(numBlocks, displacements, baseType,
+ extent);
+ }
+ else {
+ packer = new IndexedPacker();
+ }
+ }
+
+ private class IndexedPacker
+ extends GenericPacker {
+
+ Packer itemPacker;
+ int itemSize;
+ int numBlocks; //(aamir)
+
+ IndexedPacker() {
+ super(Indexed.this.extent, Indexed.this.size);
+
+ itemPacker = oldType.getPacker(); //just to avoid errors ..giving it arg 2
+ this.itemSize = oldType.extent;
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ int numBlocks = displacements.length;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int boffset = offset + displacements[i];
+ int blockLen = unitBlocks ? 1 : blockLengths[i];
+ itemPacker.pack(mpjbuf, buf, boffset, blockLen);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ int numBlocks = displacements.length;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int boffset = offset + displacements[i];
+ int blockLen = unitBlocks ? 1 : blockLengths[i];
+ itemPacker.unpack(mpjbuf, buf, boffset, blockLen);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int remaining = length;
+ for (int i = 0; i < displacements.length; i++) {
+ int boffset = offset + displacements[i];
+ int blockLen = unitBlocks ? 1 : blockLengths[i];
+ int blockSize = blockLen * itemSize;
+ if (blockSize < remaining) {
+ itemPacker.unpack(mpjbuf, buf, boffset, blockLen);
+ remaining -= blockSize;
+ }
+ else {
+ int numFull = remaining / itemSize;
+ int fullItemsSize = numFull * itemSize;
+ itemPacker.unpack(mpjbuf, buf, boffset, numFull);
+ itemPacker.unpackPartial(mpjbuf, remaining - fullItemsSize,
+ buf, boffset + fullItemsSize);
+ return;
+ }
+ }
+ }
+ }
+
+}
+
+// Things to do:
+//
+
diff --git a/src/mpi/Intercomm.java b/src/mpi/Intercomm.java
new file mode 100755
index 0000000..970e4c7
--- /dev/null
+++ b/src/mpi/Intercomm.java
@@ -0,0 +1,166 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Intercomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.10 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+
+public class Intercomm
+ extends Comm {
+
+ Comm peerComm = null; //only need Create_intercommm method ..so its OK :)
+ Comm local_comm;
+ int local_leader, remote_leader;
+
+ //TODO: get this approved
+ // native Intercomm
+ mpjdev.natmpjdev.Intercomm nativeIntercomm = null;
+
+
+ //this constructor may be used to create intercommunicators.
+ Intercomm(mpjdev.Comm mpjdevComm, mpjdev.Group lGrp, mpjdev.Group rGrp,
+ mpi.Comm peerComm, int local_leader, int remote_leader,
+ mpi.Comm local_comm) {
+ this.local_leader = local_leader;
+ this.remote_leader = remote_leader;
+ this.peerComm = peerComm;
+ this.mpjdevComm = mpjdevComm;
+ this.group = new Group(rGrp);
+ this.localgroup = new Group(lGrp);
+ this.intercomm = true;
+ this.local_comm = local_comm;
+ //you ll have to agree on send_context and recv_context
+ if(Constants.isNative)
+ nativeIntercomm = new mpjdev.natmpjdev.Intercomm(
+ (mpjdev.natmpjdev.Comm) this.mpjdevComm);
+ }
+
+ /**
+ * Size of remote group.
+ * <p>
+ * <table>
+ * <tr><td><em> returns: </em></td><td> number of process in remote group
+ * of this communicator </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_REMOTE_SIZE</tt>.
+ */
+ public int Remote_size() throws MPIException {
+ return group.Size();
+ }
+
+ /**
+ * Return the remote group.
+ * <p>
+ * <table>
+ * <tr><td><em> returns: </em></td><td> remote group of this
+ * communicator </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_REMOTE_GROUP</tt>.
+ */
+ public Group Remote_group() throws MPIException {
+ return group;
+ }
+
+ /**
+ * Create an inter-communicator.
+ * <p>
+ * <table>
+ * <tr><td><tt> high </tt></td><td> true if the local group has higher
+ * ranks in combined group </tr>
+ * <tr><td><em> returns: </em></td><td> new intra-communicator </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_INTERCOMM_MERGE</tt>.
+ */
+ public Intracomm Merge(boolean high) throws MPIException {
+ //currently we ignore the boolean argument. According to the MPI specs,
+ //if all processes in either of the two groups provide an argument equal
+ //to 'high' and all the processes in the other group provide an argument
+ //'low', then the group with 'high' arg is the first argument to thie
+ //union method. Else, it doesn't matter. It is a collective call.
+ //Well i am ignoring low/high stuff at the moment. i am just combining
+ //them.
+ //System.out.println(" ****************** "+
+// "Intercomm.Merge only works if one group of processes "+
+// "specify high as 'true', and others specify high as "+
+// "'false'. The arbitrary case is not handled at the "+
+// "moment ***************** ");
+
+ try {
+
+
+ if(Constants.isNative){
+
+ mpjdev.Group mpjdevGroup = nativeIntercomm.Merge(high);
+ mpi.Group ngrp = new mpi.Group(mpjdevGroup);
+ return MPI.COMM_WORLD.Create(ngrp); //should work
+ }
+
+
+ Group ngrp = null;
+
+ if(high){
+ // System.out.println("Merge for high, localgroup.size = "+localgroup.Size()+" group = "+group.Size());
+ ngrp = Group.Union(group, localgroup);
+ }
+ else{
+ // System.out.println("Merge for NOT high , localgroup.size = "+localgroup.Size()+" group = "+group.Size());
+ ngrp = Group.Union(localgroup, group);
+
+ }
+ //System.out.println("going to create in merge\n");
+ return MPI.COMM_WORLD.Create(ngrp); //ooooo! that's very dogdy.
+
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * where would peer communicator come from ...and also localleader,
+ * and remoteleader ....
+ */
+ public Object clone() throws MPIException {
+ return peerComm.Create_intercomm(local_comm, local_leader,
+ remote_leader, 110);
+ //this 110 is abit ODD ...its OK to be "abit" ODD ;-)
+ }
+
+}
+
diff --git a/src/mpi/Intracomm.java b/src/mpi/Intracomm.java
new file mode 100755
index 0000000..366312c
--- /dev/null
+++ b/src/mpi/Intracomm.java
@@ -0,0 +1,1077 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+ 6. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Intracomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.30 $
+ * Updated : $Date: 2014/03/11 13:13:10 PKT $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+
+public class Intracomm extends Comm {
+
+ IntracommImpl intracommImpl = null;
+
+ Intracomm() {
+ }
+
+ /**
+ * Constructor used to create an intracomm
+ *
+ * @param mpjdev
+ * .Comm mpjdev.Group
+ *
+ **/
+
+ Intracomm(mpjdev.Comm mpjdevComm, mpjdev.Group _group) throws MPIException {
+ this.mpjdevComm = mpjdevComm;
+ this.group = new Group(_group);
+
+ if (Constants.isNative) {
+ intracommImpl = new NativeIntracomm(mpjdevComm, this.group);
+ } else {
+ intracommImpl = new PureIntracomm(mpjdevComm, this.group);
+ }
+
+ }
+
+ /**
+ * Constructor used to create an intracomm
+ *
+ * @param IntracommImpl
+ *
+ **/
+ Intracomm(IntracommImpl _IntracommImpl) throws MPIException {
+
+ // set the IntracommImpl
+ intracommImpl = _IntracommImpl;
+ this.mpjdevComm = intracommImpl.mpjdevComm;
+ this.group = intracommImpl.group;
+ }
+
+ /**
+ * Compare two communicators.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> comm1 </tt></td>
+ * <td>first communicator
+ * </tr>
+ * <tr>
+ * <td><tt> comm2 </tt></td>
+ * <td>second communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>result
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ * <p>
+ * <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ * references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ * <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ * but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ * the underlying groups are similar but the communicators differ by context.
+ * <tt>MPI.UNEQUAL</tt>(2) results otherwise.
+ */
+
+ public static int Compare(Comm comm1, Comm comm2) throws MPIException {
+
+ // return intracommImpl.Compare(comm1, comm2);
+ if (Constants.isNative) {
+ // System.out.println("calling nativeIntracomm compare ");
+ // in case of native
+ return mpi.NativeIntracomm.Compare(comm1, comm2);
+ } else {
+ return mpi.Comm.Compare(comm1, comm2);
+ }
+
+ // return IntracommImpl.Compare(comm1, comm2);
+ }
+
+ /**
+ * Partition the group associated with this communicator and create a new
+ * communicator within each subgroup.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> color </tt></td>
+ * <td>control of subset assignment
+ * </tr>
+ * <tr>
+ * <td><tt> key </tt></td>
+ * <td>control of rank assignment
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_SPLIT</tt>.
+ */
+ public Intracomm Split(int color, int key) throws MPIException {
+
+ IntracommImpl nIntracommImpl = intracommImpl.Split(color, key);
+
+ return new Intracomm(nIntracommImpl);
+ }
+
+ /**
+ * Clone the communicator This method will be called only by intracommunicator
+ * .... changed the return value to Intracomm ...(instead of Object) ...
+ */
+ public Object clone() throws MPIException {
+
+ IntracommImpl nIntracommImpl = (IntracommImpl) intracommImpl.clone();
+ return (Object) new Intracomm(nIntracommImpl);
+ }
+
+ /**
+ * Create a new communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group </tt></td>
+ * <td>group which is a subset of the group of this communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_CREATE</tt>.
+ */
+
+ public Intracomm Create(Group group) throws MPIException {
+
+ IntracommImpl nIntracommImpl = intracommImpl.Create(group);
+ return new Intracomm(nIntracommImpl);
+
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * /** A call to <tt>Barrier</tt> blocks the caller until all process in the
+ * group have called it.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BARRIER</tt>.
+ */
+ public void Barrier() throws MPIException {
+ intracommImpl.Barrier();
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of broadcast root
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BCST</tt>.
+ */
+
+ public void Bcast(Object buf, int offset, int count, Datatype type, int root)
+ throws MPIException {
+
+ intracommImpl.Bcast(buf, offset, count, type, root);
+
+ }
+
+ /**
+ * Each process sends the contents of its send buffer to the root process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHER</tt>.
+ */
+ public void Gather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) throws MPIException {
+
+ intracommImpl.Gather(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+
+ }
+
+ /**
+ * Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ * from each process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ * <p>
+ * The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ * size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ * displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt> at
+ * which to place incoming data.
+ */
+ public void Gatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype, int root) throws MPIException {
+
+ intracommImpl.Gatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype, root);
+ }
+
+ /**
+ * Inverse of the operation <tt>Gather</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTER</tt>.
+ */
+
+ public void Scatter(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) throws MPIException {
+
+ intracommImpl.Scatter(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+
+ }
+
+ /**
+ * Inverse of the operation <tt>Gatherv</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.
+ */
+ public void Scatterv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] displs, Datatype sendtype, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int root) throws MPIException {
+
+ intracommImpl.Scatterv(sendbuf, sendoffset, sendcount, displs, sendtype,
+ recvbuf, recvoffset, recvcount, recvtype, root);
+
+ }
+
+ /**
+ * Similar to <tt>Gather</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.
+ */
+
+ public void Allgather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) throws MPIException {
+
+ intracommImpl.Allgather(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype);
+
+ }
+
+ /**
+ * Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.
+ */
+ public void Allgatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype) throws MPIException {
+
+ intracommImpl.Allgatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype);
+ }
+
+ /**
+ * Extension of <tt>Allgather</tt> to the case where each process sends
+ * distinct data to each of the receivers.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items received from any process
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of receive buffer items
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.
+ */
+
+ public void Alltoall(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) throws MPIException {
+
+ intracommImpl.Alltoall(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype);
+ }
+
+ /**
+ * Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ * specified by <tt>sdispls</tt> and location to place data on receive side is
+ * specified by <tt>rdispls</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sdispls </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * <tr>
+ * <td><tt> rdispls </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.
+ */
+
+ public void Alltoallv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] sdispls, Datatype sendtype, Object recvbuf, int recvoffset,
+ int[] recvcount, int[] rdispls, Datatype recvtype) throws MPIException {
+
+ intracommImpl.Alltoallv(sendbuf, sendoffset, sendcount, sdispls, sendtype,
+ recvbuf, recvoffset, recvcount, rdispls, recvtype);
+
+ }
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and return the combined value in the output buffer of the root
+ * process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of root process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ * <p>
+ * The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ * <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ * <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ * <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.
+ */
+
+ public void Reduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op, int root)
+ throws MPIException {
+
+ intracommImpl.Reduce(sendbuf, sendoffset, recvbuf, recvoffset, count,
+ datatype, op, root);
+
+ }
+
+ /**
+ * Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ * all process in the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.
+ */
+
+ public void Allreduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) throws MPIException {
+
+ intracommImpl.Allreduce(sendbuf, sendoffset, recvbuf, recvoffset, count,
+ datatype, op);
+
+ }
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and scatter the combined values over the output buffers of the
+ * processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>numbers of result elements distributed to each process
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.
+ */
+ public void Reduce_scatter(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int[] recvcounts, Datatype datatype, Op op)
+ throws MPIException {
+
+ intracommImpl.Reduce_scatter(sendbuf, sendoffset, recvbuf, recvoffset,
+ recvcounts, datatype, op);
+
+ }
+
+ /**
+ * Perform a prefix reduction on data distributed across the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCAN</tt>.
+ */
+
+ public void Scan(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) throws MPIException {
+
+ intracommImpl.Scan(sendbuf, sendoffset, recvbuf, recvoffset, count,
+ datatype, op);
+
+ }
+
+ /**
+ * Create a Cartesian topology communicator whose group is a subset of the
+ * group of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> dims </tt></td>
+ * <td>the number of processes in each dimension
+ * </tr>
+ * <tr>
+ * <td><tt> periods </tt></td>
+ * <td> <tt>true</tt> if grid is periodic, <tt>false</tt> if not, in each
+ * dimension
+ * </tr>
+ * <tr>
+ * <td><tt> reorder </tt></td>
+ * <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new Cartesian topology communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_CREATE</tt>.
+ * <p>
+ * The number of dimensions of the Cartesian grid is taken to be the size of
+ * the <tt>dims</tt> argument. The array <tt>periods</tt> must be the same
+ * size.
+ */
+ public Cartcomm Create_cart(int[] dims, boolean[] periods, boolean reorder)
+ throws MPIException {
+
+ int totalProcess = this.group.Size();
+ int places = 1;
+ mpjdev.Comm ncomm = mpjdevComm;
+ mpi.Group ngroup = this.group;
+
+ for (int i = 0; i < dims.length; i++) {
+ if (dims[i] < 0) {
+ throw new MPIException("dims[" + i + "] is less than than zero");
+ }
+ places *= dims[i];
+ }
+
+ // MPI.logger.debug("places "+places);
+ // MPI.logger.debug("totalProcesses "+totalProcess);
+
+ if (places > totalProcess) {
+ throw new MPIException(" Error in Intracomm.Create_cart: "
+ + "total grid positions <" + places + "> are greater than "
+ + " total processes <" + totalProcess + ">");
+ } else if (places < totalProcess) {
+
+ // MPI.logger.debug("dropping some processes ...");
+ int[] excl = new int[totalProcess - places];
+ // MPI.logger.debug("length of excl array "+excl.length);
+
+ for (int i = 0; i < excl.length; i++) {
+ excl[i] = i + places;
+ }
+ try {
+ // MPI.logger.debug("calling excl method .");
+
+ ngroup = ngroup.Excl(excl);
+
+ // MPI.logger.debug( "called excl .. creating "+
+ // "new group now" );
+ ncomm = ncomm.create(ngroup.mpjdevGroup);
+
+ // MPI.logger.debug("created the new comm");
+
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ } else {
+
+ // MPI.logger.debug("All OK");
+ ngroup = group;
+
+ try {
+
+ ncomm = ncomm.create(ngroup.mpjdevGroup);
+
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ // MPI.logger.debug("oldRank "+group.Rank()+">,nrank<"+ngroup.Rank());
+ if (ngroup.Rank() == -1) {
+ // MPI.logger.debug("means this process is not in the "+
+ // "new group");
+ return null; // comm stuff ...
+ }
+
+ return new Cartcomm(dims, periods, reorder, ncomm, ngroup.mpjdevGroup);
+ }
+
+ /**
+ * Create a graph topology communicator whose group is a subset of the group
+ * of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> index </tt></td>
+ * <td>node degrees
+ * </tr>
+ * <tr>
+ * <td><tt> edges </tt></td>
+ * <td>graph edges
+ * </tr>
+ * <tr>
+ * <td><tt> reorder </tt></td>
+ * <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new graph topology communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GRAPH_CREATE</tt>.
+ * <p>
+ * The number of nodes in the graph, <em>nnodes</em>, is taken to be size of
+ * the <tt>index</tt> argument. The size of array <tt>edges</tt> must be
+ * <tt>index [nnodes} - 1]</tt>.
+ */
+ public Graphcomm Create_graph(int[] index, int[] edges, boolean reorder) {
+ int size = this.group.Size();
+ int nnodes = index.length;
+ mpjdev.Comm ncomm = mpjdevComm;
+ mpi.Group ngroup = this.group;
+
+ // MPI.logger.debug("nnodes "+nnodes);
+ // MPI.logger.debug("size "+size);
+
+ if (nnodes > size) {
+ throw new MPIException(" Error in Intracomm.Create_graphs: "
+ + "total nodes <" + nnodes + "> are greater than "
+ + " total processes <" + size + ">");
+ } else if (nnodes < size) {
+ // MPI.logger.debug("dropping some processes ...");
+ int[] excl = new int[size - nnodes];
+ // MPI.logger.debug("length of excl array "+excl.length);
+
+ for (int i = 0; i < excl.length; i++) {
+ excl[i] = i + nnodes;
+ }
+
+ try {
+ // MPI.logger.debug("calling excl method .");
+ ngroup = ngroup.Excl(excl);
+ // MPI.logger.debug( "called excl .. creating "+
+ // "new group now" );
+ ncomm = ncomm.create(ngroup.mpjdevGroup);
+ // MPI.logger.debug("created the new comm");
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ } else {
+ // MPI.logger.debug("All OK");
+ ngroup = group;
+
+ try {
+ ncomm = ncomm.create(ngroup.mpjdevGroup);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ // MPI.logger.debug("oldRank "+group.Rank()+">,nrank<"+ngroup.Rank());
+
+ if (ngroup.Rank() == -1) {
+ // MPI.logger.debug("means this process is not in the "+
+ // "new group");
+ return null; // comm stuff ...
+ }
+
+ return new Graphcomm(index, edges, reorder, ncomm, ngroup.mpjdevGroup);
+ }
+
+}
diff --git a/src/mpi/IntracommImpl.java b/src/mpi/IntracommImpl.java
new file mode 100755
index 0000000..065d569
--- /dev/null
+++ b/src/mpi/IntracommImpl.java
@@ -0,0 +1,506 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Intracomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.30 $
+ * Updated : $Date: 2006/10/20 17:24:47 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+
+public abstract class IntracommImpl
+ extends Comm {
+
+ IntracommImpl() {
+ }
+
+
+
+ /**
+ * Partition the group associated with this communicator and create
+ * a new communicator within each subgroup.
+ * <p>
+ * <table>
+ * <tr><td><tt> color </tt></td><td> control of subset assignment </tr>
+ * <tr><td><tt> key </tt></td><td> control of rank assignment </tr>
+ * <tr><td><em> returns: </em></td><td> new communicator </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_SPLIT</tt>.
+ */
+ public abstract IntracommImpl Split(int color, int key);
+
+ /**
+ * Clone the communicator
+ * This method will be called only by intracommunicator ....
+ * changed the return value to Intracomm ...(instead of Object) ...
+ */
+ public abstract Object clone();
+ /**
+ * Create a new communicator.
+ * <p>
+ * <table>
+ * <tr><td><tt> group </tt></td><td> group which is a subset of the
+ * group of this communicator </tr>
+ * <tr><td><em> returns: </em></td><td> new communicator </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_CREATE</tt>.
+ */
+ public abstract IntracommImpl Create(Group group);
+
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt>
+ * to all processes of the group.
+ * <p>
+ * <table>
+ * <tr><td><tt> buf </tt></td><td> buffer array </tr>
+ * <tr><td><tt> offset </tt></td><td> initial offset in buffer </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in buffer </tr>
+ * <tr><td><tt> datatype </tt></td><td> datatype of each item in
+ * buffer </tr>
+ /**
+ * A call to <tt>Barrier</tt> blocks the caller until all process
+ * in the group have called it.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BARRIER</tt>.
+ */
+ public abstract void Barrier();
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt>
+ * to all processes of the group.
+ * <p>
+ * <table>
+ * <tr><td><tt> buf </tt></td><td> buffer array </tr>
+ * <tr><td><tt> offset </tt></td><td> initial offset in buffer </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in buffer </tr>
+ * <tr><td><tt> datatype </tt></td><td> datatype of each item in
+ * buffer </tr>
+ * <tr><td><tt> root </tt></td><td> rank of broadcast root </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BCST</tt>.
+ */
+
+ public abstract void Bcast(Object buf,
+ int offset,
+ int count,
+ Datatype type,
+ int root) ;
+
+
+ /**
+ * Each process sends the contents of its send buffer to the
+ * root process.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items to send </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcount </tt></td><td> number of items to receive </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * <tr><td><tt> root </tt></td><td> rank of receiving process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHER</tt>.
+ */
+ public abstract void Gather(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ Datatype recvtype,
+ int root);
+
+
+ /**
+ * Extends functionality of <tt>Gather</tt> by allowing varying
+ * counts of data from each process.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items to send </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcounts </tt></td><td> number of elements received from
+ * each process </tr>
+ * <tr><td><tt> displs </tt></td><td> displacements at which to place
+ * incoming data </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * <tr><td><tt> root </tt></td><td> rank of receiving process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ * <p>
+ * The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ * size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ * displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt>
+ * at which to place incoming data.
+ */
+ public abstract void Gatherv(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ Datatype recvtype,
+ int root) ;
+
+ /**
+ * Inverse of the operation <tt>Gather</tt>.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items to send </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcount </tt></td><td> number of items to receive </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * <tr><td><tt> root </tt></td><td> rank of sending process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTER</tt>.
+ */
+
+
+ public abstract void Scatter(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ Datatype recvtype,
+ int root);
+
+
+ /**
+ * Inverse of the operation <tt>Gatherv</tt>.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcounts </tt></td><td> number of items sent to each
+ * process </tr>
+ * <tr><td><tt> displs </tt></td><td> displacements from which to take
+ * outgoing data </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcount </tt></td><td> number of items to receive </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * <tr><td><tt> root </tt></td><td> rank of sending process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.
+ */
+ public abstract void Scatterv(Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] displs,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ Datatype recvtype,
+ int root);
+
+
+ /**
+ * Similar to <tt>Gather</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items to send </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcount </tt></td><td> number of items to receive </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.
+ */
+
+ public abstract void Allgather(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ Datatype recvtype) ;
+
+
+
+ /**
+ * Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items to send </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype of each item in send
+ * buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcounts </tt></td><td> number of elements received from
+ * each process </tr>
+ * <tr><td><tt> displs </tt></td><td> displacements at which to place
+ * incoming data </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.
+ */
+ public abstract void Allgatherv(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] displs,
+ Datatype recvtype);
+
+ /**
+ * Extension of <tt>Allgather</tt> to the case where each process sends
+ * distinct data to each of the receivers.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcount </tt></td><td> number of items sent to each
+ * process </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype send buffer items </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcount </tt></td><td> number of items received from any
+ * process
+ * <tr><td><tt> recvtype </tt></td><td> datatype of receive buffer
+ * items </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.
+ */
+
+
+ public abstract void Alltoall(Object sendbuf,
+ int sendoffset,
+ int sendcount,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int recvcount,
+ Datatype recvtype);
+
+ /**
+ * Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ * specified by <tt>sdispls</tt> and location to place data on receive
+ * side is specified by <tt>rdispls</tt>.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> sendcounts </tt></td><td> number of items sent to each
+ * process </tr>
+ * <tr><td><tt> sdispls </tt></td><td> displacements from which to take
+ * outgoing data </tr>
+ * <tr><td><tt> sendtype </tt></td><td> datatype send buffer items </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcounts </tt></td><td> number of elements received from
+ * each process
+ * <tr><td><tt> rdispls </tt></td><td> displacements at which to place
+ * incoming data </tr>
+ * <tr><td><tt> recvtype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.
+ */
+
+ public abstract void Alltoallv(Object sendbuf,
+ int sendoffset,
+ int[] sendcount,
+ int[] sdispls,
+ Datatype sendtype,
+ Object recvbuf,
+ int recvoffset,
+ int[] recvcount,
+ int[] rdispls,
+ Datatype recvtype);
+
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and return the combined value in the output buffer of the
+ * root process.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in send buffer </tr>
+ * <tr><td><tt> datatype </tt></td><td> data type of each item in send
+ * buffer </tr>
+ * <tr><td><tt> op </tt></td><td> reduce operation </tr>
+ * <tr><td><tt> root </tt></td><td> rank of root process </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ * <p>
+ * The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ * <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ * <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ * <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.
+ */
+
+ public abstract void Reduce(Object sendbuf, int sendoffset,
+ Object recvbuf, int recvoffset, int count,
+ Datatype datatype, Op op, int root);
+
+
+
+ /**
+ * Same as <tt>reduce</tt> except that the result appears in receive
+ * buffer of all process in the group.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in send buffer </tr>
+ * <tr><td><tt> datatype </tt></td><td> data type of each item in send
+ * buffer </tr>
+ * <tr><td><tt> op </tt></td><td> reduce operation </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.
+ */
+
+
+
+ public abstract void Allreduce(Object sendbuf, int sendoffset,
+ Object recvbuf, int recvoffset, int count,
+ Datatype datatype, Op op);
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and scatter the combined values over the output buffers
+ * of the processes.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> recvcounts </tt></td><td> numbers of result elements
+ * distributed to each process </tr>
+ * <tr><td><tt> datatype </tt></td><td> data type of each item in send
+ * buffer </tr>
+ * <tr><td><tt> op </tt></td><td> reduce operation </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.
+ */
+ public abstract void Reduce_scatter(Object sendbuf, int sendoffset,
+ Object recvbuf, int recvoffset, int[] recvcounts,
+ Datatype datatype, Op op);
+
+
+ /**
+ * Perform a prefix reduction on data distributed across the group.
+ * <p>
+ * <table>
+ * <tr><td><tt> sendbuf </tt></td><td> send buffer array </tr>
+ * <tr><td><tt> sendoffset </tt></td><td> initial offset in send buffer </tr>
+ * <tr><td><tt> recvbuf </tt></td><td> receive buffer array </tr>
+ * <tr><td><tt> recvoffset </tt></td><td> initial offset in receive
+ * buffer </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in input
+ * buffer </tr>
+ * <tr><td><tt> datatype </tt></td><td> data type of each item in input
+ * buffer </tr>
+ * <tr><td><tt> op </tt></td><td> reduce operation </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCAN</tt>.
+ */
+
+ public abstract void Scan(Object sendbuf, int sendoffset,
+ Object recvbuf, int recvoffset, int count,
+ Datatype datatype, Op op) ;
+
+}
+
diff --git a/src/mpi/Land.java b/src/mpi/Land.java
new file mode 100644
index 0000000..69048dc
--- /dev/null
+++ b/src/mpi/Land.java
@@ -0,0 +1,49 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Land.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Land extends Op {
+
+ Land() {
+ worker = new LandWorker();
+ this.opCode = mpjdev.Constants.LAND_CODE;
+ }
+
+}
diff --git a/src/mpi/LandBoolean.java b/src/mpi/LandBoolean.java
new file mode 100644
index 0000000..1679ceb
--- /dev/null
+++ b/src/mpi/LandBoolean.java
@@ -0,0 +1,72 @@
+/* This file generated automatically from template LandType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LandBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class LandBoolean extends Land {
+ boolean [] arr = null;
+ LandBoolean() {
+ }
+
+ public void perform (Object buf1, int offset, int count)
+ throws MPIException {
+
+ boolean[] arr1 = (boolean[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] && arr[i];
+ //this is bit-wise AND ..logical AND is && and its between
+ //two conditions ...not two integers ..or any other type ...
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ arr = new boolean[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/LandType.java.in b/src/mpi/LandType.java.in
new file mode 100644
index 0000000..699afb9
--- /dev/null
+++ b/src/mpi/LandType.java.in
@@ -0,0 +1,71 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Land at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Land at Type@ extends Land {
+ @type@ [] arr = null;
+ Land at Type@() {
+ }
+
+ public void perform (Object buf1, int offset, int count)
+ throws MPIException {
+
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] && arr[i];
+ //this is bit-wise AND ..logical AND is && and its between
+ //two conditions ...not two integers ..or any other type ...
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/LandWorker.java b/src/mpi/LandWorker.java
new file mode 100644
index 0000000..336f5f1
--- /dev/null
+++ b/src/mpi/LandWorker.java
@@ -0,0 +1,79 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LandWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class LandWorker
+ implements OpWorker {
+
+ LandWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ throw new MPIException(" MPI.LAND is invalid for MPI.BYTE");
+
+ case Datatype.CHAR:
+ throw new MPIException(" MPI.LAND is invalid for MPI.CHAR");
+
+ case Datatype.SHORT:
+ throw new MPIException(" MPI.LAND is invalid for MPI.SHORT");
+
+ case Datatype.BOOLEAN:
+ return new LandBoolean();
+
+ case Datatype.INT:
+ throw new MPIException(" MPI.LAND is invalid for MPI.INT");
+
+ case Datatype.LONG:
+ throw new MPIException(" MPI.LAND is invalid for MPI.LONG");
+
+ case Datatype.FLOAT:
+ throw new MPIException(" MPI.LAND is invalid for MPI.FLOAT");
+
+ case Datatype.DOUBLE:
+ throw new MPIException(" MPI.LAND is invalid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/Lor.java b/src/mpi/Lor.java
new file mode 100644
index 0000000..d2cf133
--- /dev/null
+++ b/src/mpi/Lor.java
@@ -0,0 +1,49 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Lor.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Lor extends Op {
+
+ Lor() {
+ worker = new LorWorker();
+ this.opCode = mpjdev.Constants.LOR_CODE;
+ }
+
+}
diff --git a/src/mpi/LorBoolean.java b/src/mpi/LorBoolean.java
new file mode 100644
index 0000000..58d28f5
--- /dev/null
+++ b/src/mpi/LorBoolean.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template LorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LorBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class LorBoolean extends Lor {
+ boolean [] arr = null;
+ LorBoolean() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ boolean[] arr1 = (boolean[]) buf1;
+
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] || arr[i];
+ //again this is bit-wise OR ..not logical OR
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ arr = new boolean[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/LorType.java.in b/src/mpi/LorType.java.in
new file mode 100644
index 0000000..7a7e179
--- /dev/null
+++ b/src/mpi/LorType.java.in
@@ -0,0 +1,70 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Lor at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Lor at Type@ extends Lor {
+ @type@ [] arr = null;
+ Lor at Type@() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ @type@[] arr1 = (@type@[]) buf1;
+
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] || arr[i];
+ //again this is bit-wise OR ..not logical OR
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/LorWorker.java b/src/mpi/LorWorker.java
new file mode 100644
index 0000000..9d6a4d2
--- /dev/null
+++ b/src/mpi/LorWorker.java
@@ -0,0 +1,79 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LorWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class LorWorker
+ implements OpWorker {
+
+ LorWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ throw new MPIException(" MPI.LOR is invalid for MPI.BYTE");
+
+ case Datatype.CHAR:
+ throw new MPIException(" MPI.LOR is invalid for MPI.CHAR");
+
+ case Datatype.SHORT:
+ throw new MPIException(" MPI.LOR is invalid for MPI.SHORT");
+
+ case Datatype.BOOLEAN:
+ return new LorBoolean();
+
+ case Datatype.INT:
+ throw new MPIException(" MPI.LOR is invalid for MPI.INT");
+
+ case Datatype.LONG:
+ throw new MPIException(" MPI.LOR is invalid for MPI.LONG");
+
+ case Datatype.FLOAT:
+ throw new MPIException(" MPI.LOR is invalid for MPI.FLOAT");
+
+ case Datatype.DOUBLE:
+ throw new MPIException(" MPI.LOR is invalid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/Lxor.java b/src/mpi/Lxor.java
new file mode 100644
index 0000000..8f53721
--- /dev/null
+++ b/src/mpi/Lxor.java
@@ -0,0 +1,47 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Lxor.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Lxor extends Op {
+ Lxor() {
+ worker = new LxorWorker();
+ this.opCode = mpjdev.Constants.LXOR_CODE;
+ }
+}
diff --git a/src/mpi/LxorBoolean.java b/src/mpi/LxorBoolean.java
new file mode 100644
index 0000000..3dd4c55
--- /dev/null
+++ b/src/mpi/LxorBoolean.java
@@ -0,0 +1,70 @@
+/* This file generated automatically from template LxorType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LxorBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class LxorBoolean extends Lxor {
+ boolean [] arr = null;
+ LxorBoolean() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ boolean[] arr1 = (boolean[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] ^ arr[i];
+ //this is bit-wise OR ..
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ arr = new boolean[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ boolean[] tempArray = (boolean[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/LxorType.java.in b/src/mpi/LxorType.java.in
new file mode 100644
index 0000000..6110340
--- /dev/null
+++ b/src/mpi/LxorType.java.in
@@ -0,0 +1,69 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Lxor at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Lxor at Type@ extends Lxor {
+ @type@ [] arr = null;
+ Lxor at Type@() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = offset; i < count; i++) {
+ arr[i] = arr1[i] ^ arr[i];
+ //this is bit-wise OR ..
+ }
+
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/LxorWorker.java b/src/mpi/LxorWorker.java
new file mode 100644
index 0000000..08de0e3
--- /dev/null
+++ b/src/mpi/LxorWorker.java
@@ -0,0 +1,78 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : LxorWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class LxorWorker
+ implements OpWorker {
+ LxorWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ throw new MPIException("MPI.LXOR is invalid for MPI.BYTE");
+
+ case Datatype.CHAR:
+ throw new MPIException("MPI.LXOR is invalid for MPI.CHAR");
+
+ case Datatype.SHORT:
+ throw new MPIException("MPI.LXOR is invalid for MPI.SHORT");
+
+ case Datatype.BOOLEAN:
+ return new LxorBoolean();
+
+ case Datatype.INT:
+ throw new MPIException("MPI.LXOR is invalid for MPI.INT");
+
+ case Datatype.LONG:
+ throw new MPIException("MPI.LXOR is invalid for MPI.LONG");
+
+ case Datatype.FLOAT:
+ throw new MPIException("MPI.LXOR is invalid for MPI.FLOAT");
+
+ case Datatype.DOUBLE:
+ throw new MPIException("MPI.LXOR is invalid for MPI.DOUBLE");
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/MPI.java b/src/mpi/MPI.java
new file mode 100755
index 0000000..b732f16
--- /dev/null
+++ b/src/mpi/MPI.java
@@ -0,0 +1,468 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPI.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+import java.util.Hashtable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.DailyRollingFileAppender;
+import org.apache.log4j.spi.LoggerRepository;
+
+public class MPI {
+
+ public static final boolean DEBUG = false;
+ // public static final boolean DEBUG = false;
+ static Logger logger = null;
+
+ public static Intracomm COMM_WORLD;
+ private static boolean initialized = false;
+ static boolean debug = true;
+
+ static ByteBuffer buffer = null;
+ static ArrayList<Request> pendingRequests = new ArrayList<Request>();
+
+ static final int OP_BSEND = 1;
+ static final int OP_RSEND = 2;
+ static final int OP_SEND = 3;
+ static final int OP_RECV = 4;
+ static final int OP_SSEND = 5;
+ public static final int NUM_OF_PROCESSORS = Runtime.getRuntime()
+ .availableProcessors();
+
+ static Status UNDEFINED_STATUS = new Status(-1, -1, -1);
+
+ // public static Datatype UNDEFINED = new BasicType( -1);
+ public static int UNDEFINED = -1;
+ public static Datatype NULL = new BasicType(0);
+ public static Datatype BYTE = new BasicType(1);
+ public static Datatype CHAR = new BasicType(2);
+ public static Datatype SHORT = new BasicType(3);
+ public static Datatype BOOLEAN = new BasicType(4);
+ public static Datatype INT = new BasicType(5);
+ public static Datatype LONG = new BasicType(6);
+ public static Datatype FLOAT = new BasicType(7);
+ public static Datatype DOUBLE = new BasicType(8);
+ public static Datatype PACKED = new BasicType(9);
+ public static Datatype LB = new BasicType(10);
+ public static Datatype UB = new BasicType(11);
+ public static Datatype OBJECT = new BasicType(12);
+
+ public static int THREAD_SINGLE = 1;
+ public static int THREAD_FUNNELED = 2;
+ public static int THREAD_SERIALIZED = 3;
+ public static int THREAD_MULTIPLE = 4;
+
+ /**
+ * Its actually not good to call the following basic datatypes because they
+ * are not ... this will be changed to sometyhing else ...need to think about
+ * it
+ */
+ public static Datatype SHORT2 = Datatype.Contiguous(2, MPI.SHORT);
+ public static Datatype INT2 = Datatype.Contiguous(2, MPI.INT);
+ public static Datatype LONG2 = Datatype.Contiguous(2, MPI.LONG);
+ public static Datatype FLOAT2 = Datatype.Contiguous(2, MPI.FLOAT);
+ public static Datatype DOUBLE2 = Datatype.Contiguous(2, MPI.DOUBLE);
+
+ public static Op MAX = new Max();
+ public static Op MIN = new Min();
+ public static Op SUM = new Sum();
+ public static Op PROD = new Prod();
+ public static Op LAND = new Land();
+ public static Op BAND = new Band();
+ public static Op LOR = new Lor();
+ public static Op BOR = new Bor();
+ public static Op LXOR = new Lxor();
+ public static Op BXOR = new Bxor();
+ public static Op MAXLOC = new Op(new Maxloc(), true,
+ mpjdev.Constants.MAXLOC_CODE);
+ public static Op MINLOC = new Op(new Minloc(), true,
+ mpjdev.Constants.MINLOC_CODE);
+
+ public static int ANY_SOURCE = -2, ANY_TAG = -2;
+
+ public static Status EMPTY_STATUS = new Status(MPI.ANY_SOURCE, MPI.ANY_TAG,
+ 0, 0);
+ public static int PROC_NULL = -3;
+
+ /**
+ * Overhead incurred by buffered send. This variable should be accessed after
+ * calling #Init(String[] args) method.
+ */
+ public static int BSEND_OVERHEAD;
+
+ /**
+ * These should be accessed after calling MPI.Init()
+ */
+ public static int SEND_OVERHEAD, RECV_OVERHEAD;
+ // public static Datatype UNDEFINED;
+ // This is initialized in the MPJDev.Init() and is then assigned from
+ // Constants.GROUP_EMPTY
+ public static Group GROUP_EMPTY;// = new mpi.Group(
+ // new mpjdev.Group(new xdev.ProcessID[0], null,-1));
+
+ public static Comm COMM_SELF;
+ public static final int IDENT = 0, CONGRUENT = 3, SIMILAR = 1, UNEQUAL = 2;
+ public static int GRAPH = 1, CART = 2;
+ public static Errhandler ERRORS_ARE_FATAL, ERRORS_RETURN;
+ public static int TAG_UB, HOST, IO;
+ public static Request REQUEST_NULL = new mpi.Request(true);
+ public static Comm COMM_NULL;
+ public static Group GROUP_NULL;
+
+ /**
+ * Provides to MPI a buffer in user's memory to be used for buffering outgoing
+ * messages. Java binding of the MPI operation <tt>MPI_BUFFER_ATTACH</tt>.
+ */
+ public static void Buffer_attach(ByteBuffer userBuffer) throws MPIException {
+ buffer = userBuffer;
+ }
+
+ /**
+ * Detach the buffer currently associated with MPI. Java binding of the MPI
+ * operation <tt>MPI_BUFFER_DETACH</tt>.
+ */
+ public static void Buffer_detach() throws MPIException {
+
+ synchronized (pendingRequests) {
+
+ for (Request pending : pendingRequests) {
+ // apparently may not make sense for bsend, but under the hoods
+ // bsend is using isend for comms, and there is a request
+ // object attached
+
+ pending.Wait();
+ }
+
+ buffer = null;
+
+ }
+
+ Comm.PendingMessage.clearFront();
+
+ }
+
+ /**
+ * Used to initialize MPI with certain level of threadedness ...
+ */
+ public static String[] initThread(int required, int provided, String[] argv) {
+ return null;
+ }
+
+ /**
+ * Returns true if this thread initialized MPI
+ */
+ public static boolean isMainThread() {
+ return true;
+ }
+
+ /**
+ * Returns the level of thread support provided by the MPI library and the
+ * underlying device selected
+ */
+ public static int queryThread() {
+ return MPI.THREAD_MULTIPLE;
+ }
+
+ /**
+ * Initialize MPI.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> args </tt></td>
+ * <td>arguments to <tt>main</tt> method.
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_INIT</tt>.
+ */
+ public static String[] Init(String[] argv) throws MPIException {
+
+ if (argv.length < 3) {
+ throw new MPIException("Usage: "
+ + "java MPI <myrank> <conf_file> <device_name> "
+ + "conf_file can be, ../conf/xdev.conf <Local>"
+ + "OR http://holly.dsg.port.ac.uk:15000/xdev.conf <Remote>");
+ }
+
+ DailyRollingFileAppender fileAppender = null;
+ int rank = Integer.parseInt(argv[0]);
+ Map<String, String> map = System.getenv();
+ String mpjHomeDir = map.get("MPJ_HOME");
+
+ if (logger == null && DEBUG) {
+ try {
+ fileAppender = new DailyRollingFileAppender(new PatternLayout(
+ " %-5p %c %x - %m\n"), mpjHomeDir + "/logs/mpj" + rank + ".log",
+ "yyyy-MM-dd-HH");
+
+ Logger rootLogger = Logger.getRootLogger();
+ rootLogger.addAppender(fileAppender);
+ LoggerRepository rep = rootLogger.getLoggerRepository();
+ rootLogger.setLevel((Level) Level.ALL);
+ // rep.setThreshold((Level) Level.OFF ) ;
+ logger = Logger.getLogger("mpj");
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ try {
+ mpjdev.MPJDev.init(argv);
+ GROUP_EMPTY = new mpi.Group(null);
+
+ BSEND_OVERHEAD = MPJDev.getSendOverhead();
+ SEND_OVERHEAD = BSEND_OVERHEAD;
+ RECV_OVERHEAD = MPJDev.getRecvOverhead();
+
+ COMM_WORLD = new Intracomm(mpjdev.MPJDev.WORLD, mpjdev.MPJDev.WORLD.group);
+
+ int tagub = Integer.MAX_VALUE;
+
+ if(mpjdev.Constants.isNative)
+ tagub = ((mpjdev.natmpjdev.Comm) COMM_WORLD.mpjdevComm).getMPI_TAG_UB();
+
+
+ COMM_WORLD.Attr_put(MPI.TAG_UB, tagub);
+ COMM_WORLD.Attr_put(MPI.HOST, PROC_NULL);
+ COMM_WORLD.Attr_put(MPI.IO, COMM_WORLD.Rank());
+
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ int[] self = { COMM_WORLD.Rank() };
+ Group selfGroup = COMM_WORLD.group.Incl(self);
+ COMM_SELF = COMM_WORLD.Create(selfGroup);
+
+ int[] empty = new int[0];
+ GROUP_EMPTY = COMM_WORLD.group.Incl(empty);
+ GROUP_EMPTY.code = Group.EMPTY;
+
+ // use these three in case of errors..
+ GROUP_NULL = new Group(Group.NULL);
+ COMM_NULL = new Comm(Comm.NULL);
+ // REQUEST_NULL = new Request(Request.NULL) ;
+
+ ERRORS_ARE_FATAL = new Errhandler(Errhandler.FATAL);
+ ERRORS_ARE_FATAL = new Errhandler(Errhandler.RETURN);
+
+ /*
+ * this is 3 coz i know MPI/MPJDev/xdev init methods only use the first four
+ * arguments ..if in future, we write a device which takes more argument,
+ * then this '3' may have to be changed
+ */
+ String[] nargs = null;
+ if (argv[2].equals("hybdev")){
+ nargs = new String[(argv.length - 8)];
+ System.arraycopy(argv, 8, nargs, 0, nargs.length);
+ }else {
+ nargs = new String[(argv.length - 3)];
+ System.arraycopy(argv, 3, nargs, 0, nargs.length);
+ }
+ initialized = true;
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("pendingQue.size " + pendingRequests.size());
+ logger.debug(" queue_size (init) " + Comm.PendingMessage.queue_size);
+ }
+
+ return nargs;
+ }
+
+ /**
+ * Finalize MPI.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_FINALIZE</tt>.
+ */
+ public static void Finalize() throws MPIException {
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("calling detach");
+ }
+
+ MPI.Buffer_detach();
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("called detach");
+ logger.debug(" queue_size (exit) " + Comm.PendingMessage.queue_size);
+ logger.debug("pendingQue.size " + pendingRequests.size());
+ logger.debug("calling last barrier");
+ }
+
+ try {
+ COMM_WORLD.Barrier();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new MPIException(e);
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Called it");
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Calling MPJDev finalize ");
+ }
+
+ try {
+ mpjdev.MPJDev.finish();
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Called it ...");
+ }
+
+ initialized = false;
+
+ }
+
+ /**
+ * Returns the name of the processor on which it is called.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>A unique specifier for the actual node.
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GET_PROCESSOR_NAME</tt>.
+ */
+ public static String Get_processor_name() throws MPIException {
+ try {
+ java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
+ byte[] ipAddr = addr.getAddress();
+ String hostname = addr.getHostName();
+ return hostname;
+ }
+ catch (java.net.UnknownHostException e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Set Error Handler <font color="RED"> Not Implemented in the current release
+ * </font>
+ */
+ public static void Errorhandler_set(Errhandler errhandler)
+ throws MPIException {
+ }
+
+ /**
+ * Gets the error handler <font color="RED"> Not Implemented in the current
+ * release </font>
+ */
+ public static Errhandler Errorhandler_get() throws MPIException {
+ return null;
+ }
+
+ /**
+ * Returns wallclock time.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>elapsed wallclock time in seconds since some time in the past
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WTIME</tt>.
+ */
+ public static double Wtime() throws MPIException {
+ return (System.currentTimeMillis() / 1000);
+ }
+
+ /**
+ * Returns resolution of timer.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>resolution of <tt>wtime</tt> in seconds.
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WTICK</tt>.
+ */
+ public static double Wtick() throws MPIException {
+ double time = 0L;
+ double newTime;
+ double smaller = Double.MAX_VALUE;
+
+ for (int i = 0; i < 100000; i++) {
+ time = Wtime();
+ newTime = Wtime();
+ smaller = Math.min(smaller, (newTime - time));
+ }
+
+ return smaller;
+ }
+
+ /**
+ * Test if MPI has been initialized.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td> <tt>true</tt> if <tt>Init</tt> has been called, <tt>false</tt>
+ * otherwise.
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_INITIALIZED</tt>.
+ */
+ public static boolean Initialized() throws MPIException {
+ return initialized;
+ }
+
+}
diff --git a/src/mpi/MPIException.java b/src/mpi/MPIException.java
new file mode 100755
index 0000000..cba39d5
--- /dev/null
+++ b/src/mpi/MPIException.java
@@ -0,0 +1,57 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPIException.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjdev.MPJDevException;
+
+public class MPIException extends MPJDevException {
+
+ public MPIException() {
+ super();
+ }
+
+ public MPIException(String message) {
+ super(message);
+ }
+
+ public MPIException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/src/mpi/Max.java b/src/mpi/Max.java
new file mode 100644
index 0000000..644056d
--- /dev/null
+++ b/src/mpi/Max.java
@@ -0,0 +1,49 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Max.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Max extends Op {
+
+ Max() {
+ worker = new MaxWorker();
+ this.opCode = mpjdev.Constants.MAX_CODE;
+ }
+
+}
diff --git a/src/mpi/MaxByte.java b/src/mpi/MaxByte.java
new file mode 100644
index 0000000..2fcc9ea
--- /dev/null
+++ b/src/mpi/MaxByte.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxByte extends Max {
+ byte [] arr = null;
+ MaxByte() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxChar.java b/src/mpi/MaxChar.java
new file mode 100644
index 0000000..9acebb3
--- /dev/null
+++ b/src/mpi/MaxChar.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxChar extends Max {
+ char [] arr = null;
+ MaxChar() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxDouble.java b/src/mpi/MaxDouble.java
new file mode 100644
index 0000000..5d26942
--- /dev/null
+++ b/src/mpi/MaxDouble.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxDouble extends Max {
+ double [] arr = null;
+ MaxDouble() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ double[] arr1 = (double[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ double[] tempArray = (double[]) buf;
+ arr = new double[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ double[] tempArray = (double[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxFloat.java b/src/mpi/MaxFloat.java
new file mode 100644
index 0000000..1d3a6b3
--- /dev/null
+++ b/src/mpi/MaxFloat.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxFloat extends Max {
+ float [] arr = null;
+ MaxFloat() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ float[] arr1 = (float[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ float[] tempArray = (float[]) buf;
+ arr = new float[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ float[] tempArray = (float[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxInt.java b/src/mpi/MaxInt.java
new file mode 100644
index 0000000..40f5475
--- /dev/null
+++ b/src/mpi/MaxInt.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxInt extends Max {
+ int [] arr = null;
+ MaxInt() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxLong.java b/src/mpi/MaxLong.java
new file mode 100644
index 0000000..54358f6
--- /dev/null
+++ b/src/mpi/MaxLong.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxLong extends Max {
+ long [] arr = null;
+ MaxLong() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxShort.java b/src/mpi/MaxShort.java
new file mode 100644
index 0000000..2e4d5dc
--- /dev/null
+++ b/src/mpi/MaxShort.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template MaxType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MaxShort extends Max {
+ short [] arr = null;
+ MaxShort() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxType.java.in b/src/mpi/MaxType.java.in
new file mode 100644
index 0000000..e7ba362
--- /dev/null
+++ b/src/mpi/MaxType.java.in
@@ -0,0 +1,68 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Max at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/09/03 12:48:06 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Max at Type@ extends Max {
+ @type@ [] arr = null;
+ Max at Type@() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ if (arr1[i] > arr[i]) {
+ arr[i] = arr1[i];
+ }
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
diff --git a/src/mpi/MaxWorker.java b/src/mpi/MaxWorker.java
new file mode 100644
index 0000000..a4b8dfd
--- /dev/null
+++ b/src/mpi/MaxWorker.java
@@ -0,0 +1,80 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MaxWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class MaxWorker
+ implements OpWorker {
+
+ MaxWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new MaxByte();
+
+ case Datatype.CHAR:
+ return new MaxChar();
+
+ case Datatype.SHORT:
+ return new MaxShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.MAX is invalid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new MaxInt();
+
+ case Datatype.LONG:
+ return new MaxLong();
+
+ case Datatype.FLOAT:
+ return new MaxFloat();
+
+ case Datatype.DOUBLE:
+ return new MaxDouble();
+
+ default:
+ return null;
+ }
+ }
+}
+
diff --git a/src/mpi/Maxloc.java b/src/mpi/Maxloc.java
new file mode 100644
index 0000000..657c52d
--- /dev/null
+++ b/src/mpi/Maxloc.java
@@ -0,0 +1,180 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Maxloc.java
+ * Author : Sang Lim, Sung-Hoon Ko, Xinying Li, Bryan Carpenter
+ * (contributions from MAEDA Atusi), Aamir Shafi
+ * Created : Thu Apr 9 12:22:15 BST 1998
+ * Revision : $Revision: 1.9 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ * Copyright: Northeast Parallel Architectures Center
+ * at Syracuse University 1998
+ */
+
+package mpi;
+
+
+// Minloc and Maxloc
+
+public class Maxloc extends User_function{
+ public void Call(Object invec, int inoffset, Object outvec, int outoffset,
+ int count, Datatype datatype){
+
+ // *** should work also for derived datatypes with following as
+ // as bases ? ***
+
+ if(datatype == MPI.SHORT2) {
+ short [] in_array = (short[])invec;
+ short [] out_array = (short[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2) {
+ short inval = in_array [indisp] ;
+ short outval = out_array [outdisp] ;
+
+ if(inval > outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ short inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.INT2) {
+ int [] in_array = (int[])invec;
+ int [] out_array = (int[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ int inval = in_array [indisp] ;
+ int outval = out_array [outdisp] ;
+ if(inval > outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ int inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+
+ }
+ }
+ else if(datatype == MPI.LONG2) {
+ long [] in_array = (long[])invec;
+ long [] out_array = (long[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ long inval = in_array [indisp] ;
+ long outval = out_array [outdisp] ;
+
+ if(inval > outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ long inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.FLOAT2) {
+ float [] in_array = (float[])invec;
+ float [] out_array = (float[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ float inval = in_array [indisp] ;
+ float outval = out_array [outdisp] ;
+
+ if(inval > outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ float inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.DOUBLE2) {
+ double [] in_array = (double[])invec;
+ double [] out_array = (double[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ double inval = in_array [indisp] ;
+ double outval = out_array [outdisp] ;
+
+ if(inval > outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ double inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else {
+ System.out.println("MPI.MAXLOC: invalid datatype") ;
+ try {
+ MPI.COMM_WORLD.Abort(1);
+ }
+ catch(MPIException e) {}
+ }
+ }
+}
+
+// Things to do:
+//
+// Check if `Maxloc'/`Minloc' should work with derived types.
+
diff --git a/src/mpi/MaxlocType.java.in b/src/mpi/MaxlocType.java.in
new file mode 100644
index 0000000..bb0b5b8
--- /dev/null
+++ b/src/mpi/MaxlocType.java.in
@@ -0,0 +1,84 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : Maxloc at Type@.java
+ * Author : Aamir Shafi
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Maxloc at Type@ extends Maxloc {
+
+ @type@[] arr = null;
+
+ Maxloc at Type@() {
+ }
+
+ void createInitialBuffer(Object buf) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ Call(buf1,0,arr,offset,count);
+ }
+
+ void getResultant(Object buf, int offset, int count) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ public void Call(Object invec, int inoffset, Object outvec, int outoffset,
+ int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) invec;
+ int indisp = inoffset;
+ int outdisp = outoffset;
+
+ for(int i=0 ; i<count ; i++, indisp+=2, outdisp+=2) {
+ @type@ inval = arr1[indisp];
+ @type@ outval = arr[outdisp];
+
+ if(inval > outval) {
+ arr[outdisp] = inval;
+ arr[outdisp+1] = arr1[outdisp+1];
+ }else if(inval == outval) {
+ @type@ inloc = arr1[indisp + 1];
+
+ if(inloc < arr[outdisp+1]) {
+ arr1[outdisp+1] = inloc;
+ }
+ }
+ }//end for ...
+ }//end Call method ...
+ }//end class ...
+
diff --git a/src/mpi/Min.java b/src/mpi/Min.java
new file mode 100644
index 0000000..160322e
--- /dev/null
+++ b/src/mpi/Min.java
@@ -0,0 +1,49 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Min.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Min extends Op {
+
+ Min() {
+ worker = new MinWorker();
+ this.opCode = mpjdev.Constants.MIN_CODE;
+ }
+}
diff --git a/src/mpi/MinByte.java b/src/mpi/MinByte.java
new file mode 100644
index 0000000..90848bb
--- /dev/null
+++ b/src/mpi/MinByte.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinByte extends Min {
+ byte [] arr = null;
+ MinByte() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinChar.java b/src/mpi/MinChar.java
new file mode 100644
index 0000000..75bacef
--- /dev/null
+++ b/src/mpi/MinChar.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinChar extends Min {
+ char [] arr = null;
+ MinChar() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinDouble.java b/src/mpi/MinDouble.java
new file mode 100644
index 0000000..00d884b
--- /dev/null
+++ b/src/mpi/MinDouble.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinDouble extends Min {
+ double [] arr = null;
+ MinDouble() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ double[] arr1 = (double[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ double[] tempArray = (double[]) buf;
+ arr = new double[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ double[] tempArray = (double[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinFloat.java b/src/mpi/MinFloat.java
new file mode 100644
index 0000000..1214acc
--- /dev/null
+++ b/src/mpi/MinFloat.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinFloat extends Min {
+ float [] arr = null;
+ MinFloat() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ float[] arr1 = (float[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ float[] tempArray = (float[]) buf;
+ arr = new float[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ float[] tempArray = (float[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinInt.java b/src/mpi/MinInt.java
new file mode 100644
index 0000000..4d2c274
--- /dev/null
+++ b/src/mpi/MinInt.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinInt extends Min {
+ int [] arr = null;
+ MinInt() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinLong.java b/src/mpi/MinLong.java
new file mode 100644
index 0000000..e02bdcb
--- /dev/null
+++ b/src/mpi/MinLong.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinLong extends Min {
+ long [] arr = null;
+ MinLong() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinShort.java b/src/mpi/MinShort.java
new file mode 100644
index 0000000..6265005
--- /dev/null
+++ b/src/mpi/MinShort.java
@@ -0,0 +1,71 @@
+/* This file generated automatically from template MinType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MinShort extends Min {
+ short [] arr = null;
+ MinShort() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinType.java.in b/src/mpi/MinType.java.in
new file mode 100644
index 0000000..d08299a
--- /dev/null
+++ b/src/mpi/MinType.java.in
@@ -0,0 +1,70 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Min at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Min at Type@ extends Min {
+ @type@ [] arr = null;
+ Min at Type@() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ if(arr1[i] < arr[i])
+ arr[i] = arr1[i];
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/MinWorker.java b/src/mpi/MinWorker.java
new file mode 100644
index 0000000..3893983
--- /dev/null
+++ b/src/mpi/MinWorker.java
@@ -0,0 +1,79 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MinWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class MinWorker
+ implements OpWorker {
+ MinWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new MinByte();
+
+ case Datatype.CHAR:
+ return new MinChar();
+
+ case Datatype.SHORT:
+ return new MinShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.MIN is invalid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new MinInt();
+
+ case Datatype.LONG:
+ return new MinLong();
+
+ case Datatype.FLOAT:
+ return new MinFloat();
+
+ case Datatype.DOUBLE:
+ return new MinDouble();
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/Minloc.java b/src/mpi/Minloc.java
new file mode 100644
index 0000000..f8be85b
--- /dev/null
+++ b/src/mpi/Minloc.java
@@ -0,0 +1,176 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Minloc.java
+ * Author : Sang Lim, Sung-Hoon Ko, Xinying Li, Bryan Carpenter
+ * (contributions from MAEDA Atusi), Aamir Shafi
+ * Created : Thu Apr 9 12:22:15 1998
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ * Copyright: Northeast Parallel Architectures Center
+ * at Syracuse University 1998
+ */
+
+package mpi;
+
+
+// Minloc and Maxloc
+public class Minloc extends User_function{
+ public void Call(Object invec, int inoffset, Object outvec, int outoffset,
+ int count, Datatype datatype){
+ if(datatype == MPI.SHORT2) {
+ short [] in_array = (short[])invec;
+ short [] out_array = (short[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ short inval = in_array [indisp] ;
+ short outval = out_array [outdisp] ;
+
+ if(inval < outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ short inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.INT2) {
+ int [] in_array = (int[])invec;
+ int [] out_array = (int[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ int inval = in_array [indisp] ;
+ int outval = out_array [outdisp] ;
+
+ if(inval < outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ int inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.LONG2) {
+ long [] in_array = (long[])invec;
+ long [] out_array = (long[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ long inval = in_array [indisp] ;
+ long outval = out_array [outdisp] ;
+
+ if(inval < outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ long inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.FLOAT2) {
+ float [] in_array = (float[])invec;
+ float [] out_array = (float[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ float inval = in_array [indisp] ;
+ float outval = out_array [outdisp] ;
+
+ if(inval < outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ float inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else if(datatype == MPI.DOUBLE2) {
+ double [] in_array = (double[])invec;
+ double [] out_array = (double[])outvec;
+
+ int indisp = inoffset ;
+ int outdisp = outoffset ;
+ for (int i = 0; i < count; i++, indisp += 2, outdisp += 2){
+
+ double inval = in_array [indisp] ;
+ double outval = out_array [outdisp] ;
+
+ if(inval < outval) {
+ out_array [outdisp ] = inval ;
+ out_array [outdisp + 1] = in_array [indisp + 1] ;
+ }
+ else if(inval == outval) {
+ double inloc = in_array [indisp + 1] ;
+
+ if(inloc < out_array [outdisp + 1])
+ out_array [outdisp + 1] = inloc ;
+ }
+ }
+ }
+ else {
+ System.out.println("MPI.MINLOC: invalid datatype") ;
+ try {
+ MPI.COMM_WORLD.Abort(1);
+ }
+ catch(MPIException e) {}
+ }
+ }
+}
+
+// Things to do:
+//
+// Check if `Maxloc'/`Minloc' should work with derived types.
+
diff --git a/src/mpi/MinlocType.java.in b/src/mpi/MinlocType.java.in
new file mode 100644
index 0000000..a808f15
--- /dev/null
+++ b/src/mpi/MinlocType.java.in
@@ -0,0 +1,83 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+ /*
+ * File : Minloc at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Minloc at Type@ extends Minloc {
+
+ @type@ [] arr = null;
+
+ Minloc at Type@() {
+ }
+
+ void createInitialBuffer(Object buf) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ Call(buf1,0,arr,offset,count);
+ }
+
+ void getResultant(Object buf, int offset, int count) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ public void Call(Object invec, int inoffset, Object outvec, int outoffset,
+ int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) invec;
+ int indisp = inoffset;
+ int outdisp = outoffset;
+ for(int i=0 ; i<count ; i++, indisp+=2, outdisp+=2) {
+ @type@ inval = arr1[indisp];
+ @type@ outval = arr[outdisp];
+
+ if(inval < outval) {
+ arr[outdisp] = inval;
+ arr[outdisp+1] = arr1[outdisp+1];
+ }else if(inval == outval) {
+ @type@ inloc = arr1[indisp + 1];
+
+ if(inloc < arr[outdisp+1]) {
+ arr1[outdisp+1] = inloc;
+ }
+ }
+ }//end for ...
+ }//end Call method ...
+ }//end class ...
+
diff --git a/src/mpi/MultistridedPacker.java b/src/mpi/MultistridedPacker.java
new file mode 100644
index 0000000..3928351
--- /dev/null
+++ b/src/mpi/MultistridedPacker.java
@@ -0,0 +1,77 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPacker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public abstract class MultistridedPacker
+ implements Packer {
+
+ int rank;
+ int[] indexes;
+ int extent, size;
+
+ public MultistridedPacker(int rank, int[] indexes, int extent,
+ int size) {
+ this.rank = rank;
+ this.indexes = indexes;
+ this.extent = extent;
+ this.size = size;
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if (count * size < length) {
+ throw new MPIException("Error in GenericPacker: count*size <"+
+ (count*size) + " is less than length <"+length+">");
+ }
+ else {
+ int numFull = length / size;
+ unpack(mpjbuf, buf, offset, numFull);
+ int residue = length - numFull * size;
+
+ if (residue > 0) {
+ unpackPartial(mpjbuf, residue, buf, offset);
+ }
+
+ }
+
+ }
+}
+
diff --git a/src/mpi/MultistridedPackerBoolean.java b/src/mpi/MultistridedPackerBoolean.java
new file mode 100644
index 0000000..d9f985c
--- /dev/null
+++ b/src/mpi/MultistridedPackerBoolean.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerBoolean extends MultistridedPacker {
+
+
+ public MultistridedPackerBoolean(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((boolean []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((boolean []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((boolean []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((boolean []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((boolean []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((boolean []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((boolean []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerByte.java b/src/mpi/MultistridedPackerByte.java
new file mode 100644
index 0000000..914aed7
--- /dev/null
+++ b/src/mpi/MultistridedPackerByte.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerByte extends MultistridedPacker {
+
+
+ public MultistridedPackerByte(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((byte []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((byte []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((byte []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((byte []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((byte []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((byte []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((byte []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerChar.java b/src/mpi/MultistridedPackerChar.java
new file mode 100644
index 0000000..6e890d9
--- /dev/null
+++ b/src/mpi/MultistridedPackerChar.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerChar extends MultistridedPacker {
+
+
+ public MultistridedPackerChar(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((char []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((char []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((char []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((char []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((char []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((char []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((char []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerDouble.java b/src/mpi/MultistridedPackerDouble.java
new file mode 100644
index 0000000..819bcbf
--- /dev/null
+++ b/src/mpi/MultistridedPackerDouble.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerDouble extends MultistridedPacker {
+
+
+ public MultistridedPackerDouble(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((double []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((double []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((double []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((double []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((double []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((double []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((double []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerFactory.java b/src/mpi/MultistridedPackerFactory.java
new file mode 100644
index 0000000..952e1a5
--- /dev/null
+++ b/src/mpi/MultistridedPackerFactory.java
@@ -0,0 +1,95 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerFactory.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+package mpi;
+
+public class MultistridedPackerFactory {
+
+ public static Packer create(int rank, int[] indexes, int extent, int size,
+ int baseType) {
+
+ switch (baseType) {
+ case -1: //UNDEFINED (dont know what to do here)
+ break;
+
+ case 0: //NULL (dont know what to do here)
+ break;
+
+ case 1: //BYTE
+ return new MultistridedPackerByte(rank, indexes, extent, size);
+
+ case 2: //CHAR
+ return new MultistridedPackerChar(rank, indexes, extent, size);
+
+ case 3: //SHORT
+ return new MultistridedPackerShort(rank, indexes, extent, size);
+
+ case 4: //BOOLEAN
+ return new MultistridedPackerBoolean(rank, indexes, extent, size);
+
+ case 5: //INT
+ return new MultistridedPackerInt(rank, indexes, extent, size);
+
+ case 6: //LONG
+ return new MultistridedPackerLong(rank, indexes, extent, size);
+
+ case 7: //FLOAT
+ return new MultistridedPackerFloat(rank, indexes, extent, size);
+
+ case 8: //DOUBLE
+ return new MultistridedPackerDouble(rank, indexes, extent, size);
+
+ case 9: //PACKED
+ break;
+
+ case 10: //LB
+ break;
+
+ case 11: //UB
+ //i think its not dealt with here
+ break;
+
+ case 12: //OBJECT
+ return new MultistridedPackerObject(rank, indexes, extent, size);
+
+ default:
+ break;
+ }
+
+ return null;
+ }
+}
diff --git a/src/mpi/MultistridedPackerFloat.java b/src/mpi/MultistridedPackerFloat.java
new file mode 100644
index 0000000..1656102
--- /dev/null
+++ b/src/mpi/MultistridedPackerFloat.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerFloat extends MultistridedPacker {
+
+
+ public MultistridedPackerFloat(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((float []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((float []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((float []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((float []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((float []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((float []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((float []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerInt.java b/src/mpi/MultistridedPackerInt.java
new file mode 100644
index 0000000..21a7b7e
--- /dev/null
+++ b/src/mpi/MultistridedPackerInt.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerInt extends MultistridedPacker {
+
+
+ public MultistridedPackerInt(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((int []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((int []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((int []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((int []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((int []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((int []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((int []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerLong.java b/src/mpi/MultistridedPackerLong.java
new file mode 100644
index 0000000..536daca
--- /dev/null
+++ b/src/mpi/MultistridedPackerLong.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerLong extends MultistridedPacker {
+
+
+ public MultistridedPackerLong(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((long []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((long []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((long []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((long []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((long []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((long []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((long []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerObject.java b/src/mpi/MultistridedPackerObject.java
new file mode 100644
index 0000000..ae7ccc6
--- /dev/null
+++ b/src/mpi/MultistridedPackerObject.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerObject.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerObject extends MultistridedPacker {
+
+
+ public MultistridedPackerObject(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strGather((Object []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strScatter((Object []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strScatter((Object []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strGather((Object []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strGather((Object []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strScatter((Object []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ ((mpjbuf.Buffer) mpjbuf).strScatter((Object []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerShort.java b/src/mpi/MultistridedPackerShort.java
new file mode 100644
index 0000000..fd6cb07
--- /dev/null
+++ b/src/mpi/MultistridedPackerShort.java
@@ -0,0 +1,182 @@
+/* This file generated automatically from template MultistridedPackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPackerShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPackerShort extends MultistridedPacker {
+
+
+ public MultistridedPackerShort(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strGather((short []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.strScatter((short []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ mpjbuf.strScatter((short []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ mpjbuf.strGather((short []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strGather((short []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ mpjbuf.strScatter((short []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ mpjbuf.strScatter((short []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/MultistridedPackerType.java.in b/src/mpi/MultistridedPackerType.java.in
new file mode 100644
index 0000000..696d9b8
--- /dev/null
+++ b/src/mpi/MultistridedPackerType.java.in
@@ -0,0 +1,181 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MultistridedPacker at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:09 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class MultistridedPacker at Type@ extends MultistridedPacker {
+
+
+ public MultistridedPacker at Type@(int rank, int [] indexes,
+ int extent, int size) {
+ super(rank, indexes, extent, size);
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @WRITEBUF(mpjbuf)@.strGather((@type@ []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.strScatter((@type@ []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ // In following methods, tempting to try to temporarily modify the
+ // existing `indexes' array, to avoid temporary allocations.
+ // But if `indexes' is not immutable we lose the ability to safely
+ // share the datatype object across threads.
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int [] cIndexes = new int [2 * rank] ;
+ for(int i = 0 ; i < 2 * rank ; i++)
+ cIndexes [i] = indexes [i] ;
+
+ int cubeRank = rank - 1;
+ int cubeSize = size ;
+
+ while(length > 0) {
+ cubeSize /= indexes [cubeRank] ;
+ // size of next smallest dimension cube.
+ int numCubes = length / cubeSize ; // Number of whole cubes.
+ if(numCubes > 0) {
+ cIndexes [cubeRank] = numCubes ;
+ int blockSize = numCubes * cubeSize ;
+
+ try {
+ @READBUF(mpjbuf)@.strScatter((@type@ []) buf, offset,
+ cubeRank + 1, 0, rank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+
+ // Unpack block of cubes.
+ offset += blockSize ;
+ length -= blockSize ;
+ // If cubeRank = 0, then
+ // cubeSize = 1, blockSize = numCubes = length
+ // => This assignment puts length to zero.
+ }
+ cubeRank-- ;
+ }
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+ try {
+ @WRITEBUF(mpjbuf)@.strGather((@type@ []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ @WRITEBUF(mpjbuf)@.strGather((@type@ []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+
+ if(count == 1) {
+
+ try {
+ @READBUF(mpjbuf)@.strScatter((@type@ []) buf, offset,
+ rank, 0, rank, indexes) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ else {
+ int cRank = rank + 1 ;
+ int [] cIndexes = new int [2 * cRank] ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [i] = indexes [i] ;
+ cIndexes [rank] = count ;
+ for(int i = 0 ; i < rank ; i++)
+ cIndexes [cRank + i] = indexes [rank + i] ;
+ cIndexes [cRank + rank] = extent ;
+
+ try {
+ @READBUF(mpjbuf)@.strScatter((@type@ []) buf, offset,
+ cRank, 0, cRank, cIndexes) ;
+ }catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+ }
+
+
+ }
+
diff --git a/src/mpi/NativeIntracomm.java b/src/mpi/NativeIntracomm.java
new file mode 100755
index 0000000..49e72a1
--- /dev/null
+++ b/src/mpi/NativeIntracomm.java
@@ -0,0 +1,1369 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : NativeIntracomm.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+import java.nio.*;
+
+public class NativeIntracomm extends PureIntracomm {
+
+ mpjdev.natmpjdev.Intracomm nativeIntracomm = null;
+
+ /*
+ * Copy pasted these things (ENUMs for Types) from mpi/dataType.java These
+ * have to be consistent with mpi/dataType.java some how have to expose them
+ * in dataType so that they be accessible to other classes
+ */
+
+ final static int UNDEFINED = -1;
+ final static int NULL = 0;
+ final static int BYTE = 1;
+ final static int CHAR = 2;
+ final static int SHORT = 3;
+ final static int BOOLEAN = 4;
+ final static int INT = 5;
+ final static int LONG = 6;
+ final static int FLOAT = 7;
+ final static int DOUBLE = 8;
+ final static int PACKED = 9;
+ // after this non primitive types start
+ final static int PRIMITIVE_TYPE_RANGE_UB = 9;
+
+ final static int LB = 10;
+ final static int UB = 11;
+ final static int OBJECT = 12;
+
+ final static int SHORT2 = 3;
+ final static int INT2 = 5;
+ final static int LONG2 = 6;
+ final static int FLOAT2 = 7;
+ final static int DOUBLE2 = 8;
+
+ NativeIntracomm() {
+ }
+
+ /**
+ * Constructor used to create an intracomm
+ *
+ * @param mpjdev
+ * .Comm The "obvious" way for allocating contexts is each process
+ * independently increments a "next context" variable (a static
+ * variable if you like, but local to the process). Then the
+ * processes in the group do a collective "maxval" of the candidates,
+ * and agree to accept the largest proposal. This is returned as the
+ * result of the collective context allocation, and all processes
+ * also store it in the static variable they use as a starting point
+ * next time round. This algorithm can also allocate several
+ * consecutive contexts in a single phase, which is useful here.
+ **/
+
+ NativeIntracomm(mpjdev.Comm _mpjdevComm, mpjdev.Group _group) {
+
+ super(_mpjdevComm, _group);
+
+ nativeIntracomm = new mpjdev.natmpjdev.Intracomm(
+ (mpjdev.natmpjdev.Comm) mpjdevComm);
+ }
+
+ NativeIntracomm(mpjdev.Comm _mpjdevComm, mpi.Group _group) {
+
+ super(_mpjdevComm, _group);
+
+ nativeIntracomm = new mpjdev.natmpjdev.Intracomm(
+ (mpjdev.natmpjdev.Comm) mpjdevComm);
+ }
+
+ /**
+ * Compare two communicators.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> comm1 </tt></td>
+ * <td>first communicator
+ * </tr>
+ * <tr>
+ * <td><tt> comm2 </tt></td>
+ * <td>second communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>result
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ * <p>
+ * <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ * references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ * <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ * but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ * the underlying groups are similar but the communicators differ by context.
+ * <tt>MPI.UNEQUAL</tt>(2) results otherwise.
+ */
+
+ public static int Compare(mpi.Comm comm1, mpi.Comm comm2) throws MPIException {
+
+ return mpjdev.natmpjdev.Intracomm.Compare(comm1.mpjdevComm,
+ comm2.mpjdevComm);
+ }
+
+ /**
+ * Partition the group associated with this communicator and create a new
+ * communicator within each subgroup.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> color </tt></td>
+ * <td>control of subset assignment
+ * </tr>
+ * <tr>
+ * <td><tt> key </tt></td>
+ * <td>control of rank assignment
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_SPLIT</tt>.
+ */
+ public IntracommImpl Split(int color, int key) {
+
+ try {
+ mpjdev.Comm ncomm = mpjdevComm.split(color, key);
+ return new NativeIntracomm(ncomm, ncomm.group);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ /**
+ * Clone the communicator This method will be called only by intracommunicator
+ * .... changed the return value to Intracomm ...(instead of Object) ...
+ */
+ public Object clone() {
+
+ return this.Create(this.group);
+ }
+
+ /**
+ * Create a new communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group </tt></td>
+ * <td>group which is a subset of the group of this communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_CREATE</tt>.
+ */
+ public IntracommImpl Create(Group group) {
+
+ mpjdev.Comm tcomm = mpjdevComm.create(group.mpjdevGroup);
+
+ if (tcomm == null) {
+ // if I uncomment the retuen null; then mpi.group.group test case doesn't
+ // work. The testcases are working so I am leaving this as is
+ // System.out.println("NativeIntracomm Create - tcomm returned as null");
+ // return null;
+ }
+ return (new NativeIntracomm(tcomm, group.mpjdevGroup));
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * /** A call to <tt>Barrier</tt> blocks the caller until all process in the
+ * group have called it.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BARRIER</tt>.
+ */
+ public void Barrier() {
+
+ nativeIntracomm.Barrier();
+
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of broadcast root
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BCST</tt>.
+ */
+
+ public void Bcast(Object buf, int offset, int count, Datatype type, int root) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (type.baseType > PRIMITIVE_TYPE_RANGE_UB || type.Size() > 1) {
+ super.Bcast(buf, offset, count, type, root);
+ return;
+ }
+
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+ int size = this.mpjdevComm.size();
+
+ int numBytes = count * type.getByteSize();
+ ByteBuffer wBuffer = ByteBuffer.allocateDirect(numBytes);
+
+ try {
+ if (index == root) {
+ byteBufferSetData(buf, wBuffer, 0, offset, count, type.getType());
+ wBuffer.flip();
+ // wBuffer.limit(numBytes);
+ }
+ wBuffer.limit(numBytes);
+
+ nativeIntracomm.Bcast(wBuffer, numBytes, root);
+
+ // FIXME: Optimization tip root shouldn't do this
+ byteBufferGetData(wBuffer, buf, 0, offset, count, type.getType());
+ wBuffer.clear();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Each process sends the contents of its send buffer to the root process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHER</tt>.
+ */
+ public void Gather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Gather(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+ return;
+
+ }
+
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+ int size = this.mpjdevComm.size();
+
+ int numSendBytes = sendcount * sendtype.getByteSize();
+ ByteBuffer wBuffer = ByteBuffer.allocateDirect(numSendBytes);
+
+ ByteBuffer rBuffer = null;
+ int numRecvBytes = -1;
+
+ if (index == root) {
+ numRecvBytes = recvcount * recvtype.getByteSize() * size;
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+ }
+
+ try {
+ byteBufferSetData(sendbuf, wBuffer, 0, sendoffset, sendcount,
+ sendtype.getType());
+ wBuffer.flip();
+ wBuffer.limit(numSendBytes);
+
+ nativeIntracomm.Gather(wBuffer, numSendBytes, rBuffer, numSendBytes,
+ root, index == root ? true : false);
+
+ if (index == root) { // root is the source point of gather
+ rBuffer.limit(numRecvBytes);
+ byteBufferGetData(rBuffer, recvbuf, 0, recvoffset, recvcount * size,
+ recvtype.getType());
+ rBuffer.clear();
+
+ } // ends if root
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+ }
+
+ /**
+ * Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ * from each process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ * <p>
+ * The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ * size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ * displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt> at
+ * which to place incoming data.
+ */
+ public void Gatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype, int root) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Gatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype, root);
+ return;
+
+ }
+ super.Gatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype, root);
+ }
+
+ /**
+ * Inverse of the operation <tt>Gather</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTER</tt>.
+ */
+
+ public void Scatter(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Scatter(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+ return;
+
+ }
+
+ /*
+ * super.Scatter(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ * recvoffset, recvcount, recvtype, root);
+ */
+ // System.out.println("Native Scatter");
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+ int size = this.mpjdevComm.size();
+
+ ByteBuffer wBuffer = null;
+ int numSendBytes = -1;
+
+ if (index == root) {
+ numSendBytes = sendcount * sendtype.getByteSize() * size;
+ wBuffer = ByteBuffer.allocateDirect(numSendBytes);
+ }
+
+ ByteBuffer rBuffer = null;
+ int numRecvBytes = -1;
+
+ numRecvBytes = recvcount * recvtype.getByteSize();
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+
+ try {
+ if (index == root) {
+ byteBufferSetData(sendbuf, wBuffer, 0, sendoffset, sendcount * size,
+ sendtype.getType());
+ wBuffer.flip();
+ wBuffer.limit(numSendBytes);
+ }
+
+ nativeIntracomm.Scatter(wBuffer, numRecvBytes, rBuffer, numRecvBytes,
+ root);
+
+ rBuffer.limit(numRecvBytes);
+ byteBufferGetData(rBuffer, recvbuf, 0, recvoffset, recvcount,
+ recvtype.getType());
+ rBuffer.clear();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Inverse of the operation <tt>Gatherv</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.
+ */
+ public void Scatterv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] displs, Datatype sendtype, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int root) {
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Scatterv(sendbuf, sendoffset, sendcount, displs, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+ return;
+
+ }
+ super.Scatterv(sendbuf, sendoffset, sendcount, displs, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype, root);
+
+ }
+
+ /**
+ * Similar to <tt>Gather</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.
+ */
+
+ public void Allgather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Allgather(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype);
+ return;
+
+ }
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+ int size = this.mpjdevComm.size();
+
+ ByteBuffer wBuffer = null;
+ int numSendBytes = -1;
+
+ numSendBytes = sendcount * sendtype.getByteSize();
+ wBuffer = ByteBuffer.allocateDirect(numSendBytes);
+
+ ByteBuffer rBuffer = null;
+ int numRecvBytes = -1;
+
+ numRecvBytes = recvcount * recvtype.getByteSize() * size;
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+
+ try {
+
+ byteBufferSetData(sendbuf, wBuffer, 0, sendoffset, sendcount,
+ sendtype.getType());
+ wBuffer.flip();
+ wBuffer.limit(numSendBytes);
+
+ nativeIntracomm.Allgather(wBuffer, numSendBytes, rBuffer, numSendBytes);
+
+ rBuffer.limit(numRecvBytes);
+ byteBufferGetData(rBuffer, recvbuf, 0, recvoffset, recvcount * size,
+ recvtype.getType());
+ rBuffer.clear();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.
+ */
+ public void Allgatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype) {
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Allgatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype);
+ return;
+
+ }
+ super.Allgatherv(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, displs, recvtype);
+
+ }
+
+ /**
+ * Extension of <tt>Allgather</tt> to the case where each process sends
+ * distinct data to each of the receivers.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items received from any process
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of receive buffer items
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.
+ */
+
+ public void Alltoall(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) {
+
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Alltoall(sendbuf, sendoffset, sendcount, sendtype, recvbuf,
+ recvoffset, recvcount, recvtype);
+ return;
+
+ }
+ // int index = this.mpjdevComm.id();// Get the rank of the current
+ // process
+
+ int size = this.mpjdevComm.size();
+
+ ByteBuffer wBuffer = null;
+ int numSendBytes = -1;
+
+ numSendBytes = sendcount * sendtype.getByteSize() * size;
+ wBuffer = ByteBuffer.allocateDirect(numSendBytes);
+
+ ByteBuffer rBuffer = null;
+ int numRecvBytes = -1;
+
+ numRecvBytes = recvcount * recvtype.getByteSize() * size;
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+
+ try {
+
+ byteBufferSetData(sendbuf, wBuffer, 0, sendoffset, sendcount * size,
+ sendtype.getType());
+ wBuffer.flip();
+ wBuffer.limit(numSendBytes);
+
+ numSendBytes = sendcount * sendtype.getByteSize();
+
+ nativeIntracomm.Alltoall(wBuffer, numSendBytes, rBuffer, numSendBytes);
+
+ rBuffer.limit(numRecvBytes);
+ byteBufferGetData(rBuffer, recvbuf, 0, recvoffset, recvcount * size,
+ recvtype.getType());
+ rBuffer.clear();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ * specified by <tt>sdispls</tt> and location to place data on receive side is
+ * specified by <tt>rdispls</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sdispls </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * <tr>
+ * <td><tt> rdispls </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.
+ */
+
+ public void Alltoallv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] sdispls, Datatype sendtype, Object recvbuf, int recvoffset,
+ int[] recvcount, int[] rdispls, Datatype recvtype) {
+ // for UB, LB, Object and Derived Datatypes (Vector, Struct etc when
+ // size>1)
+ if (sendtype.baseType > PRIMITIVE_TYPE_RANGE_UB || sendtype.Size() > 1) {
+ super.Alltoallv(sendbuf, sendoffset, sendcount, sdispls, sendtype,
+ recvbuf, recvoffset, recvcount, rdispls, recvtype);
+ return;
+
+ }
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+
+ int size = this.mpjdevComm.size();
+
+ ByteBuffer wBuffer = null;
+ int numSendBytes = -1;
+ int totalSendCount = 0;
+ int totalRecvCount = 0;
+
+ for (int i = 0; i < size; i++) {
+ totalSendCount += sendcount[i];
+ }
+ numSendBytes = totalSendCount * sendtype.getByteSize();
+ wBuffer = ByteBuffer.allocateDirect(numSendBytes);
+
+ ByteBuffer rBuffer = null;
+ int numRecvBytes = -1;
+
+ for (int i = 0; i < size; i++) {
+ totalRecvCount += recvcount[i];
+ }
+ numRecvBytes = totalRecvCount * recvtype.getByteSize();
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+
+ int sendcountBytes[] = new int[sendcount.length];// or size?
+ int sdisplsBytes[] = new int[sdispls.length];// or size?
+ int recvcountBytes[] = new int[recvcount.length];// or size?
+ int rdisplsBytes[] = new int[rdispls.length];// or size?
+
+ // convert into bytes
+ for (int i = 0; i < sendcountBytes.length; i++) {
+ sendcountBytes[i] = sendcount[i] * sendtype.getByteSize();
+ }
+ sdisplsBytes[0] = 0;
+ for (int i = 1; i < sdisplsBytes.length; i++) {
+ sdisplsBytes[i] = sendcountBytes[i - 1] + sdisplsBytes[i - 1];
+ }
+
+ for (int i = 0; i < recvcountBytes.length; i++) {
+ recvcountBytes[i] = recvcount[i] * recvtype.getByteSize();
+ }
+ rdisplsBytes[0] = 0;
+ for (int i = 1; i < rdisplsBytes.length; i++) {
+ rdisplsBytes[i] = recvcountBytes[i - 1] + rdisplsBytes[i - 1];
+ }
+
+ try {
+
+ for (int i = 0; i < size; i++)
+ byteBufferSetData(sendbuf, wBuffer, 0, sdispls[i], sendcount[i],
+ sendtype.getType());
+
+ wBuffer.flip();
+ wBuffer.limit(numSendBytes);
+
+ nativeIntracomm.Alltoallv(wBuffer, sendcountBytes, sdisplsBytes, rBuffer,
+ recvcountBytes, rdisplsBytes);
+
+ rBuffer.limit(numRecvBytes);
+ for (int i = 0; i < size; i++)
+ byteBufferGetData(rBuffer, recvbuf, 0, rdispls[i], recvcount[i],
+ recvtype.getType());
+
+ rBuffer.clear();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and return the combined value in the output buffer of the root
+ * process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of root process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ * <p>
+ * The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ * <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ * <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ * <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.
+ */
+
+ public void Reduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype type, Op op, int root) {
+
+ // for UB, LB, Object and Vector
+ if (type.baseType > PRIMITIVE_TYPE_RANGE_UB || type.Size() > 1
+ || op.opCode > 10) { // 10 -- because MAXLOC MINLOC not yet
+ // implemented
+ super.Reduce(sendbuf, sendoffset, recvbuf, recvoffset, count, type, op,
+ root);
+ return;
+
+ }
+
+ int index = this.mpjdevComm.id();// Get the rank of the current process
+
+ // int size = this.mpjdevComm.size();
+
+ ByteBuffer rBuffer = null;
+
+ int numRecvBytes = -1;
+ int recvcount = count; // naive case, TODO: fix this for MAXLOC etc?
+ numRecvBytes = recvcount * type.getByteSize();
+ rBuffer = ByteBuffer.allocateDirect(numRecvBytes);
+ rBuffer.limit(numRecvBytes);
+ try {
+
+ nativeIntracomm.Reduce(sendbuf, rBuffer, count, type, op, root);
+
+ if (index == root) { // root is the source point of gather
+
+ // this should copy the values compatably
+ byteBufferGetData(rBuffer, recvbuf, 0, recvoffset, recvcount,
+ type.getType());
+ rBuffer.clear();
+
+ } // ends if root
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ return;
+
+ }
+
+ /**
+ * Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ * all process in the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.
+ */
+
+ public void Allreduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) {
+ // for UB, LB, Object and Vector
+ if (datatype.baseType > PRIMITIVE_TYPE_RANGE_UB || datatype.Size() > 1
+
+ || op.opCode > 10) { // 10 -- because MAXLOC MINLOC not yet
+ // implemented
+ // anyways for MAXLOC and MINLOC we use
+ // MPI.INT2
+ // and its contiguous type so for that
+ // Size()>1
+ super.Allreduce(sendbuf, sendoffset, recvbuf, recvoffset, count,
+ datatype, op);
+ return;
+
+ }
+
+ super.Allreduce(sendbuf, sendoffset, recvbuf, recvoffset, count, datatype,
+ op);
+
+ }
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and scatter the combined values over the output buffers of the
+ * processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>numbers of result elements distributed to each process
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.
+ */
+ public void Reduce_scatter(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int[] recvcounts, Datatype datatype, Op op) {
+ // for UB, LB, Object and Vector
+ if (datatype.baseType > PRIMITIVE_TYPE_RANGE_UB || datatype.Size() > 1) {
+ super.Reduce_scatter(sendbuf, sendoffset, recvbuf, recvoffset,
+ recvcounts, datatype, op);
+ return;
+
+ }
+ super.Reduce_scatter(sendbuf, sendoffset, recvbuf, recvoffset, recvcounts,
+ datatype, op);
+
+ }
+
+ /**
+ * Perform a prefix reduction on data distributed across the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCAN</tt>.
+ */
+
+ public void Scan(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int recvcounts, Datatype datatype, Op op)
+ throws MPIException {
+ // for UB, LB, Object and Vector
+ if (datatype.baseType > PRIMITIVE_TYPE_RANGE_UB || datatype.Size() > 1) {
+ super.Scan(sendbuf, sendoffset, recvbuf, recvoffset, recvcounts,
+ datatype, op);
+
+ return;
+
+ }
+ super.Scan(sendbuf, sendoffset, recvbuf, recvoffset, recvcounts, datatype,
+ op);
+
+ }
+
+ /*
+ * Utility and helping functions
+ */
+
+ private void byteBufferSetData(Object src, ByteBuffer dest, int destOffset,
+ int offset, int count, int typeCode) {
+
+ if (typeCode == this.BYTE) {
+ dest.position(destOffset);
+ dest.put((byte[]) src, offset, count);
+ } else if (typeCode == this.CHAR) {
+ dest.position(destOffset);
+ CharBuffer CharBuffer = dest.asCharBuffer();
+ CharBuffer.put((char[]) src, offset, count);
+ } else if (typeCode == this.SHORT) {
+ dest.position(destOffset);
+ ShortBuffer ShortBuffer = dest.asShortBuffer();
+ ShortBuffer.put((short[]) src, offset, count);
+ } else if (typeCode == this.BOOLEAN) {
+ dest.position(destOffset);
+ boolean srcB[] = (boolean[]) src;
+ for (int i = 0; i < count; i++) {
+ dest.put((byte) (srcB[i + offset] ? 1 : 0)); // boolean
+ }
+
+ } else if (typeCode == this.INT) {
+ dest.position(destOffset);
+ IntBuffer IntBuffer = dest.asIntBuffer();
+ IntBuffer.put((int[]) src, offset, count);
+ } else if (typeCode == this.LONG) {
+ dest.position(destOffset);
+ LongBuffer LongBuffer = dest.asLongBuffer();
+ LongBuffer.put((long[]) src, offset, count);
+ } else if (typeCode == this.FLOAT) {
+ dest.position(destOffset);
+ FloatBuffer FloatBuffer = dest.asFloatBuffer();
+ FloatBuffer.put((float[]) src, offset, count);
+ } else if (typeCode == this.DOUBLE) {
+ dest.position(destOffset);
+ DoubleBuffer DoubleBuffer = dest.asDoubleBuffer();
+ DoubleBuffer.put((double[]) src, offset, count);
+ }
+
+ }
+
+ private void byteBufferGetData(ByteBuffer src, Object dest, int srcOffset,
+ int offset, int count, int typeCode) {
+
+ if (typeCode == this.BYTE) {
+ src.position(srcOffset);
+ src.get((byte[]) dest, offset, count);
+ } else if (typeCode == this.CHAR) {
+ src.position(srcOffset);
+ CharBuffer CharBuffer = src.asCharBuffer();
+ CharBuffer.get((char[]) dest, offset, count);
+ } else if (typeCode == this.SHORT) {
+ src.position(srcOffset);
+ ShortBuffer ShortBuffer = src.asShortBuffer();
+ ShortBuffer.get((short[]) dest, offset, count);
+ } else if (typeCode == this.BOOLEAN) {
+ src.position(srcOffset);
+ boolean destB[] = (boolean[]) dest;
+
+ for (int i = 0; i < count; i++) {
+ destB[i + offset] = (src.get() == 1); // boolean
+ }
+
+ } else if (typeCode == this.INT) {
+ src.position(srcOffset);
+ IntBuffer IntBuffer = src.asIntBuffer();
+ IntBuffer.get((int[]) dest, offset, count);
+ } else if (typeCode == this.LONG) {
+ src.position(srcOffset);
+ LongBuffer LongBuffer = src.asLongBuffer();
+ LongBuffer.get((long[]) dest, offset, count);
+ } else if (typeCode == this.FLOAT) {
+ src.position(srcOffset);
+ FloatBuffer FloatBuffer = src.asFloatBuffer();
+ FloatBuffer.get((float[]) dest, offset, count);
+ } else if (typeCode == this.DOUBLE) {
+ src.position(srcOffset);
+ DoubleBuffer DoubleBuffer = src.asDoubleBuffer();
+ DoubleBuffer.get((double[]) dest, offset, count);
+ }
+
+ }
+
+}
diff --git a/src/mpi/Op.java b/src/mpi/Op.java
new file mode 100644
index 0000000..5ef946c
--- /dev/null
+++ b/src/mpi/Op.java
@@ -0,0 +1,106 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Op.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.91 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+public class Op {
+ OpWorker worker = null;
+ User_function funct = null;
+
+ //TODO: Document this and later make this private and provide a
+ // getter function
+ // need for natmpjdev
+ public int opCode = -1; // MPI.UNDEFINED
+
+ Op() {
+ }
+
+ /* this method should be something like abstract ...
+ but its not possible coz these methods like free() and finalize and
+ and constructor to create User_fuctions ..is needed here ..
+ */
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException{
+ }
+
+ void getResultant(Object buf, int offset, int count) throws MPIException {
+ }
+
+ public void free() throws MPIException {
+ }
+
+ public void finalize() throws MPIException {
+ }
+
+ /**
+ * Bind a user-defined global reduction operation to an <tt>Op</tt> object.
+ * <p>
+ * <table>
+ * <tr><td><tt> function </tt></td><td> user defined function </tr>
+ * <tr><td><tt> commute </tt></td><td> <tt>true</tt> if commutative,
+ * <tt>false</tt> otherwise </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_OP_CREATE</tt>.
+ */
+ public Op(User_function function, boolean commute) throws MPIException {
+ funct = function;
+ }
+ //TODO: document this new constructor
+ /**
+ * Bind a user-defined global reduction operation to an <tt>Op</tt> object.
+ * <p>
+ * <table>
+ * <tr><td><tt> function </tt></td><td> user defined function </tr>
+ * <tr><td><tt> commute </tt></td><td> <tt>true</tt> if commutative,
+ * <tt>false</tt> otherwise </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_OP_CREATE</tt>.
+ */
+ public Op(User_function function, boolean commute, int opCode_) throws MPIException {
+ funct = function;
+ this.opCode = opCode_;
+ }
+
+ void getWorker() throws MPIException {
+ }
+
+}
diff --git a/src/mpi/OpWorker.java b/src/mpi/OpWorker.java
new file mode 100644
index 0000000..32462cf
--- /dev/null
+++ b/src/mpi/OpWorker.java
@@ -0,0 +1,42 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : OpWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+public interface OpWorker {
+ public Op getWorker(Datatype datatype) throws MPIException ;
+}
diff --git a/src/mpi/Packer.java b/src/mpi/Packer.java
new file mode 100644
index 0000000..2cfcd70
--- /dev/null
+++ b/src/mpi/Packer.java
@@ -0,0 +1,77 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Packer.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+public interface Packer {
+
+ public abstract void pack(mpjbuf.Buffer mpjbuf,
+ Object buf,
+ int offset) throws MPIException ;
+
+ public abstract void unpack(mpjbuf.Buffer mpjbuf,
+ Object buf,
+ int offset) throws MPIException ;
+
+ /**
+ * Precondition for calling `unpackPartial()' is that `length'
+ * is less than `size' (numEls).
+ */
+ public abstract void unpackPartial(mpjbuf.Buffer mpjbuf,
+ int length,
+ Object buf, int offset)
+ throws MPIException ;
+
+ // Pack and unpack items with repeat count.
+ public abstract void pack(mpjbuf.Buffer mpjbuf,
+ Object buf,
+ int offset,
+ int count) throws MPIException;
+
+ public abstract void unpack(mpjbuf.Buffer mpjbuf,
+ int length,
+ Object buf,
+ int offset,
+ int count) throws MPIException;
+
+ public abstract void unpack(mpjbuf.Buffer mpjbuf,
+ Object buf,
+ int offset,
+ int count) throws MPIException;
+
+}
+
diff --git a/src/mpi/Prequest.java b/src/mpi/Prequest.java
new file mode 100755
index 0000000..6f008d6
--- /dev/null
+++ b/src/mpi/Prequest.java
@@ -0,0 +1,138 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Prequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.10 $
+ * Updated : $Date: 2005/11/27 19:37:22 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+
+public class Prequest
+ extends Request {
+
+ /* */
+ Object buf = null;
+ int offset = 0, count = 0, dest = 0, tag = 0, op = 0;
+ Datatype datatype = null;
+ mpi.Comm comm = null;
+
+ Prequest(Object buf, int offset, int count, Datatype datatype,
+ int dest, int tag, int op, mpi.Comm comm) {
+ this.buf = buf;
+ this.offset = offset;
+ this.count = count;
+ this.datatype = datatype;
+ this.dest = dest;
+ this.tag = tag;
+ this.op = op;
+ this.comm = comm;
+ }
+
+ /**
+ * Activate a persistent communication request.
+ * Java binding of the MPI operation <tt>MPI_START</tt>.
+ * The communication is completed by using the request in
+ * one of the <tt>wait</tt> or <tt>test</tt> operations.
+ * On successful completion the request becomes inactive again.
+ * It can be reactivated by a further call to <tt>Start</tt>.
+ */
+ public void Start() throws MPIException {
+ Request request = null;
+ switch (op) {
+
+ case MPI.OP_SEND:
+ request = comm.Isend(buf, offset, count, datatype, dest, tag);
+ this.req = request.req;
+ this.isNull = false;
+ //this.datatype = request.datatype;
+ //this.isNull = request.isNull;
+ break;
+
+ case MPI.OP_BSEND:
+ request = comm.Ibsend(buf, offset, count, datatype, dest, tag);
+ this.req = request.req;
+ this.isNull = false;
+ //this.datatype = request.datatype;
+ //this.isNull = request.isNull;
+ break;
+
+ case MPI.OP_RSEND:
+ request = comm.Irsend(buf, offset, count, datatype, dest, tag);
+ this.req = request.req;
+ this.isNull = false;
+ //this.datatype = request.datatype;
+ //this.isNull = request.isNull;
+ break;
+
+ case MPI.OP_SSEND:
+ request = comm.Issend(buf, offset, count, datatype, dest, tag);
+ this.req = request.req;
+ this.isNull = false;
+ //this.datatype = request.datatype;
+ //this.isNull = request.isNull;
+ break;
+
+ case MPI.OP_RECV:
+ request = comm.Irecv(buf, offset, count, datatype, dest, tag);
+ this.req = request.req;
+ this.isNull = false;
+ //this.datatype = request.datatype;
+ //this.isNull = request.isNull;
+ break;
+
+ default:
+ throw new MPIException("Invalid persistent request operation");
+ }
+ }
+
+ /**
+ * Activate a list of communication requests.
+ * <p>
+ * <table>
+ * <tr><td><tt> array_of_requests </tt></td><td> array of requests </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_STARTALL</tt>.
+ */
+ public static void Startall(Prequest[] array_of_request) throws MPIException {
+
+ for (int i = 0; i < array_of_request.length; i++) {
+ if (array_of_request[i] != null)
+ array_of_request[i].Start();
+ }
+ }
+}
+
diff --git a/src/mpi/ProcTree.java b/src/mpi/ProcTree.java
new file mode 100755
index 0000000..034b489
--- /dev/null
+++ b/src/mpi/ProcTree.java
@@ -0,0 +1,116 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : ProcTree.java
+ * Author : Sang Lim, Bryan Carpenter
+ * Created : Thu Dec 20 16:39:43 BST 2001
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/08/06 15:21:36 $
+ */
+
+//package hpjava.lang;
+package mpi;
+
+public class ProcTree {
+
+ public static final int PROCTREE_A = 4;
+ public int numChildren;
+ public int[] child = new int[PROCTREE_A];
+ public int parent;
+ public int root;
+ public boolean isRoot;
+
+ public ProcTree() {
+ isRoot = false; //it was set to true ...
+ numChildren = -1;
+ for (int i = 0; i < child.length; i++) {
+ child[i] = -1;
+ }
+ root = -1;
+ parent = -1;
+ }
+
+ public static void main(String args[]) {
+ //ProcTree main method ...
+ ProcTree procTree = null;
+
+ if (args.length < 3) {
+ System.out.println("three arguments ...");
+ System.out.println("rank, size, root");
+ return;
+ }
+
+ int index = Integer.parseInt(args[0]);
+ int extent = Integer.parseInt(args[1]);
+ int root = Integer.parseInt(args[2]);
+ procTree = new ProcTree();
+ int places = ProcTree.PROCTREE_A * index;
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ System.out.println("places " + places);
+ ch %= extent;
+
+ if (places < extent) {
+ System.out.println("ch <" + i + ">" + "=<" + ch + ">");
+ System.out.println("adding to the tree at index <" + (i - 1) + ">\n\n");
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ }
+ else {
+ System.out.println("not adding to the tree");
+ }
+
+ //places = index*ProcTree.PROCTREE_A +i;
+ }
+
+ System.out.println("procTree.numChildren <" + procTree.numChildren + ">");
+
+ if (index == root)
+ procTree.isRoot = true;
+ else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ }
+
+ procTree.root = root;
+
+ for (int i = 0; i < procTree.PROCTREE_A; i++) {
+ System.out.print(" child[" + i + "]=>" + procTree.child[i]);
+ }
+
+ System.out.println(" ------- End --------");
+ //ProcTree main method ...
+ }
+
+}
diff --git a/src/mpi/Prod.java b/src/mpi/Prod.java
new file mode 100644
index 0000000..db236bd
--- /dev/null
+++ b/src/mpi/Prod.java
@@ -0,0 +1,50 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Prod.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Prod
+ extends Op {
+
+ Prod() {
+ worker = new ProdWorker();
+ this.opCode = mpjdev.Constants.PROD_CODE;
+ }
+}
+
diff --git a/src/mpi/ProdByte.java b/src/mpi/ProdByte.java
new file mode 100644
index 0000000..25e7197
--- /dev/null
+++ b/src/mpi/ProdByte.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdByte extends Prod {
+ byte [] arr = null;
+ ProdByte() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (byte) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdChar.java b/src/mpi/ProdChar.java
new file mode 100644
index 0000000..e0e64d0
--- /dev/null
+++ b/src/mpi/ProdChar.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdChar extends Prod {
+ char [] arr = null;
+ ProdChar() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (char) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdDouble.java b/src/mpi/ProdDouble.java
new file mode 100644
index 0000000..58e43b2
--- /dev/null
+++ b/src/mpi/ProdDouble.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdDouble extends Prod {
+ double [] arr = null;
+ ProdDouble() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ double[] arr1 = (double[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (double) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ double[] tempArray = (double[]) buf;
+ arr = new double[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ double[] tempArray = (double[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdFloat.java b/src/mpi/ProdFloat.java
new file mode 100644
index 0000000..507427a
--- /dev/null
+++ b/src/mpi/ProdFloat.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdFloat extends Prod {
+ float [] arr = null;
+ ProdFloat() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ float[] arr1 = (float[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (float) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ float[] tempArray = (float[]) buf;
+ arr = new float[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ float[] tempArray = (float[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdInt.java b/src/mpi/ProdInt.java
new file mode 100644
index 0000000..11b8a54
--- /dev/null
+++ b/src/mpi/ProdInt.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdInt extends Prod {
+ int [] arr = null;
+ ProdInt() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (int) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdLong.java b/src/mpi/ProdLong.java
new file mode 100644
index 0000000..ac883c9
--- /dev/null
+++ b/src/mpi/ProdLong.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdLong extends Prod {
+ long [] arr = null;
+ ProdLong() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (long) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdShort.java b/src/mpi/ProdShort.java
new file mode 100644
index 0000000..b9c42d7
--- /dev/null
+++ b/src/mpi/ProdShort.java
@@ -0,0 +1,68 @@
+/* This file generated automatically from template ProdType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class ProdShort extends Prod {
+ short [] arr = null;
+ ProdShort() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (short) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdType.java.in b/src/mpi/ProdType.java.in
new file mode 100644
index 0000000..c1275b7
--- /dev/null
+++ b/src/mpi/ProdType.java.in
@@ -0,0 +1,67 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Prod at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Prod at Type@ extends Prod {
+ @type@ [] arr = null;
+ Prod at Type@() {
+ }
+
+ void perform (Object buf1, int offset, int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0; i < count; i++) {
+ arr[i] = (@type@) (arr1[i] * arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+ }
+
diff --git a/src/mpi/ProdWorker.java b/src/mpi/ProdWorker.java
new file mode 100644
index 0000000..43a7c1f
--- /dev/null
+++ b/src/mpi/ProdWorker.java
@@ -0,0 +1,78 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProdWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class ProdWorker
+ implements OpWorker {
+ ProdWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new ProdByte();
+
+ case Datatype.CHAR:
+ return new ProdChar();
+
+ case Datatype.SHORT:
+ return new ProdShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.PROD is invalid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new ProdInt();
+
+ case Datatype.LONG:
+ return new ProdLong();
+
+ case Datatype.FLOAT:
+ return new ProdFloat();
+
+ case Datatype.DOUBLE:
+ return new ProdDouble();
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/PureIntracomm.java b/src/mpi/PureIntracomm.java
new file mode 100755
index 0000000..3da9af8
--- /dev/null
+++ b/src/mpi/PureIntracomm.java
@@ -0,0 +1,2097 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Intracomm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.30 $
+ * Updated : $Date: 2006/10/20 17:24:47 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+
+public class PureIntracomm extends IntracommImpl {
+
+ int bcast_tag = 35 * 1000;
+ int nBARRIER_TAG = (34 * 1000) + 1;
+ int gatherTag = (34 * 1000) + 2;
+ int gathervTag = (34 * 1000) + 3;
+ int scatterTag = (34 * 1000) + 4;
+ int scattervTag = (34 * 1000) + 5;
+ int allgatherTag = (34 * 1000) + 6;
+ int allgathervTag = (34 * 1000) + 7;
+ int alltoallTag = (34 * 1000) + 8;
+ int alltoallvTag = (34 * 1000) + 9;
+ int reduceTag = (34 * 1000) + 10;
+ int allreduceTag = (34 * 1000) + 11;
+ int reducescatterTag = (34 * 1000) + 12;
+ int scanTag = (34 * 1000) + 13;
+
+ PureIntracomm() {
+ }
+
+ int bCount = 1000;
+ ProcTree procTree = null;
+
+ /**
+ * Constructor used to create an intracomm
+ *
+ * @param mpjdev
+ * .Comm The "obvious" way for allocating contexts is each process
+ * independently increments a "next context" variable (a static
+ * variable if you like, but local to the process). Then the
+ * processes in the group do a collective "maxval" of the candidates,
+ * and agree to accept the largest proposal. This is returned as the
+ * result of the collective context allocation, and all processes
+ * also store it in the static variable they use as a starting point
+ * next time round. This algorithm can also allocate several
+ * consecutive contexts in a single phase, which is useful here.
+ **/
+
+ PureIntracomm(mpjdev.Comm mpjdevComm, mpjdev.Group group) throws MPIException {
+ // System.out.println("PureIntracomm");
+ // MPI.logger.debug("--Intracomm--");
+ this.mpjdevComm = mpjdevComm;
+ this.group = new Group(group);
+
+ procTree = new ProcTree();
+
+ int root = 0;
+ int index = Rank();
+ int extent = Size();
+ int places = ProcTree.PROCTREE_A * index;
+
+ // MPI.logger.debug(" init places <"+places+">");
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ // MPI.logger.debug("places "+places);
+ ch %= extent;
+ // MPI.logger.debug("ch "+ch);
+
+ if (places < extent) {
+ // MPI.logger.debug("ch <"+i+">"+"=<"+ch+">");
+ // MPI.logger.debug("adding to the tree at index <"+(i-1) +">\n\n");
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ } else {
+ // MPI.logger.debug("not adding to the tree");
+ }
+ }
+
+ // MPI.logger.debug("procTree.numChildren <"+procTree.numChildren+">");
+
+ if (index == root) {
+ procTree.isRoot = true;
+ // MPI.logger.debug("setting the root flag for root");
+ } else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ // MPI.logger.debug("setting parent for non-root == procTree.parent "+
+ // procTree.parent);
+ }
+
+ procTree.root = root;
+ }
+
+ // needed for our wrapper implementation
+ PureIntracomm(mpjdev.Comm mpjdevComm, mpi.Group _group) throws MPIException {
+ // System.out.println("PureIntracomm");
+ // MPI.logger.debug("--Intracomm--");
+ this.mpjdevComm = mpjdevComm;
+ this.group = _group;
+
+ procTree = new ProcTree();
+
+ int root = 0;
+ int index = Rank();
+ int extent = Size();
+ int places = ProcTree.PROCTREE_A * index;
+
+ // MPI.logger.debug(" init places <"+places+">");
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ // MPI.logger.debug("places "+places);
+ ch %= extent;
+ // MPI.logger.debug("ch "+ch);
+
+ if (places < extent) {
+ // MPI.logger.debug("ch <"+i+">"+"=<"+ch+">");
+ // MPI.logger.debug("adding to the tree at index <"+(i-1) +">\n\n");
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ } else {
+ // MPI.logger.debug("not adding to the tree");
+ }
+ }
+
+ // MPI.logger.debug("procTree.numChildren <"+procTree.numChildren+">");
+
+ if (index == root) {
+ procTree.isRoot = true;
+ // MPI.logger.debug("setting the root flag for root");
+ } else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ // MPI.logger.debug("setting parent for non-root == procTree.parent "+
+ // procTree.parent);
+ }
+
+ procTree.root = root;
+ }
+
+ /**
+ * Partition the group associated with this communicator and create a new
+ * communicator within each subgroup.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> color </tt></td>
+ * <td>control of subset assignment
+ * </tr>
+ * <tr>
+ * <td><tt> key </tt></td>
+ * <td>control of rank assignment
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_SPLIT</tt>.
+ */
+
+ // FIXME: This was returning Intracomm I have changed it to return
+ // PureIntracomm ? This needs a study to find out how natives will be
+ // dealth ?
+ // Fixed it to Intracomm should work now
+ // TODO: remove the above comments
+ public IntracommImpl Split(int color, int key) throws MPIException {
+ PureIntracomm icomm = null; // THIS was Intracomm previously !!!
+ int[][] b = new int[this.group.Size()][3];
+ int len = 0;
+ int a[] = new int[2], ra[] = new int[2];
+ a[0] = color;
+ a[1] = key;
+ ra[0] = 0;
+ ra[1] = 0;
+ b[len][0] = color;
+ b[len][1] = key;
+ b[len][2] = this.group.Rank();
+ len++;
+
+ int size = this.group.Size();
+ int rank = this.group.Rank();
+ int tag = 1110;
+
+ mpi.Request[] reqs = new mpi.Request[size];
+
+ /* send to all processes */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)
+ continue;
+ reqs[i] = isend(a, 0, 2, MPI.INT, i, rank + tag + i, false);
+ }
+
+ /* now receive from all other processes */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)
+ continue;
+ // MPI.out.print("p<"+rank+"> receving from <"+i+">");
+ recv(ra, 0, 2, MPI.INT, i, (tag + i + rank), false);
+
+ if (ra[0] == color) {
+ b[len][0] = ra[0];
+ b[len][1] = ra[1];
+ b[len][2] = i;
+ len++;
+ }
+ }
+
+ /* complete send operation */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)
+ continue;
+ reqs[i].Wait();
+ }
+
+ int keys[] = new int[len];
+ for (int i = 0; i < len; i++) {
+ keys[i] = b[i][1];
+ }
+
+ java.util.Arrays.sort(keys);
+ int nids[] = new int[len];
+
+ for (int i = 0; i < len; i++) {
+ for (int j = 0; j < len; j++) {
+ if (keys[i] == b[j][1])
+ nids[i] = b[j][2];
+ }
+ }
+ /*
+ * StringBuffer nbuffer = new StringBuffer(); nbuffer.append("rank "+rank);
+ * for(int i=0 ; i<this.group.mpjdevGroup.ids.length ; i++) {
+ * nbuffer.append("ids["+i+"]="+this.group.mpjdevGroup.ids[i].uuid());
+ * nbuffer.append("ids["+i+"]="+this.group.mpjdevGroup.ids[i].rank()); }
+ * if(rank == 0) System.out.println("\n "+nbuffer.toString());
+ */
+ try {
+ mpjdev.Comm ncomm = mpjdevComm.create(nids);
+ icomm = new PureIntracomm(ncomm, ncomm.group); // Check the reference type
+ // ??
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return icomm;
+ }
+
+ /**
+ * Clone the communicator This method will be called only by intracommunicator
+ * .... changed the return value to Intracomm ...(instead of Object) ...
+ */
+ public Object clone() throws MPIException {
+ return this.Create(this.group);
+ }
+
+ /**
+ * Create a new communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> group </tt></td>
+ * <td>group which is a subset of the group of this communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_CREATE</tt>.
+ */
+ public IntracommImpl Create(Group group) throws MPIException {
+ mpjdev.Comm tcomm = mpjdevComm.create(group.mpjdevGroup);
+ return (new PureIntracomm(tcomm, group.mpjdevGroup));
+ }
+
+ void nBarrier() throws MPIException {
+ /*
+ * int index = Rank(); int root = 0; ProcTree procTree = new ProcTree(); int
+ * extent = Size(); int places = ProcTree.PROCTREE_A * index;
+ *
+ * for (int i = 1; i <= ProcTree.PROCTREE_A; i++) { ++places; int ch =
+ * (ProcTree.PROCTREE_A * index) + i + root; ch %= extent;
+ *
+ * if (places < extent) { procTree.child[i - 1] = ch;
+ * procTree.numChildren++; } }
+ *
+ * if (index == root) { procTree.isRoot = true; } else { procTree.isRoot =
+ * false; int pr = (index - 1) / ProcTree.PROCTREE_A; procTree.parent = pr;
+ * }
+ *
+ * procTree.root = root;
+ */
+ int offset = 0;
+ Datatype type = MPI.INT;
+ int[] buf = new int[1];
+ int count = 1;
+ int btag = nBARRIER_TAG;
+
+ // ------------------anti-bcast-------------------
+
+ if (procTree.isRoot) {
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1)
+ recv(buf, offset, count, type, procTree.child[i], btag
+ - procTree.child[i], false);
+ }
+ } else {
+ if (procTree.parent == -1) {
+ System.out.println("non root's node parent doesn't exist");
+ }
+
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1)
+ recv(buf, offset, count, type, procTree.child[i], btag
+ - procTree.child[i], false);
+ }
+
+ send(buf, offset, count, type, procTree.parent, btag - Rank(), false);
+ }
+
+ // ------------------bcast-------------------
+
+ if (procTree.isRoot) {
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1)
+ send(buf, offset, count, type, procTree.child[i], btag
+ - procTree.child[i], false);
+ }
+ } else {
+ if (procTree.parent == -1) {
+ System.out.println("non root's node parent doesn't exist");
+ }
+
+ recv(buf, offset, count, type, procTree.parent, btag - Rank(), false);
+
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1)
+ send(buf, offset, count, type, procTree.child[i], btag
+ - procTree.child[i], false);
+ }
+ }
+
+ }
+
+ void newBarrier() throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--new Barrier starts--");
+ }
+ int size = Size();
+ int rank = Rank();
+ Request req = null;
+ int stuff[] = new int[1];
+ int y = (int) Math.pow(2d, Math.floor(Math.log(size) / Math.log(2)));
+
+ if (rank >= y) {
+
+ try {
+ req = isend(stuff, 0, 1, MPI.INT, rank - y,
+ ((999 + rank - y) * bCount), false);
+ recv(stuff, 0, 1, MPI.INT, rank - y, ((999 + rank) * bCount), false);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ req.Wait();
+
+ } else {
+
+ if ((size - y) > rank) {
+
+ try {
+ recv(stuff, 0, 1, MPI.INT, rank + y, (999 + rank) * bCount, false);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+
+ int round = -1;
+ int peer = 0;
+
+ do {
+ round = round + 1;
+ peer = rank ^ (int) Math.pow(2d, round);
+ try {
+ req = isend(stuff, 0, 1, MPI.INT, peer, (999 + peer) * bCount, false);
+ recv(stuff, 0, 1, MPI.INT, peer, (999 + rank) * bCount, false);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ } while (round != ((int) (Math.log(y) / Math.log(2)) - 1));
+
+ if ((size - y) > rank) {
+
+ try {
+ req = isend(stuff, 0, 1, MPI.INT, rank + y,
+ (999 + rank + y) * bCount, false);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ }
+
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--new Barrier ends--");
+ }
+
+ private void exoticBarrier() throws MPIException {
+ int size, rank, src, dst, mask;
+
+ size = Size();
+ rank = Rank();
+ byte[] barrierMsg = new byte[1];
+ mask = 0x1;
+
+ while (mask < size) {
+ dst = (rank + mask) % size;
+ src = (rank - mask + size) % size;
+
+ sendrecv(barrierMsg, 0, 1, MPI.BYTE, dst, nBARRIER_TAG, barrierMsg, 0, 1,
+ MPI.BYTE, src, nBARRIER_TAG);
+ mask <<= 1;
+ }
+
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * /** A call to <tt>Barrier</tt> blocks the caller until all process in the
+ * group have called it.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BARRIER</tt>.
+ */
+ public void Barrier() throws MPIException {
+ // System.out.println("Dummy: PureIntracomm Barrier");
+ if (Size() == 1) {
+ return;
+ }
+
+ if (EXOTIC_BARRIER) {
+ exoticBarrier();
+ return;
+ }
+
+ nBarrier();
+ // newBarrier();
+ /*
+ * MPI.logger.debug("--Barrier starts--"); bCount++; int size = Size(); int
+ * rank = Rank(); Request req = null; int stuff[] = new int[1]; int y =
+ * (int) Math.pow(2d, Math.floor(Math.log(size) / Math.log(2)));
+ * MPI.logger.debug("y " + y);
+ *
+ * if (rank >= y) { MPI.logger.debug("Group B"); MPI.logger.debug(" pro<" +
+ * rank + "> sending a message with tag<" + ( (999 + rank - y) * bCount) +
+ * "> to pro<" + (rank - y)); req = isend(stuff, 0, 1, MPI.INT, rank - y, (
+ * (999 + rank - y) * bCount), false); MPI.logger.debug(" pro<" + rank +
+ * "> receiving a message with tag<" + ( (999 + rank) * bCount) +
+ * "> from pro<" + (rank - y)); try { recv(stuff, 0, 1, MPI.INT, rank - y, (
+ * (999 + rank) * bCount), false); } catch (Exception e) { throw new
+ * MPIException( e ); }
+ *
+ * req.Wait(); } else { MPI.logger.debug("Group A"); if ( (size - y) > rank)
+ * { MPI.logger.debug("this process got partners in Group B");
+ * MPI.logger.debug(" pro<" + rank + "> sending a message with tag<" + (
+ * (999 + rank) * bCount) + "> to pro<" + (rank + y)); try { recv(stuff, 0,
+ * 1, MPI.INT, rank + y, (999 + rank) * bCount, false); } catch (Exception
+ * e) { throw new MPIException( e ); } }
+ *
+ * int round = -1; int peer = 0;
+ *
+ * do { round = round + 1; MPI.logger.debug("round " + round);
+ * MPI.logger.debug("round limit <" + (Math.log(y) / Math.log(2))); peer =
+ * rank ^ (int) Math.pow(2d, round); MPI.logger.debug("peer " + peer);
+ * MPI.logger.debug(" pro<" + rank + "> sending a message with tag<" + (
+ * (999 + peer) * bCount) + "> to pro<" + peer + ">"); req = isend(stuff, 0,
+ * 1, MPI.INT, peer, (999 + peer) * bCount, false); MPI.logger.debug(" pro<"
+ * + rank + "> receiving a message with tag<" + ( (999 + rank) * bCount) +
+ * "> from pro<" + peer + ">"); try { recv(stuff, 0, 1, MPI.INT, peer, (999
+ * + rank) * bCount, false); } catch (Exception e) { throw new MPIException(
+ * e ); }
+ *
+ * req.Wait();
+ *
+ * } while (round != ( (int) (Math.log(y) / Math.log(2)) - 1));
+ *
+ * if ( (size - y) > rank) { MPI.logger.debug(" pro<" + rank +
+ * "> sending a message with tag<" + ( (999 + rank + y) * bCount) +
+ * "> to pro<" + (rank + y) + ">"); req = isend(stuff, 0, 1, MPI.INT, rank +
+ * y, (999 + rank + y) * bCount, false); req.Wait(); }
+ *
+ * }
+ *
+ * if (bCount == Integer.MAX_VALUE - 1) bCount = 1000;
+ *
+ * MPI.logger.debug("--Barrier ends--");
+ */
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of broadcast root
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BCST</tt>.
+ */
+
+ public void Bcast(Object buf, int offset, int count, Datatype type, int root)
+ throws MPIException {
+
+ int index = Rank();
+
+ if (root != 0) {
+ if (root == index)
+ send(buf, offset, count, type, 0, bcast_tag, false);
+
+ if (index == 0)
+ recv(buf, offset, count, type, root, bcast_tag - Rank(), false);
+ }
+
+ root = 0;
+ /*
+ * ProcTree procTree = new ProcTree(); int extent = Size(); int places =
+ * ProcTree.PROCTREE_A * index;
+ *
+ * //MPI.logger.debug(" init places <"+places+">");
+ *
+ * for (int i = 1; i <= ProcTree.PROCTREE_A; i++) { ++places; int ch =
+ * (ProcTree.PROCTREE_A * index) + i + root;
+ * //MPI.logger.debug("places "+places); ch %= extent;
+ * //MPI.logger.debug("ch "+ch);
+ *
+ * if (places < extent) { //MPI.logger.debug("ch <"+i+">"+"=<"+ch+">");
+ * //MPI.logger.debug("adding to the tree at index <"+(i-1) +">\n\n");
+ * procTree.child[i - 1] = ch; procTree.numChildren++; } else {
+ * //MPI.logger.debug("not adding to the tree"); } }
+ *
+ * //MPI.logger.debug("procTree.numChildren <"+procTree.numChildren+">");
+ *
+ * if (index == root) { procTree.isRoot = true;
+ * //MPI.logger.debug("setting the root flag for root"); } else {
+ * procTree.isRoot = false; int pr = (index - 1) / ProcTree.PROCTREE_A;
+ * procTree.parent = pr;
+ * //MPI.logger.debug("setting parent for non-root == procTree.parent "+ //
+ * procTree.parent); }
+ *
+ * procTree.root = root;
+ *
+ * //for (int i = 0; i < procTree.PROCTREE_A; i++) {
+ * //MPI.out.print(" child["+i+"]=>"+procTree.child[i]); //}
+ *
+ * //MPI.logger.debug(" ------- End --------");
+ * //MPI.logger.debug("---Bcast---");
+ */
+
+ if (procTree.isRoot) {
+ // MPI.logger.debug("This process is root");
+ for (int i = 0; i < procTree.child.length; i++) {
+ // MPI.logger.debug("sending to children <"+i+">");
+ // MPI.logger.debug("procTree.child[i] <"+procTree.child[i]+">");
+ if (procTree.child[i] != -1)
+ send(buf, offset, count, type, procTree.child[i], bcast_tag
+ - procTree.child[i], false);
+ // MPI.logger.debug("Sent");
+ }
+ } else {
+ if (procTree.parent == -1) {
+ System.out.println("non root's node parent doesn't exist");
+ }
+ // MPI.logger.debug("This process is not root");
+ // MPI.logger.debug("receiving from parent ");
+ // MPI.logger.debug("procTree.parent <"+procTree.parent+">");
+ recv(buf, offset, count, type, procTree.parent, bcast_tag - Rank(), false);
+
+ for (int i = 0; i < procTree.child.length; i++) {
+ // MPI.logger.debug("sending to children <"+i+">");
+ // MPI.logger.debug("procTree.child[i] <"+procTree.child[i]+">");
+ if (procTree.child[i] != -1)
+ send(buf, offset, count, type, procTree.child[i], bcast_tag
+ - procTree.child[i], false);
+ // MPI.logger.debug("Sent");
+ }
+ }
+
+ /*
+ * 0(N) algorithm ... if(root == Rank()) { for(int i=0;i<Size();i++) { if(i
+ * == Rank()) continue;
+ *
+ * send(buf,offset,count,type,i,bcast_tag-i, false);
+ * //MPI.logger.debug("root "+root+" sent msg to "+i); } }else {
+ * recv(buf,offset,count,type,root,bcast_tag-Rank(), false);
+ * //MPI.logger.debug("process "+Rank()+" recvd msg from"+root); }
+ */
+
+ // MPI.logger.debug("--Bcast ends--");
+ if (bcast_tag == 65535) {
+ bcast_tag = 35 * 1000;
+ }
+ bcast_tag++;
+ }
+
+ /**
+ * Each process sends the contents of its send buffer to the root process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHER</tt>.
+ */
+ public void Gather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Gather--");
+ int rcount = -1, roffset = -1, soffset = -1, scount = -1;
+ Request req = null;
+ if (root != Rank()) {
+ req = isend(sendbuf, sendoffset, sendcount, sendtype, root, gatherTag
+ + Rank(), false);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("ssent to " + root);
+ }
+ } else {
+ scount = sendcount;
+ soffset = sendoffset;
+ }
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (i != root) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("root " + root + " getting from " + i);
+ recv(recvbuf, recvoffset, recvcount, recvtype, i, gatherTag + i,
+ false);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("root " + root + " got from " + i);
+ } else {
+ roffset = recvoffset;
+ rcount = recvcount;
+ }
+
+ recvoffset += recvcount;
+ }
+ }
+ if (rcount != scount) {
+ System.out.println(" scount != rcount, should not happen");
+ System.out.println(" this is Reduce method");
+ }
+
+ if (root == Rank()) {
+ System.arraycopy(sendbuf, soffset, recvbuf, roffset, rcount);
+ } else {
+ req.Wait();
+ }
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Gather ends--");
+ }
+
+ /**
+ * Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ * from each process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ * <p>
+ * The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ * size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ * displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt> at
+ * which to place incoming data.
+ */
+ public void Gatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype, int root) throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Gatherv--");
+ int rcount = -1, roffset = -1;
+ Request req = null;
+ if (root != Rank()) {
+ req = isend(sendbuf, sendoffset, sendcount, sendtype, root, gathervTag
+ + Rank(), false);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("ssent to " + root);
+ }
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (i != root) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("root " + root + " getting from " + i);
+ recv(recvbuf, recvoffset + displs[i], recvcount[i], recvtype, i,
+ gathervTag + i, false);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("root " + root + " got from " + i);
+ } else {
+ roffset = recvoffset + displs[i];
+ rcount = recvcount[i];
+ }
+ }
+ }
+
+ if (root == Rank()) {
+ if (rcount != sendcount) {
+ System.out.println(" scount != rcount, should not happen");
+ System.out.println(" this is Reduce method");
+ }
+
+ System.arraycopy(sendbuf, sendoffset, recvbuf, roffset, rcount);
+ } else {
+ req.Wait();
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Gatherv ends--");
+ }
+
+ /**
+ * Inverse of the operation <tt>Gather</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTER</tt>.
+ */
+
+ public void Scatter(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype, int root) throws MPIException {
+
+ // MPI.logger.debug("--Scatter--");
+ Request[] reqs = new Request[Size()];
+ int soffset = -1, scount = -1;
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (root != i)
+ reqs[i] = isend(sendbuf, sendoffset, sendcount, sendtype, i,
+ scatterTag + i, false);
+
+ else {
+ soffset = sendoffset;
+ scount = sendcount;
+ }
+ sendoffset += sendcount;
+ }
+ }
+
+ if (root != Rank())
+ recv(recvbuf, recvoffset, recvcount, recvtype, root, scatterTag + Rank(),
+ false);
+ else {
+ if (scount != recvcount) {
+ System.out.println(" scount shuld be equal to recvcount");
+ }
+ System.arraycopy(sendbuf, soffset, recvbuf, recvoffset, recvcount);
+ }
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (i != root)
+ reqs[i].Wait();
+ }
+ }
+
+ // MPI.logger.debug("--Scatter ends--");
+ }
+
+ /**
+ * Inverse of the operation <tt>Gatherv</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.
+ */
+ public void Scatterv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] displs, Datatype sendtype, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int root) throws MPIException {
+
+ // MPI.logger.debug("--Scatter--");
+ Request[] reqs = new Request[Size()];
+ int soffset = -1, scount = -1;
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (root != i)
+ reqs[i] = isend(sendbuf, sendoffset + displs[i], sendcount[i],
+ sendtype, i, scattervTag + i, false);
+ else {
+ soffset = sendoffset + displs[i];
+ scount = sendcount[i];
+ }
+ }
+ }
+
+ if (root != Rank())
+ recv(recvbuf, recvoffset, recvcount, recvtype, root,
+ scattervTag + Rank(), false);
+ else {
+ if (scount != recvcount) {
+ System.out.println(" scount shuld be equal to recvcount");
+ }
+ System.arraycopy(sendbuf, soffset, recvbuf, recvoffset, recvcount);
+ }
+
+ if (root == Rank()) {
+ for (int i = 0; i < Size(); i++) {
+ if (i != root)
+ reqs[i].Wait();
+ }
+ }
+
+ // MPI.logger.debug("--Scatter ends--");
+ }
+
+ /**
+ * Similar to <tt>Gather</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.
+ */
+
+ public void Allgather(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) throws MPIException {
+
+ if (EXOTIC_ALLGATHER) {
+
+ int me = Rank();
+ int size = Size();
+
+ int pof2 = 1;
+
+ while (pof2 < size)
+ pof2 *= 2;
+
+ if (pof2 == size)
+ pof2 = 1;
+ else
+ pof2 = 0;
+
+ System.arraycopy(sendbuf, sendoffset, recvbuf, recvcount * me, recvcount);
+
+ int curr_cnt = recvcount;
+
+ int mask = 0x1;
+ int i = 0, dst;
+ int dst_tree_root, my_tree_root;
+ int send_offset, recv_offset;
+ int last_recv_cnt;
+
+ while (mask < size) {
+
+ dst = me ^ mask;
+
+ dst_tree_root = dst >> i;
+ dst_tree_root <<= i;
+
+ my_tree_root = me >> i;
+ my_tree_root <<= i;
+
+ send_offset = my_tree_root * recvcount;
+ recv_offset = dst_tree_root * recvcount;
+
+ Status status = sendrecv(recvbuf, send_offset, curr_cnt, sendtype, dst,
+ allgatherTag, recvbuf, recv_offset, recvcount * mask, recvtype,
+ dst, allgatherTag);
+
+ last_recv_cnt = status.Get_count(recvtype);
+ curr_cnt += last_recv_cnt;
+
+ mask <<= 1;
+ i++;
+
+ } // end while
+
+ } // end if(true)
+
+ else {
+ // MPI.logger.debug("--Allgather--");
+ Request req[] = new Request[Size()];
+ int rcount = -1, roffset = -1;
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i] = isend(sendbuf, sendoffset, sendcount, sendtype, i,
+ allgatherTag + i + Rank(), false);
+ }
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank())
+ recv(recvbuf, recvoffset, recvcount, recvtype, i, allgatherTag
+ + Rank() + i, false);
+ else {
+ rcount = recvcount;
+ roffset = recvoffset;
+ }
+
+ recvoffset += recvcount;
+ }
+
+ // if (rcount != sendcount) {
+ // System.out.println("rcount not equal to sendcount");
+ // System.out.println("this is not possible, should not happen!");
+ // }
+
+ System.arraycopy(sendbuf, sendoffset, recvbuf, roffset, rcount);
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i].Wait();
+ }
+ }
+
+ // MPI.logger.debug("--Allgather Ends--");
+ }
+
+ static boolean EXOTIC_ALLGATHER = false;
+ static boolean EXOTIC_ALLGATHERV = false;
+ static boolean EXOTIC_BARRIER = false;
+
+ /**
+ * Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.
+ */
+ public void Allgatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype) throws MPIException {
+
+ if (EXOTIC_ALLGATHERV) {
+ int total_count = 0;
+ Object tmp_buf = null;
+ int me = Rank();
+ int size = Size();
+
+ for (int i = 0; i < recvcount.length; i++) {
+ total_count += recvcount[i];
+ }
+
+ if (total_count == 0) {
+ return;
+ }
+
+ int pof2 = 1;
+
+ while (pof2 < size)
+ pof2 *= 2;
+
+ if (pof2 == size)
+ pof2 = 1;
+ else
+ pof2 = 0;
+
+ if (sendtype == MPI.LONG) {
+ tmp_buf = new long[total_count];
+ tmp_buf = (long[]) tmp_buf;
+ } else if (sendtype == MPI.INT) {
+ tmp_buf = new int[total_count];
+ tmp_buf = (int[]) tmp_buf;
+ }
+
+ int position = 0;
+
+ for (int i = 0; i < me; i++) {
+ position += recvcount[i];
+ }
+
+ System.arraycopy(sendbuf, sendoffset, tmp_buf, position, recvcount[me]);
+
+ int curr_cnt = recvcount[me];
+
+ int mask = 0x1;
+ int i = 0, dst;
+ int dst_tree_root, my_tree_root;
+ int send_offset, recv_offset;
+ int last_recv_cnt;
+
+ while (mask < size) {
+
+ dst = me ^ mask;
+
+ dst_tree_root = dst >> i;
+ dst_tree_root <<= i;
+
+ my_tree_root = me >> i;
+ my_tree_root <<= i;
+
+ send_offset = 0;
+
+ for (int j = 0; j < my_tree_root; j++)
+ send_offset += recvcount[j];
+
+ recv_offset = 0;
+
+ for (int j = 0; j < dst_tree_root; j++)
+ recv_offset += recvcount[j];
+
+ Status status = sendrecv(tmp_buf, send_offset, curr_cnt, sendtype, dst,
+ allgathervTag, tmp_buf, recv_offset, total_count, recvtype, dst,
+ allgathervTag);
+
+ last_recv_cnt = status.Get_count(recvtype);
+ curr_cnt += last_recv_cnt;
+
+ mask <<= 1;
+ i++;
+
+ } // end while
+
+ position = 0;
+ for (int j = 0; j < size; j++) {
+
+ System.arraycopy(tmp_buf, position, recvbuf, recvoffset + displs[j],
+ recvcount[j]);
+ position += recvcount[j];
+
+ }
+
+ } // end if(true)
+
+ else {
+
+ // MPI.logger.debug("--Allgatherv--");
+ Request req[] = new Request[Size()];
+ Request rreq[] = new Request[Size()];
+ int rcount = -1, roffset = -1, i = 0;
+
+ for (i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i] = isend(sendbuf, sendoffset, sendcount, sendtype, i,
+ allgathervTag + i + Rank(), false);
+ }
+
+ for (i = 0; i < Size(); i++) {
+ if (i != Rank())
+ rreq[i] = irecv(recvbuf, recvoffset + displs[i], recvcount[i],
+ recvtype, i, allgathervTag + i + Rank(), false);
+ else {
+ rcount = recvcount[i];
+ roffset = recvoffset + displs[i];
+ }
+
+ }
+
+ // if (rcount != sendcount) {
+ // System.out.println("rcount not equal to sendcount");
+ // System.out.println("this is not possible, should not happen!");
+ // }
+
+ System.arraycopy(sendbuf, sendoffset, recvbuf, roffset, rcount);
+
+ for (i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i].Wait();
+ }
+
+ for (i = 0; i < Size(); i++) {
+ if (i != Rank())
+ rreq[i].Wait();
+ }
+ // MPI.logger.debug("--Allgather Ends--");
+
+ }
+ }
+
+ /**
+ * Extension of <tt>Allgather</tt> to the case where each process sends
+ * distinct data to each of the receivers.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items received from any process
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of receive buffer items
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.
+ */
+
+ public void Alltoall(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int recvcount,
+ Datatype recvtype) throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--All to all--");
+ Request req[] = new Request[Size()];
+ int soffset = -1, scount = -1, roffset = -1, rcount = -1;
+
+ for (int i = 0; i < Size(); i++) {
+
+ if (i != Rank()) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("proc <" + Rank() + ">-sending message to proc<" + i
+ + ">");
+ req[i] = isend(sendbuf, sendoffset, sendcount, sendtype, i, alltoallTag
+ * (76 + (i + 1)), false);
+ } else {
+ soffset = sendoffset;
+ scount = sendcount;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("soffset" + soffset);
+ MPI.logger.debug("scount" + scount);
+ MPI.logger.debug("process " + Rank() + "sent to process " + i);
+ }
+ sendoffset += sendcount;
+ }
+
+ for (int i = 0; i < Size(); i++) {
+
+ if (i != Rank()) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger
+ .debug("proc <" + Rank() + "> recving from proc<" + i + ">");
+ }
+ recv(recvbuf, recvoffset, recvcount, recvtype, i, alltoallTag
+ * (76 + (Rank() + 1)), false);
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("recvoffset " + recvoffset);
+ MPI.logger.debug("recvcount " + recvcount);
+ MPI.logger.debug("process " + Rank() + "recvd from process " + i);
+ }
+ } else {
+ roffset = recvoffset;
+ rcount = recvcount;
+ }
+ recvoffset += recvcount;
+ }
+
+ // copy from sendbuffer to recvbuffer ...
+ if (scount != rcount) {
+ System.out.println("Alltoall, rcount not equal to scount");
+ System.out.println("this can never happen ...");
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("copying the message from sendbuffer to recvbuffer");
+ }
+ System.arraycopy(sendbuf, soffset, recvbuf, roffset, rcount);
+
+ for (int i = 0; i < Size(); i++) {
+ if (i == Rank())
+ continue;
+
+ req[i].Wait();
+ }
+ }
+
+ /**
+ * Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ * specified by <tt>sdispls</tt> and location to place data on receive side is
+ * specified by <tt>rdispls</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sdispls </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * <tr>
+ * <td><tt> rdispls </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.
+ */
+
+ public void Alltoallv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] sdispls, Datatype sendtype, Object recvbuf, int recvoffset,
+ int[] recvcount, int[] rdispls, Datatype recvtype) throws MPIException {
+
+ // MPI.logger.debug("--All to all--");
+ Request req[] = new Request[Size()];
+ int soffset = -1, scount = -1, roffset = -1, rcount = -1;
+
+ for (int i = 0; i < Size(); i++) {
+
+ if (i != Rank()) {
+ req[i] = isend(sendbuf, sendoffset + sdispls[i], sendcount[i],
+ sendtype, i, alltoallvTag, false);
+ } else {
+ soffset = sendoffset + sdispls[i];
+ scount = sendcount[i];
+ }
+
+ // MPI.logger.debug("sendoffset "+sendoffset);
+ // MPI.logger.debug("sendcount "+sendcount);
+ // MPI.logger.debug("process "+Rank()+"sent to process "+i);
+ }
+
+ for (int i = 0; i < Size(); i++) {
+
+ // MPI.logger.debug("process "+Rank()+"recving from process "+i);
+ if (i != Rank()) {
+ recv(recvbuf, recvoffset + rdispls[i], recvcount[i], recvtype, i,
+ alltoallvTag, false);
+ } else {
+ roffset = recvoffset + rdispls[i];
+ rcount = recvcount[i];
+ }
+ // MPI.logger.debug("recvoffset "+recvoffset);
+ // MPI.logger.debug("recvcount "+recvcount);
+ // MPI.logger.debug("process "+Rank()+"recvd from process "+i);
+ }
+
+ // copy from sendbuffer to recvbuffer ...
+ if (scount != rcount) {
+ System.out.println("Alltoall, rcount not equal to scount");
+ System.out.println("this can never happen ...");
+ }
+
+ System.arraycopy(sendbuf, soffset, recvbuf, roffset, rcount);
+
+ for (int i = 0; i < Size(); i++) {
+ if (i == Rank())
+ continue;
+
+ req[i].Wait();
+ }
+
+ }
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and return the combined value in the output buffer of the root
+ * process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of root process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ * <p>
+ * The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ * <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ * <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ * <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.
+ */
+
+ public void Reduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op, int root)
+ throws MPIException {
+
+ if (op.worker == null) {
+
+ Request req = null;
+ // BUG:
+ // Object tmpbuf = sendbuf;
+ Object tmpbuf = createTemporaryBuffer(datatype, count);
+
+ if (root != Rank())
+ req = isend(sendbuf, sendoffset, count, datatype, root, reduceTag,
+ false);
+ else
+ System.arraycopy(sendbuf, sendoffset, tmpbuf, sendoffset, count
+ * datatype.size);
+
+ if (Rank() == root) {
+ for (int i = 0; i < Size(); i++) {
+ if (i == Rank()) {
+ continue;
+ }
+ recv(recvbuf, recvoffset, count, datatype, i, reduceTag, false);
+ op.funct.Call(recvbuf, recvoffset, tmpbuf, sendoffset, count,
+ datatype);
+ }
+ }
+
+ if (root != Rank())
+ req.Wait();
+
+ System.arraycopy(tmpbuf, sendoffset, recvbuf, recvoffset, count
+ * datatype.size);
+ return;
+
+ }// end if user_defined datatypes.
+
+ /* Code for pre-defined operations */
+ Op op2 = op.worker.getWorker(datatype);
+ op2.createInitialBuffer(sendbuf, sendoffset, count);
+ Request req = null;
+
+ if (root != Rank())
+ req = isend(sendbuf, sendoffset, count, datatype, root, reduceTag, false);
+ // else
+ // op2.perform(sendbuf, sendoffset, count);
+
+ if (Rank() == root) {
+ for (int i = 0; i < Size(); i++) {
+ if (i == Rank()) {
+ continue;
+ }
+ recv(recvbuf, recvoffset, count, datatype, i, reduceTag, false);
+ op2.perform(recvbuf, recvoffset, count);
+ }
+ }
+
+ op2.getResultant(recvbuf, recvoffset, count);
+
+ if (root != Rank())
+ req.Wait();
+
+ }
+
+ static boolean EXOTIC_ALLREDUCE = false;
+
+ /**
+ * Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ * all process in the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.
+ */
+
+ Object createTemporaryBuffer(Datatype datatype, int count) {
+
+ Object tempBuffer = null;
+
+ switch (datatype.baseType) {
+
+ case Datatype.UNDEFINED:
+ System.out.println("Intracomm.createTemporaryBuffer() - "
+ + "UNDEFINED datatype");
+ break;
+
+ case Datatype.NULL:
+ System.out.println("Intracomm.createTemporaryBuffer() - "
+ + "NULL datatype");
+ break;
+
+ case Datatype.BYTE:
+ tempBuffer = new byte[count * datatype.Size()];
+ break;
+
+ case Datatype.CHAR:
+ tempBuffer = new char[count * datatype.Size()];
+ break;
+
+ case Datatype.SHORT:
+ tempBuffer = new short[count * datatype.Size()];
+ break;
+
+ case Datatype.BOOLEAN:
+ tempBuffer = new byte[count * datatype.Size()];
+ break;
+
+ case Datatype.INT:
+ tempBuffer = new int[count * datatype.Size()];
+ break;
+
+ case Datatype.LONG:
+ tempBuffer = new long[count * datatype.Size()];
+ break;
+
+ case Datatype.FLOAT:
+ tempBuffer = new float[count * datatype.Size()];
+ break;
+
+ case Datatype.DOUBLE:
+ tempBuffer = new double[count * datatype.Size()];
+ break;
+
+ case Datatype.PACKED:
+ System.out.println("Intracomm.createTemporaryBuffer() - "
+ + "PACKED datatype");
+ break;
+
+ case Datatype.OBJECT:
+ // System.out.println("Intracomm.createTemporaryBuffer() - "+
+ // "OBJECT datatype");
+ tempBuffer = new Object[count * datatype.Size()];
+ break;
+
+ default:
+ System.out.println("Intracomm.createTemporaryBuffer() - "
+ + "default datatype");
+ break;
+ }
+
+ return tempBuffer;
+
+ }
+
+ public void Allreduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("Allreduce called");
+ }
+
+ if (op.worker == null) {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("User-defined ops ..but should not "
+ + "see this for MAXLOC ");
+ }
+ Request req[] = new Request[Size()];
+
+ // BUG: this is a bug, identified by Sarah Nakao
+ // Object tmpbuf = sendbuf;
+ Object tmpbuf = createTemporaryBuffer(datatype, count);
+
+ for (int i = 0; i < req.length; i++) {
+ if (i != Rank())
+ req[i] = isend(sendbuf, sendoffset, count, datatype, i, allreduceTag,
+ false);
+ else
+ System.arraycopy(sendbuf, sendoffset, tmpbuf, sendoffset, count
+ * datatype.size);
+ }
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank()) {
+ recv(recvbuf, recvoffset, count, datatype, i, allreduceTag, false);
+ op.funct.Call(recvbuf, recvoffset, tmpbuf, sendoffset, count,
+ datatype);
+ }
+ }
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i].Wait();
+ }
+
+ // why is it count.datatype.size ???
+ System.arraycopy(tmpbuf, sendoffset, recvbuf, recvoffset, count
+ * datatype.size);
+ return;
+
+ } // end if user_defined datatypes.
+
+ else {
+
+ if (EXOTIC_ALLREDUCE) {
+
+ Op op2 = op.worker.getWorker(datatype);
+
+ op2.createInitialBuffer(sendbuf, sendoffset, count * datatype.size);
+ op2.getResultant(recvbuf, recvoffset, count);
+
+ int mask = 0x1;
+ int i = 0, dst;
+ int me = Rank();
+ int size = Size();
+
+ while (mask < size) {
+
+ dst = me ^ mask;
+
+ sendrecv(recvbuf, sendoffset, count, datatype, dst, allreduceTag,
+ sendbuf, recvoffset, count, datatype, dst, allreduceTag);
+
+ op2.perform(sendbuf, recvoffset, count);
+ op2.getResultant(recvbuf, recvoffset, count);
+ mask <<= 1;
+ }
+
+ return;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("Pre defined ops");
+
+ Op op2 = op.worker.getWorker(datatype);
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("got worker");
+
+ op2.createInitialBuffer(sendbuf, sendoffset, count * datatype.size);
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("created initial buffer ");
+
+ Request req[] = new Request[Size()];
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("sending messages ");
+
+ for (int i = 0; i < req.length; i++) {
+ if (i != Rank())
+ req[i] = isend(sendbuf, sendoffset, count, datatype, i, allreduceTag,
+ false);
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("receiving messages ");
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank()) {
+ recv(recvbuf, recvoffset, count, datatype, i, allreduceTag, false);
+ op2.perform(recvbuf, recvoffset, count);
+ }
+ }
+
+ op2.getResultant(recvbuf, recvoffset, count);
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("got resultant ..");
+
+ for (int i = 0; i < Size(); i++) {
+ if (i != Rank())
+ req[i].Wait();
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" All reduce ends ");
+
+ return;
+ }
+
+ } // end Allreduce
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and scatter the combined values over the output buffers of the
+ * processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>numbers of result elements distributed to each process
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.
+ */
+ public void Reduce_scatter(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int[] recvcounts, Datatype datatype, Op op)
+ throws MPIException {
+
+ int root = 0, myself = Rank();
+ int sendcount = 0;
+
+ for (int k = 0; k < recvcounts.length; k++) {
+ sendcount += recvcounts[k];
+ }
+
+ Reduce(sendbuf, sendoffset, recvbuf, recvoffset, sendcount, datatype, op,
+ root);
+ Scatter(recvbuf, recvoffset, recvcounts[myself], datatype, recvbuf,
+ recvoffset, recvcounts[myself], datatype, root);
+ }
+
+ /**
+ * Perform a prefix reduction on data distributed across the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in input buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCAN</tt>.
+ */
+
+ public void Scan(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) throws MPIException {
+
+ if (op.worker == null) {
+
+ Request req[] = new Request[Size()];
+ // BUG:
+ // Object tmpbuf = sendbuf;
+ Object tmpbuf = createTemporaryBuffer(datatype, count);
+ System.arraycopy(sendbuf, sendoffset, tmpbuf, sendoffset, count
+ * datatype.size);
+
+ for (int i = (Size() - 1); i > Rank(); i--) {
+ req[i] = isend(sendbuf, sendoffset, count, datatype, i, scanTag, false);
+ }
+
+ for (int i = 0; i < Rank(); i++) {
+ recv(recvbuf, recvoffset, count, datatype, i, scanTag, false);
+ op.funct.Call(recvbuf, recvoffset, tmpbuf, sendoffset, count, datatype);
+ }
+
+ for (int i = (Size() - 1); i > Rank(); i--) {
+ req[i].Wait();
+ }
+
+ System.arraycopy(tmpbuf, sendoffset, recvbuf, recvoffset, count
+ * datatype.size);
+ return;
+
+ }// end if user_defined datatypes.
+
+ Op op2 = op.worker.getWorker(datatype);
+ op2.createInitialBuffer(sendbuf, sendoffset, count);
+ Request req[] = new Request[Size()];
+ // op2.perform(sendbuf, sendoffset, count);
+ for (int i = (Size() - 1); i > Rank(); i--) {
+ req[i] = isend(sendbuf, sendoffset, count, datatype, i, scanTag, false);
+ }
+
+ for (int i = 0; i < Rank(); i++) {
+ recv(recvbuf, recvoffset, count, datatype, i, scanTag, false);
+ op2.perform(recvbuf, recvoffset, count);
+ }
+
+ op2.getResultant(recvbuf, recvoffset, count);
+
+ for (int i = (Size() - 1); i > Rank(); i--) {
+ req[i].Wait();
+ }
+
+ }
+
+}
diff --git a/src/mpi/Request.java b/src/mpi/Request.java
new file mode 100755
index 0000000..de5e978
--- /dev/null
+++ b/src/mpi/Request.java
@@ -0,0 +1,551 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Request.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.26 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import java.util.ArrayList;
+
+public class Request {
+ public mpjdev.Request req = null;
+ Datatype datatype = null;
+ boolean isNull = false;
+ static final int NULL = 2;
+ int code = -1;
+
+ Request() {
+ }
+
+ Request(int code) {
+ this.code = code;
+ }
+
+ Request(boolean isNull) {
+ this.isNull = isNull;
+ }
+
+ /**
+ */
+ public Request(mpjdev.Request req) {
+ this.req = req;
+ }
+
+ /**
+ * Blocks until the operation identified by the request is complete.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WAIT</tt>.
+ * <p>
+ * After the call returns, the request object becomes inactive.
+ */
+ public Status Wait() throws MPIException {
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("--Wait--");
+ }
+
+ if (isNull) {
+ return MPI.EMPTY_STATUS;
+ }
+
+ if (this.req == null) {
+ System.out.println(" mpjdev Request is null in Wait() ");
+ return null;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("calling wait of niodev ");
+
+ mpjdev.Status mpjdevStatus = this.req.iwait();
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("called wait of niodev ");
+
+ isNull = true;
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--Wait ends --");
+
+ Status status = new mpi.Status(mpjdevStatus);
+ // status.source = ? ;
+ return status;
+
+ }
+
+ private Status Test(boolean nothing) throws MPIException {
+
+ if (isNull == true) {
+ return new Status();
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("-- Test (boolean) ");
+ mpi.Status status = null;
+ mpjdev.Status devStatus = null;
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("this.req " + this.req);
+ if (this.req != null) {
+ devStatus = this.req.itest();
+ } else
+ return null;
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" returned devStatus ");
+
+ if (devStatus == null) {
+ return null;
+ }
+
+ return new Status();
+ }
+
+ /**
+ * Returns a status object if the operation identified by the request is
+ * complete, or a null reference otherwise.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object or null reference
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TEST</tt>.
+ * <p>
+ * After the call, if the operation is complete (ie, if the return value is
+ * non-null), the request object becomes inactive.
+ */
+ public Status Test() throws MPIException {
+
+ if (isNull) {
+ return MPI.EMPTY_STATUS;
+ }
+
+ mpi.Status status = null;
+ mpjdev.Status devStatus = null;
+
+ if (this.req != null) {
+ devStatus = this.req.itest();
+
+ } else
+ return null;
+
+ if (devStatus == null) {
+
+ return null;
+ }
+ if (mpjdev.Constants.isNative) {
+ // for native device case
+ isNull = true;
+
+ status = new mpi.Status(devStatus);
+ // status.source = ? ;
+ return status;
+
+ } else {
+
+ status = Wait();
+ return status;
+ }
+ }
+
+ /**
+ * Tests for completion of either one or none of the operations associated
+ * with active requests.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object or null reference
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TESTANY</tt>.
+ * <p>
+ * If some request completed, the index in <tt>array_of_requests</tt> for that
+ * request can be obtained from the returned status object through the. The
+ * corresponding element of <tt>array_of_requests</tt> becomes inactive. If no
+ * request completed, <tt>Testany</tt> returns a null reference.
+ */
+ public static Status Testany(Request[] r) throws MPIException {
+
+ Status s = null;
+
+ for (int i = 0; i < r.length; i++) {
+ if (r[i] == null) {
+ continue;
+ }
+ if (r[i].Is_null()) {
+ continue;
+ }
+
+ s = r[i].Test();
+
+ if (s != null) {
+ s.index = i;
+ return s;
+ }
+
+ }
+
+ return null;
+
+ }
+
+ /**
+ */
+ public void finalize() throws MPIException {
+ }
+
+ /**
+ * Test if request object is void.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>true if the request object is void, false otherwise
+ * </tr>
+ * </table>
+ */
+ public boolean Is_null() throws MPIException {
+ return isNull;
+ }
+
+ /**
+ * Blocks until all of the operations associated with the active requests in
+ * the array have completed.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>array of status objects
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WAITALL</tt>.
+ * <p>
+ * The result array will be the same size as <tt>array_of_requests</tt>. On
+ * exit, requests become inactive. If the <em>input</em> value of
+ * <tt>arrayOfRequests</tt> contains inactive requests, corresponding elements
+ * of the result array will contain null status references.
+ */
+ public static Status[] Waitall(Request[] r) throws MPIException {
+
+ Status[] s = new Status[r.length];
+
+ for (int i = 0; i < r.length; i++) {
+ if (r[i] != null) {
+
+ s[i] = r[i].Wait();
+ }
+ }
+
+ return s;
+
+ }
+
+ /**
+ * Blocks until one of the operations associated with the active requests in
+ * the array has completed.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>status object
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WAITANY</tt>.
+ * <p>
+ * The index in <tt>array_of_requests</tt> for the request that completed can
+ * be obtained from the returned status object through the
+ * <tt>Status.index</tt> field. The corresponding element of
+ * <tt>array_of_requests</tt> becomes inactive.
+ */
+ public static Status Waitany(Request[] r) throws MPIException {
+
+ /*
+ * mpjdev.Request requests[] = new mpjdev.Request[r.length] ;
+ *
+ * for(int i=0 ; i<r.length ; i++) { if(r[i] != null) { requests[i] =
+ * r[i].req ; } }
+ *
+ * mpjdev.Status completedStatus = mpjdev.Request.iwaitany(requests) ;
+ * Status wrapperCompletedStatus = new Status(completedStatus) ;
+ *
+ * for(int i=0 ; i<r.length ; i++) { if(r[i] != null) { r[i].isNull = true ;
+ * } }
+ *
+ * return wrapperCompletedStatus ;
+ */
+
+ /* Do not need this naive implementation ... */
+ Status s = null;
+
+ // BUG: if all requests are inactive, this method would never return
+ for (int i = 0; i < r.length; i++) {
+
+ if (r[i].Is_null()) {
+ if (i == r.length - 1)
+ i = -1;
+ continue;
+ }
+
+ s = r[i].Test(true);
+
+ if (s != null) {
+ s = r[i].Wait();
+ s.index = i;
+ return s;
+ }
+
+ if (i == r.length - 1)
+ i = -1;
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Tests for completion of <em>all</em> of the operations associated with
+ * active requests.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>array of status objects
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TESTALL</tt>.
+ * <p>
+ * If all operations have completed, the exit value of the argument array and
+ * the result array are as for <tt>Waitall</tt>. If any operation has not
+ * completed, the result value is null and no element of the argument array is
+ * modified.
+ */
+
+ public static Status[] Testall(Request[] r) throws MPIException {
+
+ Status[] s = new Status[r.length];
+
+ for (int i = 0; i < r.length; i++) {
+
+ if (r[i] != null) {
+ s[i] = r[i].Test(true);
+
+ if (s[i] == null) {
+ /*
+ * for( int j=i-1; j>-1 ; j--) { r[j].isNull = false; }
+ */
+ try {
+ Thread.currentThread().sleep(500);
+ }
+ catch (Exception e) {
+ }
+ //
+ return null;
+ }
+
+ }
+ }
+
+ for (int i = 0; i < r.length; i++) {
+ s[i] = r[i].Wait();
+ }
+
+ return s;
+
+ }
+
+ /**
+ * Blocks until at least one of the operations associated with the active
+ * requests in the array has completed.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>array of status objects
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_WAITSOME</tt>.
+ * <p>
+ * The size of the result array will be the number of operations that
+ * completed. The index in <tt>array_of_requests</tt> for each request that
+ * completed can be obtained from the returned status objects through the
+ * <tt>Status.index</tt> field. The corresponding element in
+ * <tt>array_of_requests</tt> becomes inactive.
+ */
+
+ public static Status[] Waitsome(Request[] r) throws MPIException {
+
+ ArrayList<Status> list = new ArrayList<Status>();
+ boolean break_flag = false;
+
+ for (int i = 0; i < r.length; i++) {
+ Status s = null;
+
+ if (r[i].Is_null()) {
+
+ if (break_flag && i == r.length - 1) {
+ break;
+ } else if (i == r.length - 1) {
+ i = -1;
+ }
+
+ continue;
+ }
+
+ s = r[i].Test(true);
+
+ if (s != null) {
+ s = r[i].Wait();
+ s.index = i;
+ list.add(s);
+ break_flag = true;
+ }
+
+ if (break_flag && i == r.length - 1) {
+ break;
+ } else if (i == r.length - 1) {
+ i = -1;
+ }
+
+ }
+
+ return list.toArray(new Status[0]);
+ }
+
+ /**
+ * Behaves like <tt>Waitsome</tt>, except that it returns immediately.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> array_of_requests </tt></td>
+ * <td>array of requests
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>array of status objects
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TESTSOME</tt>.
+ * <p>
+ * If no operation has completed, <tt>TestSome</tt> returns an array of length
+ * zero and elements of <tt>array_of_requests</tt> are unchanged. Otherwise,
+ * arguments and return value are as for <tt>Waitsome</tt>.
+ */
+ public static Status[] Testsome(Request[] r) throws MPIException {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" Testsome ");
+ ArrayList<Status> list = new ArrayList<Status>();
+
+ for (int i = 0; i < r.length; i++) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("i " + i);
+ Status s = null;
+
+ if (r[i].Is_null()) {
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug(" its null, continuing");
+ continue;
+ }
+
+ if (MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("calling test again.");
+ }
+
+ s = r[i].Test();
+
+ if (s != null) {
+ s.index = i;
+ list.add(s);
+ }
+
+ }
+
+ return list.toArray(new Status[0]);
+
+ }
+
+ /**
+ * Mark a pending nonblocking communication for cancellation. Java binding of
+ * the MPI operation <tt>MPI_CANCEL</tt>.
+ */
+ public void Cancel() throws MPIException {
+
+ System.out.println("Request.Cancel(): Not implemented in this release");
+
+ if (this.req.cancel()) {
+ isNull = true;
+ } else {
+ isNull = false;
+ }
+
+ }
+
+}
diff --git a/src/mpi/ShiftParms.java b/src/mpi/ShiftParms.java
new file mode 100755
index 0000000..ec571f1
--- /dev/null
+++ b/src/mpi/ShiftParms.java
@@ -0,0 +1,46 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ShiftParms.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+public class ShiftParms {
+ ShiftParms() {
+ }
+
+ public int rank_source;
+ public int rank_dest;
+}
diff --git a/src/mpi/SimplePacker.java b/src/mpi/SimplePacker.java
new file mode 100644
index 0000000..933e8af
--- /dev/null
+++ b/src/mpi/SimplePacker.java
@@ -0,0 +1,51 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePacker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public abstract class SimplePacker
+ implements Packer {
+
+ protected int numEls;
+
+ public SimplePacker(int numEls) {
+ this.numEls = numEls;
+ }
+}
+
diff --git a/src/mpi/SimplePackerBoolean.java b/src/mpi/SimplePackerBoolean.java
new file mode 100644
index 0000000..af4e0fe
--- /dev/null
+++ b/src/mpi/SimplePackerBoolean.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerBoolean.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerBoolean extends SimplePacker{
+
+ public SimplePackerBoolean(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((boolean []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((boolean []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((boolean []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((boolean []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((boolean []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((boolean []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerByte.java b/src/mpi/SimplePackerByte.java
new file mode 100644
index 0000000..408b21b
--- /dev/null
+++ b/src/mpi/SimplePackerByte.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerByte extends SimplePacker{
+
+ public SimplePackerByte(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((byte []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((byte []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((byte []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((byte []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((byte []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((byte []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerChar.java b/src/mpi/SimplePackerChar.java
new file mode 100644
index 0000000..a6923e3
--- /dev/null
+++ b/src/mpi/SimplePackerChar.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerChar extends SimplePacker{
+
+ public SimplePackerChar(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((char []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((char []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((char []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((char []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((char []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((char []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerDouble.java b/src/mpi/SimplePackerDouble.java
new file mode 100644
index 0000000..3b20333
--- /dev/null
+++ b/src/mpi/SimplePackerDouble.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerDouble extends SimplePacker{
+
+ public SimplePackerDouble(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((double []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((double []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((double []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((double []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((double []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((double []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerFactory.java b/src/mpi/SimplePackerFactory.java
new file mode 100644
index 0000000..86dca5d
--- /dev/null
+++ b/src/mpi/SimplePackerFactory.java
@@ -0,0 +1,93 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerFactory.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/16 21:44:02 $
+ */
+
+package mpi;
+
+public class SimplePackerFactory {
+ public static Packer create(int count, int datatype) {
+
+ switch (datatype) {
+ case Datatype.UNDEFINED:
+ break;
+
+ case Datatype.NULL:
+ break;
+
+ case Datatype.BYTE:
+ return new SimplePackerByte(count);
+
+ case Datatype.CHAR:
+ return new SimplePackerChar(count);
+
+ case Datatype.SHORT:
+ return new SimplePackerShort(count);
+
+ case Datatype.BOOLEAN:
+ return new SimplePackerBoolean(count);
+
+ case Datatype.INT:
+ return new SimplePackerInt(count);
+
+ case Datatype.LONG:
+ return new SimplePackerLong(count);
+
+ case Datatype.FLOAT:
+ return new SimplePackerFloat(count);
+
+ case Datatype.DOUBLE:
+ return new SimplePackerDouble(count);
+
+ case Datatype.PACKED:
+ //return new NullPacker();
+ break ;
+
+ case Datatype.LB:
+ break;
+
+ case Datatype.UB:
+ break;
+
+ case Datatype.OBJECT:
+ return new SimplePackerObject(count);
+
+ default:
+ break;
+ }
+
+ return null;
+ }
+}
diff --git a/src/mpi/SimplePackerFloat.java b/src/mpi/SimplePackerFloat.java
new file mode 100644
index 0000000..97d6296
--- /dev/null
+++ b/src/mpi/SimplePackerFloat.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerFloat extends SimplePacker{
+
+ public SimplePackerFloat(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((float []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((float []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((float []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((float []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((float []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((float []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerInt.java b/src/mpi/SimplePackerInt.java
new file mode 100644
index 0000000..7619b5a
--- /dev/null
+++ b/src/mpi/SimplePackerInt.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerInt extends SimplePacker{
+
+ public SimplePackerInt(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((int []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((int []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((int []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((int []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((int []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((int []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerLong.java b/src/mpi/SimplePackerLong.java
new file mode 100644
index 0000000..74a2f28
--- /dev/null
+++ b/src/mpi/SimplePackerLong.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerLong extends SimplePacker{
+
+ public SimplePackerLong(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((long []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((long []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((long []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((long []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((long []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((long []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerObject.java b/src/mpi/SimplePackerObject.java
new file mode 100644
index 0000000..06a77a1
--- /dev/null
+++ b/src/mpi/SimplePackerObject.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerObject.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerObject extends SimplePacker{
+
+ public SimplePackerObject(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).write((Object []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).read((Object []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).read((Object []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).write((Object []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ ((mpjbuf.Buffer) mpjbuf).read((Object []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ ((mpjbuf.Buffer) mpjbuf).read((Object []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerShort.java b/src/mpi/SimplePackerShort.java
new file mode 100644
index 0000000..c8252d6
--- /dev/null
+++ b/src/mpi/SimplePackerShort.java
@@ -0,0 +1,116 @@
+/* This file generated automatically from template SimplePackerType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePackerShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePackerShort extends SimplePacker{
+
+ public SimplePackerShort(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.write((short []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ mpjbuf.read((short []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ mpjbuf.read((short []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.write((short []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ mpjbuf.read((short []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ mpjbuf.read((short []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/SimplePackerType.java.in b/src/mpi/SimplePackerType.java.in
new file mode 100644
index 0000000..8346cba
--- /dev/null
+++ b/src/mpi/SimplePackerType.java.in
@@ -0,0 +1,115 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SimplePacker at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SimplePacker at Type@ extends SimplePacker{
+
+ public SimplePacker at Type@(int numEls) {
+ super(numEls);
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @WRITEBUF(mpjbuf)@.write((@type@ []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.read((@type@ []) buf, offset, numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.read((@type@ []) buf, offset, length) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ @WRITEBUF(mpjbuf)@.write((@type@ []) buf, offset, count * numEls) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf, int offset,
+ int count) throws MPIException {
+ try {
+ @READBUF(mpjbuf)@.read((@type@ []) buf, offset, count*numEls ) ;
+ }
+ catch(Exception e) {
+ throw new MPIException(e);
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, int length, Object buf,
+ int offset, int count) throws MPIException {
+
+ if(count * numEls < length) {
+ throw new MPIException ("Error in SimplePacker : count <"+
+ (count*numEls)+"> is less than length <"+length+">");
+ }
+
+ try {
+ @READBUF(mpjbuf)@.read((@type@ []) buf, offset, length) ;
+ }catch(Exception e){
+ throw new MPIException(e);
+ }
+ }
+ }
+
diff --git a/src/mpi/Status.java b/src/mpi/Status.java
new file mode 100755
index 0000000..1a9cd5d
--- /dev/null
+++ b/src/mpi/Status.java
@@ -0,0 +1,188 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Status.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.14 $
+ * Updated : $Date: 2005/11/27 19:37:22 $
+ */
+
+package mpi;
+
+import mpjdev.*;
+import mpjbuf.*;
+import java.util.Hashtable;
+
+public class Status
+ extends mpjdev.Status implements Freeable {
+
+ Status(int s, int t, int numEls, int count) {
+ this.source = s;
+ this.tag = t;
+ this.numEls = numEls;
+ this.count = count;
+ }
+
+ public Status(mpjdev.Status s) {
+ this.source = s.source;
+ this.tag = s.tag;
+ this.index = s.index;
+ this.count = s.count;
+ this.numEls = s.numEls;
+ this.type = s.type;
+ this.countInBytes = s.countInBytes ; //needed for mxdev
+ }
+
+ Status(int s, int t, int i) {
+ this.source = s;
+ this.tag = t;
+ this.index = i;
+ }
+
+ /**
+ * Get the number of received entries.
+ * <p>
+ * <table>
+ * <tr><td><tt> datatype </tt></td><td> datatype of each item in receive
+ * buffer </tr>
+ * <tr><td><em> returns: </em></td><td> number of received entries </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GET_COUNT</tt>.
+ */
+ public int Get_count(Datatype datatype) throws MPIException {
+ /*
+ System.out.println(" source "+ source);
+ System.out.println(" tag "+ tag);
+ System.out.println(" index "+ index );
+ System.out.println(" count "+ count );
+ System.out.println(" numEls "+ numEls );
+ System.out.println(" type "+ type );
+ /*
+ * this (if loop) will force MPJ to work for mxdev. If a user calls probe
+ * and then calls this method with the status returned by probe,
+ * there is no way, we can be sure about the datatype of the messages
+ *
+ * If the users have called irecv followed by wait ..then we can
+ * retrieve type and numEls from the buffer. In such a case, this
+ * loop would not get executed ..but we need to make it work in case
+ * this method is called followed by a probe method ...
+ *
+ * The MPI specifications look ambigous to me about this ...it states
+ * the the datatype argument to this method *should* be the same
+ * as the receive methods. There is no way of doing error-checking
+ * to ensure this. We are overdoing this in niodev and are passing
+ * the type of the message as part of the control message ...but
+ * what other MPI implementations do is to divide count (number of
+ * bytes in the message) by the datatype provided to this method ...
+ * if the remainder is non-zero ...return MPI.UNDEFINED .. otherwise
+ * return the result of count/datatype.size ..note that there is no
+ * guarantee that the message is of the datatype specified by the user
+ * as an arg to this method. In MPJ, we actually ensure that this is the
+ * case ...
+ */
+
+ if(type == null) {
+ if(countInBytes % datatype.byteSize == 0) {
+ return countInBytes/datatype.byteSize ;
+ }
+ else {
+ return 0; //MPI.UNDEFINED ..
+ }
+ }
+
+ if (datatype.bufferType.getCode() == type.getCode() ) {
+ return count;
+ }
+ else {
+ System.out.println("This status object doesn't contain any count" +
+ "of this datatype");
+ //maybe throw an exception in this case ...is it really an exception?
+ return 0;
+ }
+
+ }
+
+ /**
+ * Constructor
+ */
+ public Status() {
+ }
+
+ /**
+ * Test if communication was cancelled.
+ * <p>
+ * <table>
+ * <tr><td><em> returns: </em></td><td> true if the operation was
+ * succesfully cancelled,
+ * false otherwise
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_TEST_CANCELLED</tt>.
+ */
+ public boolean Test_cancelled() throws MPIException {
+ System.out.println("Cancel functionality is not implemented.");
+ return false;
+ }
+
+ /**
+ */
+ public void free() {
+ }
+
+ /**
+ * Retrieve number of basic elements from status.
+ * <p>
+ * <table>
+ * <tr><td><tt> datatype </tt></td><td> datatype used by receive
+ * operation </tr>
+ * <tr><td><em> returns: </em></td><td> number of received basic
+ * elements </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GET_ELEMENTS</tt>.
+ */
+ public int Get_elements(Datatype datatype) throws MPIException {
+ if (datatype.bufferType.getCode() == type.getCode() ) {
+ return numEls;
+ }
+ else {
+ System.out.println("This status object doesn't contain any numEls" +
+ "of this datatype");
+ //maybe throw an exception here ...is it really an exception?
+ return 0;
+ }
+ }
+
+}
+
+// Things to do
+// What about derived datatypes ...
diff --git a/src/mpi/Struct.java b/src/mpi/Struct.java
new file mode 100644
index 0000000..329f67a
--- /dev/null
+++ b/src/mpi/Struct.java
@@ -0,0 +1,544 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Struct.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.16 $
+ * Updated : $Date: 2005/08/25 10:22:07 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer;
+
+/**
+ * Subclass of `Datatype' representing a derived datatype created using
+ * `Struct()'.
+ * createWriteBuffer doesn't write the sectionHeader because Struct datatype
+ * may consist of various different datatypes, thus the best place to write
+ * these section headers (and read them as well) are pack() and unpack()
+ * methods in StructPacker class. This behaviour is only exhibited,
+ * (writing various different kind of sections) by Struct datatype.
+ * Thus, it has be dealt here only. This
+ * may not be the best way of doing this, but at the mom. it looks *the best*.
+ */
+public class Struct
+ extends Datatype {
+
+ private int[] blockLengths, displacements;
+ private Datatype[] oldTypes;
+
+ private boolean unitsOfOldExtent;
+ // true => Indexed, false => Hindexed.
+
+ private boolean unitBlocks;
+ // Case where all blocks have unit length is detected and
+ // treated specially.
+
+ private Datatype oldType;
+ private int numBlocks;
+ //int extent = 0;
+
+ /** you want to pack multiple type of non-contigous or contigous elements.
+ */
+ public Struct(int[] array_of_blocklengths, int[] array_of_displacements,
+ Datatype[] array_of_types) throws MPIException {
+
+ numBlocks = array_of_blocklengths.length;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("\n\n--struct--");
+ MPI.logger.debug("numBlocks " + numBlocks);
+ }
+
+ blockLengths = new int[numBlocks];
+ displacements = new int[numBlocks];
+ oldTypes = new Datatype[numBlocks];
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("iterating over numBlocks ");
+ }
+
+ for (int i = 0; i < numBlocks; i++) {
+ blockLengths[i] = array_of_blocklengths[i];
+ displacements[i] = array_of_displacements[i];
+ oldTypes[i] = array_of_types[i];
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("numBlocks[" + i + "] bkln<" + blockLengths[i] +
+ ">,dis<" +displacements[i] +
+ ">,otype<" + oldTypes[i] + ">");
+ }
+ }
+
+ // Compute base type, type size
+ baseType = UNDEFINED;
+ for (int i = 0; i < numBlocks; i++) {
+ Datatype oldType = oldTypes[i];
+ int oldBaseType = oldType.baseType;
+ if (oldBaseType != UNDEFINED) {
+ if (baseType == UNDEFINED) {
+ baseType = oldBaseType;
+ bufferType = oldType.bufferType;
+ }
+ else if (oldBaseType != baseType) {
+ /*MPIException.processMpiJavaException(MPI.ERR_TYPE,
+ "Base types of all component types in a Struct " +
+ "must agree.");*/
+ throw new MPIException(
+ "Base types of all component types in a Struct " +
+ "must agree");
+ }
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("numBlocks[" + i + "] bkln<" + blockLengths[i] +
+ ">,dis<" + displacements[i] + ">,otype<" + oldTypes[i] +
+ ">");
+ }
+ size += blockLengths[i] * oldType.Size();
+ }
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("numBlocks[" + i + "] size<" + size + ">,otype<" +
+ oldTypes[i] + ">");
+ MPI.logger.debug("baseType " + baseType);
+ }
+ }
+
+ computeBounds();
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("bufferType " + bufferType);
+ MPI.logger.debug("after calling computeBounds");
+ MPI.logger.debug("extent " + extent);
+ MPI.logger.debug("lb " + lb);
+ MPI.logger.debug("ub " + ub);
+ MPI.logger.debug("lbSet " + lbSet);
+ MPI.logger.debug("ubSet " + ubSet);
+ MPI.logger.debug(
+ "bufferType for struct hasn't been set, "+
+ " and it won't work like this");
+ }
+ }
+
+ private void computeBounds() throws MPIException {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("--computeBounds--");
+ // Compute `ub' and `lb', which define the `extent' of the new type.
+ // Also defines `ubSet', `lbSet' for this type.
+
+ ubSet = false;
+ lbSet = false;
+ lb = Integer.MAX_VALUE;
+ ub = Integer.MIN_VALUE;
+
+ // Because currently we don't save the true lb (ub) of old types,
+ // following will be an upper bound (lower bound), obtained
+ // from precursor types for which lbSet (ubSet) is false.
+
+ int trueLb = Integer.MAX_VALUE;
+ int trueUb = Integer.MIN_VALUE;
+
+ extent = 0; // Follow MPICH in defining extent to be zero if
+ // bounds are undefined (i.e. empty type).
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("initial values on computeBounds");
+ MPI.logger.debug("extent " + extent);
+ MPI.logger.debug("lb " + lb);
+ MPI.logger.debug("ub " + ub);
+ MPI.logger.debug("lbSet " + lbSet);
+ MPI.logger.debug("ubSet " + ubSet);
+ MPI.logger.debug("trueLb " + trueLb);
+ MPI.logger.debug("trueUb " + trueUb);
+
+ MPI.logger.debug("--iterating over the numBlocks<" + numBlocks);
+ }
+ for (int i = 0; i < numBlocks; i++) {
+ int blockLen = blockLengths[i];
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(" iteration<" + i + ">");
+ MPI.logger.debug(" blklen <" + blockLen + ">");
+ }
+
+ if (blockLen < 0) {
+ /*MPIException.processMpiJavaException(MPI.ERR_COUNT,
+ "All block-lengths for Struct " +
+ "must be non-negative.") ;*/
+ throw new MPIException(
+ "All block-lengths for Struct must be non-negative");
+ }
+
+ if (blockLen > 0) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("if blklen > 0");
+ Datatype oldtype = oldTypes[i];
+ int oldBaseType = oldtype.baseType;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("getting old type" + oldtype);
+ MPI.logger.debug("old base type" + oldBaseType);
+ }
+ int oldSize = oldtype.Size();
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled())
+ MPI.logger.debug("old size " + oldSize);
+ boolean oldUbSet = oldtype.ubSet;
+ boolean oldLbSet = oldtype.lbSet;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("oldubset " + oldUbSet);
+ MPI.logger.debug("oldlbset" + oldLbSet);
+ }
+ if (oldSize != 0 || oldLbSet || oldUbSet) {
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("within oldSize != 0 or oldLbSet or oldUbSet ");
+ }
+ // `oldtype.ub', `oldtype.lb', `oldtype.extent'
+ // all well-defined.
+
+ int oldExtent = oldtype.Extent();
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("oldextent" + oldExtent);
+ }
+
+ int max_ub = displacements[i] + (blockLen - 1) * oldExtent +
+ oldtype.ub;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("max_ub" + max_ub);
+ }
+ if (oldUbSet) {
+ ubSet = true;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("(MPI.uB) max_ub" + max_ub);
+ MPI.logger.debug("(MPI.uB) true" + trueUb);
+ MPI.logger.debug("(MPI.uB) ub" + ub);
+ MPI.logger.debug("(MPI.uB) oldtype.ub" + oldtype.ub);
+ }
+ //aamir -- removed this if condition
+ //if (max_ub > ub)
+ ub = max_ub;
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("(after((MPI.uB) ub" + ub);
+ }
+ }
+ else {
+ if (max_ub > trueUb) {
+ trueUb = max_ub;
+
+ /* aamir (start) */
+ if (max_ub > displacements[i])
+ ub = max_ub; // + oldSize;
+ else
+ ub = displacements[i]; //+oldSize;
+
+ //ub = (max_ub*displacements[i])+oldSize; //aamir + (what is epsolon here ??)
+ //MPI.logger.debug("ub aamir ");
+ /* aamir (end) */
+ }
+ /*
+ else {
+ ub = displacements[i] + oldSize;//aamir
+ }*/
+ }
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("trueUb" + trueUb);
+ }
+ int min_lb = displacements[i] + oldtype.lb;
+ if (oldLbSet) {
+ lbSet = true;
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("(MPI.lB) min_lb" + min_lb);
+ MPI.logger.debug("(MPI.lB) true" + trueLb);
+ MPI.logger.debug("(MPI.lB) lb" + lb);
+ MPI.logger.debug("(MPI.LB) oldtype.lb" + oldtype.lb);
+ }
+
+ //aamir -- removed this if condition
+ //if (min_lb < lb)
+ lb = min_lb;
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug(")after((MPI.UB) lb" + lb);
+ }
+ }
+ else {
+ if (min_lb < trueLb) {
+ trueLb = min_lb;
+
+ /* aamir (start) */
+ if (min_lb < displacements[i])
+ lb = min_lb;
+ else
+ lb = displacements[i];
+
+ //lb = min_lb*displacements[i];
+ //lb = min_lb;
+ /* aamir (end) */
+ }
+ /*
+ else
+ lb = displacements[i];//aamir
+ */
+ }
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("trueLb" + trueLb);
+ }
+ /* Following "correct" according to standard, but likely to
+ cause compatibility problems with MPICH?
+
+ int maxStartElement = startBlock +
+ oldExtent > 0 ? (blockLen - 1) * oldExtent : 0
+
+ // `ubSet' acts like a most significant positive bit in
+ // the maximization operation.
+
+ if (oldUbSet == ubSet) {
+ int max_ub = maxStartElement + oldtype.ub ;
+ if (max_ub > ub)
+ ub = max_ub ;
+ }
+ else if(oldUbSet) {
+ ub = maxStartElement + oldtype.ub ;
+ ubSet = true ;
+ }
+
+ int minStartElement = startBlock +
+ oldExtent > 0 ? 0 : (blockLen - 1) * oldExtent ;
+
+ // `lbSet' acts like a most significant negative bit in
+ // the minimization operation.
+
+ if (oldLbSet == lbSet) {
+ int min_lb = minStartElement + oldtype.lb ;
+ if (min_lb < lb)
+ lb = min_lb ;
+ }
+ else if(oldLbSet) {
+ lb = minStartElement + oldtype.lb ;
+ lbSet = true ;
+ }
+ */
+ }
+ } //end if blkLen > 0
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("lb<" + lb + ">");
+ MPI.logger.debug("ub<" + ub + ">");
+ MPI.logger.debug("trueLb<" + trueLb + ">");
+ MPI.logger.debug("trueUb<" + trueUb + ">");
+ }
+
+ }
+
+ if(MPI.DEBUG && MPI.logger.isDebugEnabled()) {
+ MPI.logger.debug("(e)lb<" + lb + ">");
+ MPI.logger.debug("(e)ub<" + ub + ">");
+ MPI.logger.debug("(e)trueLb<" + trueLb + ">");
+ MPI.logger.debug("(e)trueUb<" + trueUb + ">");
+ }
+ /*
+ if(lb > trueLb) {
+
+ // MPIException.processMpiJavaException(MPI.ERR_TYPE,
+ // "Compatibility restriction: in Struct, lb defined by MPI_LB " +
+ // "may not be higher than \"true\" lb.") ;
+
+ throw new MPIException("Compatibility restriction");
+ }
+
+ if(ub < trueUb) {
+ // MPIException.processMpiJavaException(MPI.ERR_TYPE,
+ // "Compatibility restriction: in Struct, ub defined by MPI_UB " +
+ // "may not be lower than \"true\" ub.") ;
+ // throw new MPIException("Compatibility restriction");
+ }
+ */
+
+ if (lb != Integer.MAX_VALUE || ub != Integer.MIN_VALUE)
+ extent = ub - lb;
+ }
+
+ mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer, int messageSize) {
+ return new mpjbuf.Buffer( new NIOBuffer(messageSize, slicedBuffer),
+ MPI.BSEND_OVERHEAD , messageSize ) ;
+ }
+
+ mpjbuf.Buffer createWriteBuffer(int count) throws MPIException {
+ int capacity = packedSize(count) +MPI.SEND_OVERHEAD ;
+ int offset = MPI.SEND_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer(rawBuffer, offset, capacity);
+
+ try {
+ wBuffer.putSectionHeader(this.bufferType);
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+
+ return wBuffer;
+ }
+
+ mpjbuf.Buffer createReadBuffer(int count) {
+ int capacity = packedSize(count)+ MPI.RECV_OVERHEAD ;
+ int offset = MPI.RECV_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create (capacity);
+ mpjbuf.Buffer mpjbuf = new mpjbuf.Buffer( rawBuffer , offset, capacity) ;
+ return mpjbuf;
+ }
+
+ int packedSize(int count) {
+ /* calculate the size of each block, add them */
+ int sectionHeader = 8; //what about multiple sections.
+
+ for (int i = 0; i < blockLengths.length; i++) {
+ int blockLen = blockLengths[i];
+ Datatype oldtype = oldTypes[i];
+ int sectionSize = 0;
+ sectionSize = (blockLen * oldtype.byteSize);
+ // int padding = 0;
+ // if (sectionSize % 8 != 0)
+ // padding = sectionSize % 8;
+ // sectionSize += padding;
+ byteSize += sectionSize;
+ }
+
+ /* calculate the size of each block, add them */
+ return ((byteSize * count)+sectionHeader) ;
+ }
+
+ void setPacker() {
+ packer = new StructPacker();
+ }
+
+ private class StructPacker
+ extends GenericPacker {
+
+ StructPacker() {
+ super(Struct.this.extent, Struct.this.size); //what is size ?
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ int numBlocks = displacements.length;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int boffset = offset + displacements[i];
+ int blockLen = blockLengths[i];
+ Datatype oldtype = oldTypes[i];
+ Packer itemPacker = oldtype.getPacker();
+ int itemExtent = oldtype.extent;
+ for (int j = 0; j < blockLen; j++) {
+ itemPacker.pack(mpjbuf, buf, boffset);
+ boffset += itemExtent;
+ }
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ int numBlocks = displacements.length;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int boffset = offset + displacements[i];
+ int blockLen = blockLengths[i];
+ Datatype oldtype = oldTypes[i];
+
+ Packer itemPacker = oldtype.getPacker();
+ int itemExtent = oldtype.extent;
+
+ for (int j = 0; j < blockLen; j++) {
+ itemPacker.unpack(mpjbuf, buf, boffset, itemExtent);
+ boffset += itemExtent;
+ }
+
+ if (oldtype.bufferType == null)
+ System.out.println("bufferType is null in createWriteBuffer");
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int numBlocks = displacements.length;
+ int residue = length;
+ int boffset = 0;
+ Datatype oldtype = null;
+ //Packer itemPacker;
+
+
+ for (int i = 0; i < numBlocks; i++) {
+ boffset = offset + displacements[i];
+ int blockLen = blockLengths[i];
+ oldtype = oldTypes[i];
+
+ int blockSize = blockLen * oldtype.size;
+
+ if (residue < blockSize)break;
+
+ Packer itemPacker = oldtype.getPacker(); //just to avoid errors
+ int itemLen = oldtype.extent;
+
+ for (int j = 0; j < blockLen; j++) {
+ itemPacker.unpack(mpjbuf, buf, boffset);
+ boffset += itemLen;
+ }
+
+ residue -= blockSize;
+ }
+
+ // Precondition is `length < size'.
+ // So `size > 0'. So `numBlocks > 0'.
+ // So `boffset', `oldtype' always defined on exit from above loop.
+
+ int remFull = residue / oldtype.size;
+ for (int j = 0; j < remFull; j++) {
+ //is this itemPacker good enough here ?
+
+ Packer itemPacker = oldtype.getPacker(); //just to avoid errors
+ int itemLen = oldtype.extent;
+ itemPacker.unpack(mpjbuf, buf, boffset);
+ boffset += itemLen;
+ }
+
+ residue -= remFull * oldtype.size;
+ Packer itemPacker = oldtype.getPacker(); //jsut to avoid errors
+ if (residue > 0)
+ itemPacker.unpackPartial(mpjbuf, residue, buf, boffset);
+ }
+ }
+
+}
+
+// Things to do:
+//
+
diff --git a/src/mpi/Sum.java b/src/mpi/Sum.java
new file mode 100644
index 0000000..98a4afc
--- /dev/null
+++ b/src/mpi/Sum.java
@@ -0,0 +1,48 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Sum.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class Sum extends Op {
+
+ Sum() {
+ worker = new SumWorker();
+ this.opCode = mpjdev.Constants.SUM_CODE;
+ }
+}
diff --git a/src/mpi/SumByte.java b/src/mpi/SumByte.java
new file mode 100644
index 0000000..a1c2e68
--- /dev/null
+++ b/src/mpi/SumByte.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumByte.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumByte extends Sum {
+ byte [] arr = null;
+
+ SumByte() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ byte[] arr1 = (byte[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (byte) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ arr = new byte[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ byte[] tempArray = (byte[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumChar.java b/src/mpi/SumChar.java
new file mode 100644
index 0000000..9acb296
--- /dev/null
+++ b/src/mpi/SumChar.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumChar.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumChar extends Sum {
+ char [] arr = null;
+
+ SumChar() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ char[] arr1 = (char[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (char) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ char[] tempArray = (char[]) buf;
+ arr = new char[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ char[] tempArray = (char[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumDouble.java b/src/mpi/SumDouble.java
new file mode 100644
index 0000000..328039d
--- /dev/null
+++ b/src/mpi/SumDouble.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumDouble.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumDouble extends Sum {
+ double [] arr = null;
+
+ SumDouble() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ double[] arr1 = (double[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (double) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ double[] tempArray = (double[]) buf;
+ arr = new double[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ double[] tempArray = (double[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumFloat.java b/src/mpi/SumFloat.java
new file mode 100644
index 0000000..b5d73cf
--- /dev/null
+++ b/src/mpi/SumFloat.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumFloat.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumFloat extends Sum {
+ float [] arr = null;
+
+ SumFloat() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ float[] arr1 = (float[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (float) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ float[] tempArray = (float[]) buf;
+ arr = new float[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ float[] tempArray = (float[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumInt.java b/src/mpi/SumInt.java
new file mode 100644
index 0000000..48e5fa4
--- /dev/null
+++ b/src/mpi/SumInt.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumInt.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumInt extends Sum {
+ int [] arr = null;
+
+ SumInt() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ int[] arr1 = (int[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (int) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ int[] tempArray = (int[]) buf;
+ arr = new int[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ int[] tempArray = (int[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumLong.java b/src/mpi/SumLong.java
new file mode 100644
index 0000000..431957b
--- /dev/null
+++ b/src/mpi/SumLong.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumLong.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumLong extends Sum {
+ long [] arr = null;
+
+ SumLong() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ long[] arr1 = (long[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (long) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ long[] tempArray = (long[]) buf;
+ arr = new long[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ long[] tempArray = (long[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumShort.java b/src/mpi/SumShort.java
new file mode 100644
index 0000000..3298a6f
--- /dev/null
+++ b/src/mpi/SumShort.java
@@ -0,0 +1,69 @@
+/* This file generated automatically from template SumType.java.in. */
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumShort.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class SumShort extends Sum {
+ short [] arr = null;
+
+ SumShort() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ short[] arr1 = (short[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (short) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ short[] tempArray = (short[]) buf;
+ arr = new short[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ short[] tempArray = (short[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumType.java.in b/src/mpi/SumType.java.in
new file mode 100644
index 0000000..9f7d233
--- /dev/null
+++ b/src/mpi/SumType.java.in
@@ -0,0 +1,68 @@
+ /*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Sum at Type@.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/01 22:31:40 $
+ */
+
+ package mpi;
+
+ import mpjbuf.*;
+
+ public class Sum at Type@ extends Sum {
+ @type@ [] arr = null;
+
+ Sum at Type@() {
+ }
+
+ void perform(Object buf1, int offset, int count) throws MPIException {
+ @type@[] arr1 = (@type@[]) buf1;
+
+ for (int i = 0+offset; i < count; i++) {
+ arr[i] = (@type@) (arr1[i] + arr[i]);
+ }
+ }
+
+ void createInitialBuffer(Object buf, int offset, int count)
+ throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ arr = new @type@[tempArray.length];
+ System.arraycopy(buf, offset, arr, offset, count) ;
+ }
+
+ void getResultant(Object buf, int offset, int count ) throws MPIException {
+ @type@[] tempArray = (@type@[]) buf;
+ System.arraycopy(arr, offset, tempArray, offset, count);
+ }
+
+ }
diff --git a/src/mpi/SumWorker.java b/src/mpi/SumWorker.java
new file mode 100644
index 0000000..7da95a2
--- /dev/null
+++ b/src/mpi/SumWorker.java
@@ -0,0 +1,78 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : SumWorker.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+
+public class SumWorker
+ implements OpWorker {
+ SumWorker() {
+ }
+
+ public Op getWorker(Datatype datatype) throws MPIException {
+
+ switch (datatype.baseType) {
+ case Datatype.BYTE:
+ return new SumByte();
+
+ case Datatype.CHAR:
+ return new SumChar();
+
+ case Datatype.SHORT:
+ return new SumShort();
+
+ case Datatype.BOOLEAN:
+ throw new MPIException("MPI.SUM is invalid for MPI.BOOLEAN");
+
+ case Datatype.INT:
+ return new SumInt();
+
+ case Datatype.LONG:
+ return new SumLong();
+
+ case Datatype.FLOAT:
+ return new SumFloat();
+
+ case Datatype.DOUBLE:
+ return new SumDouble();
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/mpi/User_function.java b/src/mpi/User_function.java
new file mode 100755
index 0000000..331ad19
--- /dev/null
+++ b/src/mpi/User_function.java
@@ -0,0 +1,64 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : User_function.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpi;
+
+public abstract class User_function {
+ /**
+ * User-defined function for a new <tt>Op</tt>.
+ * <p>
+ * <table>
+ * <tr><td><tt> invec </tt></td><td> array of values to combine with
+ * <tt>inoutvec</tt> elements </tr>
+ * <tr><td><tt> inoffset </tt></td><td> initial offset in
+ * <tt>invec<tt> </tr>
+ * <tr><td><tt> inoutvec </tt></td><td> in-out array of accumulator
+ * locations </tr>
+ * <tr><td><tt> inoutoffset </tt></td><td> initial offset in
+ * <tt>inoutvec<tt> </tr>
+ * <tr><td><tt> count </tt></td><td> number of items in arrays </tr>
+ * <tr><td><tt> datatype </tt></td><td> type of each item </tr>
+ * </table>
+ * <p>
+ * Java equivalent of the MPI <tt>USER_FUNCTION</tt>.
+ */
+ public abstract void Call(Object invec, int inoffset,
+ Object inoutvec, int inoutoffset,
+ int count, Datatype datatype) throws MPIException ;
+}
+
diff --git a/src/mpi/Vector.java b/src/mpi/Vector.java
new file mode 100644
index 0000000..aa51f87
--- /dev/null
+++ b/src/mpi/Vector.java
@@ -0,0 +1,338 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Vector.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Sep 10 12:22:15 BST 2004
+ * Revision : $Revision: 1.15 $
+ * Updated : $Date: 2005/08/12 19:12:08 $
+ */
+
+package mpi;
+
+import mpjbuf.*;
+import java.nio.ByteBuffer ;
+
+/**
+ * Subclass of `Datatype' representing a derived datatype created using
+ * `Vector()' or `Hvector()'.
+ */
+public class Vector
+ extends Datatype {
+
+ private int count, blockLength, stride;
+ private boolean unitsOfOldExtent;
+ // true => Vector, false => Hvector.
+ private Datatype oldType;
+ private int realStride;
+
+ /*
+ * count == total number of elements that you wish to transfer
+ * blockLength == blockLength ..like one row
+ * may've 10 elemtns you want to send just a row.
+ * stride == jump ...skip these number of elements
+ * oldtype
+ * boolean, true or false.
+ */
+ public Vector(int count, int blockLength, int stride, Datatype oldType,
+ boolean unitsOfOldExtent) throws MPIException {
+
+
+ if (count < 0) {
+ throw new MPIException(
+ "count argument of Vector or Hvector must be non-negative");
+ }
+
+ if (blockLength < 0) {
+ throw new MPIException(
+ "Block-length argument of Vector or Hvector must be non-negative");
+ }
+
+ bufferType = oldType.bufferType;
+ this.oldType = oldType;
+ this.count = count;
+ this.blockLength = blockLength;
+ this.stride = stride;
+
+ int oldExtent = oldType.extent;
+ realStride = stride;
+
+ if (unitsOfOldExtent) realStride *= oldExtent;
+
+ baseType = oldType.baseType;
+ int oldSize = oldType.Size();
+ int repetitions = count * blockLength;
+ size = repetitions * oldSize;
+ byteSize = repetitions * oldType.byteSize;
+
+ computeBounds(oldSize, repetitions);
+ }
+
+ private void computeBounds(int oldSize, int repetitions) {
+
+ // Compute `ub' and `lb', which define the `extent' of the new type.
+ // Also defines `ubSet', `lbSet' for this type.
+
+ ubSet = repetitions > 0 && oldType.ubSet; //was oldtype.
+ lbSet = repetitions > 0 && oldType.lbSet; //was oldtype.
+
+ // Compute ub and lb, which define the extent of the new type.
+
+ lb = Integer.MAX_VALUE;
+ ub = Integer.MIN_VALUE;
+ extent = 0; // Follow MPICH in defining extent to be zero if
+ // bounds are undefined (i.e. empty type).
+
+ if (oldSize != 0 || oldType.lbSet || oldType.ubSet) {
+
+ // `oldType.ub', `oldType.lb', `oldType.extent' all well-defined.
+
+ if (count > 0 && blockLength > 0) { //was blockSize => blockLength (aamir)
+
+ // Assume all extents are non-negative.
+
+ int oldExtent = oldType.extent;
+
+ if (realStride > 0) {
+ ub = realStride * (count - 1) + (blockLength - 1) * oldExtent +
+ oldType.ub;
+ lb = oldType.lb;
+ }
+ else {
+ ub = (blockLength - 1) * oldExtent + oldType.ub;
+ lb = realStride * (count - 1) + oldType.lb;
+ }
+
+ extent = ub - lb;
+ }
+
+ /* Following "correct" according to standard, but likely to
+ cause compatibility problems with MPICH?
+ for (int i = 0 ; i < count ; i++) {
+
+ int startBlock = realStride * i ;
+
+ if(oldExtent > 0) {
+ int max_ub = startBlock + (blocklength - 1) * oldExtent +
+ oldType.ub ;
+ if (max_ub > ub)
+ ub = max_ub ;
+
+ int min_lb = startBlock + oldType.lb ;
+ if (min_lb < lb)
+ lb = min_lb ;
+ }
+ else {
+ int max_ub = startBlock + oldType.ub ;
+ if (max_ub > ub)
+ ub = max_ub ;
+
+ int min_lb = startBlock + (blocklength - 1) * oldExtent +
+ oldType.lb ;
+ if (min_lb < lb)
+ lb = min_lb ;
+ }
+ }
+
+ extent = ub - lb ;
+ */
+ }
+ }
+
+ mpjbuf.Buffer createWriteBuffer(int count) throws MPIException {
+ int capacity = packedSize(count) + MPI.SEND_OVERHEAD ;
+ int offset = MPI.SEND_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer(rawBuffer, offset, capacity) ;
+
+ try {
+ wBuffer.putSectionHeader(this.bufferType); // need conversion
+ }
+ catch (Exception e) {
+ throw new MPIException(e);
+ }
+ return wBuffer;
+ }
+
+ mpjbuf.Buffer createWriteBuffer(ByteBuffer slicedBuffer, int messageSize) {
+ return new mpjbuf.Buffer(new NIOBuffer(messageSize, slicedBuffer),
+ MPI.BSEND_OVERHEAD , messageSize );
+ }
+
+ mpjbuf.Buffer createReadBuffer(int count) {
+ int capacity = packedSize(count) + MPI.RECV_OVERHEAD ;
+ int offset = MPI.RECV_OVERHEAD ;
+ mpjbuf.RawBuffer rawBuffer = BufferFactory.create(capacity);
+ mpjbuf.Buffer mpjbuf = new mpjbuf.Buffer(rawBuffer, offset, capacity);
+ return mpjbuf;
+ }
+
+ int packedSize(int count) {
+ int dataSize = count * byteSize;
+ int totalSize = 0;
+ int sectionHeader = 8; //what about multiple sections.
+ totalSize = sectionHeader + dataSize;
+ int padding = 0;
+
+ if (totalSize % 8 != 0)
+ padding = totalSize % 8;
+
+ return totalSize + padding;
+ }
+
+ void setPacker() {
+
+ Packer oldPacker = oldType.getPacker();
+
+ if (oldPacker instanceof SimplePacker) {
+
+ int oldCount = ( (SimplePacker) oldPacker).numEls;
+ int newCount = blockLength * oldCount;
+ int[] indexes = {
+ newCount, count, 1, realStride};
+ packer = MultistridedPackerFactory.create(2, indexes, extent, size,
+ baseType);
+ }
+ else if (oldPacker instanceof MultistridedPacker) {
+ MultistridedPacker multiOldPacker = (MultistridedPacker) oldPacker;
+
+ int oldRank = multiOldPacker.rank;
+ int[] oldIndexes = multiOldPacker.indexes;
+
+ int rank;
+ int[] indexes;
+ if (blockLength == 1) {
+ rank = oldRank + 1;
+ indexes = new int[2 * rank]; //it was int[] indexes (aamir)
+ for (int i = 0; i < oldRank; i++)
+ indexes[i] = oldIndexes[i];
+ indexes[oldRank] = count;
+ for (int i = 0; i < oldRank; i++)
+ indexes[rank + i] = oldIndexes[oldRank + i];
+ indexes[rank + oldRank] = realStride;
+ }
+ else {
+ rank = oldRank + 2;
+ indexes = new int[2 * rank]; //it was int[] indexes
+ for (int i = 0; i < oldRank; i++)
+ indexes[i] = oldIndexes[i];
+ indexes[oldRank] = blockLength;
+ indexes[oldRank + 1] = count;
+ for (int i = 0; i < oldRank; i++)
+ indexes[rank + i] = oldIndexes[oldRank + i];
+ indexes[rank + oldRank] = oldType.extent;
+ indexes[rank + oldRank + 1] = realStride;
+ }
+
+ packer = MultistridedPackerFactory.create(rank, indexes,
+ extent, size,
+ baseType);
+ }
+ else {
+ packer = new VectorPacker();
+ }
+ }
+
+ private class VectorPacker
+ extends GenericPacker {
+
+ Packer itemPacker;
+ int itemExtent;
+ int itemSize;
+
+ VectorPacker() {
+ super(Vector.this.extent, Vector.this.size);
+ itemPacker = oldType.getPacker();
+ this.itemExtent = oldType.extent;
+ this.itemSize = oldType.size ;
+ }
+
+ public void pack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ for (int i = 0; i < count; i++) {
+ int boffset = offset;
+ for (int j = 0; j < blockLength; j++) {
+ itemPacker.pack(mpjbuf, buf, boffset);
+ boffset += itemExtent;
+ }
+ offset += realStride;
+ }
+ }
+
+ public void unpack(mpjbuf.Buffer mpjbuf, Object buf,
+ int offset) throws MPIException {
+
+ for (int i = 0; i < count; i++) {
+ int boffset = offset;
+ for (int j = 0; j < blockLength; j++) {
+ itemPacker.unpack(mpjbuf, buf, boffset);
+ boffset += itemExtent;
+ }
+ offset += realStride;
+ }
+ }
+
+ public void unpackPartial(mpjbuf.Buffer mpjbuf, int length,
+ Object buf, int offset) throws MPIException {
+
+ int numFull = length / itemSize;
+ int numBlocks = numFull / blockLength;
+
+ for (int i = 0; i < numBlocks; i++) {
+ int boffset = offset;
+ for (int j = 0; j < blockLength; j++) {
+ itemPacker.unpack(mpjbuf, buf, boffset);
+ boffset += itemExtent;
+ }
+ offset += realStride;
+ }
+
+ int remFull = numFull - numBlocks * blockLength;
+
+ for (int j = 0; j < remFull; j++) {
+ itemPacker.unpack(mpjbuf, buf, offset);
+ offset += itemExtent;
+ }
+
+ int residue = length - numFull * itemSize;
+
+ if (residue > 0)
+ itemPacker.unpackPartial(mpjbuf, residue, buf, offset);
+
+ }
+ }
+
+}
+
+// Things to do:
+//
+
diff --git a/src/mpi/clean.pl b/src/mpi/clean.pl
new file mode 100644
index 0000000..7da22cc
--- /dev/null
+++ b/src/mpi/clean.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+# File : generate.pl
+# Author : Bryan Carpenter
+# Created : Thu Jul 15 10:44:32 BST 2004
+# Revision : $Revision: 1.3 $
+# Updated : $Date: 2005/08/16 21:44:02 $
+
+ # Numeric types
+
+ @ntypes = ('byte', 'short', 'int', 'long', 'char', 'float', 'double') ;
+ @nTypes = ('Byte', 'Short', 'Int', 'Long', 'Char', 'Float', 'Double') ;
+
+
+ # Primitive types
+
+ @ptypes = (@ntypes, 'boolean') ;
+ @pTypes = (@nTypes, 'Boolean') ;
+
+
+ # General types
+
+ @types = (@ptypes, 'Object') ;
+ @Types = (@pTypes, 'Object') ;
+
+
+ # Root names for classes generated by simple templates over primitive types
+
+ @proots = () ;
+
+
+ # Root names for classes generated by simple templates over general types
+ # groots = ('SimplePacker', 'MultistridedPacker', 'GatherPacker') ;
+ @groots = ('SimplePacker', 'MultistridedPacker', 'GatherPacker',
+ 'Band', 'Max', 'Bor', 'Minloc', 'Bxor', 'Min', 'Land', 'Lor',
+ 'Prod', 'Lxor', 'Maxloc', 'Sum') ;
+
+
+ foreach $root (@proots) {
+
+ for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $Type = $pTypes [$i] ;
+
+ unlink "${root}${Type}.java" ;
+ }
+
+ }
+
+
+ foreach $root (@groots) {
+
+ $template = "${root}Type.java.in" ;
+
+ for ($i = 0 ; $i < @types ; $i++) {
+
+ $Type = $Types [$i] ;
+
+ unlink "${root}${Type}.java" ;
+ }
+
+ }
+
diff --git a/src/mpi/generate.pl b/src/mpi/generate.pl
new file mode 100644
index 0000000..2a956af
--- /dev/null
+++ b/src/mpi/generate.pl
@@ -0,0 +1,170 @@
+#!/usr/bin/perl
+
+# File : generate.pl
+# Author : Bryan Carpenter
+# Created : Thu Jul 15 10:44:32 BST 2004
+# Revision : $Revision: 1.4 $
+# Updated : $Date: 2005/08/16 21:44:02 $
+
+ #logical types
+
+
+ # Numeric types
+ @ntypes = ('byte', 'short', 'int', 'long', 'char', 'float', 'double') ;
+ @nTypes = ('Byte', 'Short', 'Int', 'Long', 'Char', 'Float', 'Double') ;
+ @nTYPES = ('BYTE', 'SHORT', 'INT', 'LONG', 'CHAR', 'FLOAT', 'DOUBLE') ;
+
+ # Logical types ..only boolean ..and even boolean is represented
+ @ltypes = ('boolean');
+ @lTypes = ('Boolean');
+ @lTYPES = ('BOOLEAN');
+
+ # in Java bit-wise operations cannot be applied to double and float ...
+ @btypes = ('byte', 'short', 'int', 'long', 'char');
+ @bTypes = ('Byte', 'Short', 'Int', 'Long', 'Char');
+ @bTYPES = ('BYTE', 'SHORT', 'INT', 'LONG', 'CHAR');
+
+ # another category for minloc and maxloc operations ...
+ @mtypes = ('short', 'int', 'long', 'float', 'double');
+ @mTypes = ('Short', 'Int', 'Long', 'Float', 'Double');
+ @mTYPES = ('SHORT', 'INT', 'LONG', 'FLOAT', 'DOUBLE');
+
+ @smallest = ('Byte.MIN_VALUE', 'Short.MIN_VALUE', 'Integer.MIN_VALUE',
+ 'Long.MIN_VALUE', 'Character.MIN_VALUE',
+ 'Float.NEGATIVE_INFINITY', 'Double.NEGATIVE_INFINITY') ;
+
+ @largest = ('Byte.MAX_VALUE', 'Short.MAX_VALUE', 'Integer.MAX_VALUE',
+ 'Long.MAX_VALUE', 'Character.MAX_VALUE',
+ 'Float.POSITIVE_INFINITY', 'Double.POSITIVE_INFINITY') ;
+
+
+ # Primitive types
+
+ @ptypes = (@ntypes, 'boolean') ;
+ @pTypes = (@nTypes, 'Boolean') ;
+ @pTYPES = (@nTYPES, 'BOOLEAN') ;
+
+
+ # General types
+
+ @types = (@ptypes, 'Object') ;
+ @Types = (@pTypes, 'Object') ;
+ @TYPES = (@pTYPES, 'OBJECT') ;
+
+
+ # Root names for classes generated by simple templates over primitive types
+
+ #@mroots = ('Minloc','Maxloc') ;
+
+ @lroots = ('Land', 'Lor', 'Lxor') ;
+
+ @nroots = ('Max','Min','Sum','Prod');
+
+ @broots = ('Bxor','Bor','Band');
+
+ # Root names for classes generated by simple templates over general types
+
+ @groots = ('SimplePacker', 'MultistridedPacker', 'GatherPacker');
+
+ #foreach $root (@mroots) {
+ # $template = "${root}Type.java.in" ;
+ # for ($i = 0 ; $i < @mtypes ; $i++) {
+ # $type = $mtypes [$i] ;
+ # $Type = $mTypes [$i] ;
+ # $TYPE = $mTYPES [$i] ;
+ # makeSimple("${root}${Type}", $type, $Type, $TYPE, 'false',
+ # $template) ;
+ #}
+ #}
+
+ foreach $root (@lroots) {
+ $template = "${root}Type.java.in" ;
+ for ($i = 0 ; $i < @ltypes ; $i++) {
+ $type = $ltypes [$i] ;
+ $Type = $lTypes [$i] ;
+ $TYPE = $lTYPES [$i] ;
+ makeSimple("${root}${Type}", $type, $Type, $TYPE, 'false',
+ $template) ;
+ }
+ }
+
+ foreach $root (@broots) {
+ $template = "${root}Type.java.in" ;
+ for ($i = 0 ; $i < @btypes ; $i++) {
+ $type = $btypes [$i] ;
+ $Type = $bTypes [$i] ;
+ $TYPE = $bTYPES [$i] ;
+ makeSimple("${root}${Type}", $type, $Type, $TYPE, 'false',
+ $template) ;
+ }
+ }
+
+ foreach $root (@nroots) {
+ $template = "${root}Type.java.in" ;
+ for ($i = 0 ; $i < @ntypes ; $i++) {
+ $type = $ntypes [$i] ;
+ $Type = $nTypes [$i] ;
+ $TYPE = $nTYPES [$i] ;
+ makeSimple("${root}${Type}", $type, $Type, $TYPE, 'false',
+ $template) ;
+ }
+ }
+
+ foreach $root (@groots) {
+
+ $template = "${root}Type.java.in" ;
+
+ for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $Type = $pTypes [$i] ;
+ $TYPE = $pTYPES [$i] ;
+
+ makeSimple("${root}${Type}", $type, $Type, $TYPE, 'false',
+ $template) ;
+ }
+
+ makeSimple("${root}Object", 'Object', 'Object', 'OBJECT', 'true',
+ $template) ;
+ }
+
+
+ sub makeSimple {
+
+ local $name = $_[0] ;
+ local $type = $_[1] ;
+ local $Type = $_[2] ;
+ local $TYPE = $_[3] ;
+ local $isObject = $_[4] ;
+ local $template = $_[5] ;
+
+ local $target = "${name}.java" ;
+
+ open(TEMPLATE, $template) or die "Can't open $template: $!\n" ;
+ open(TARGET, ">$target") or die "Can't create $target: $!\n" ;
+
+ print TARGET "/* This file generated automatically ",
+ "from template $template. */\n" ;
+
+ while($line = <TEMPLATE>) {
+ $line =~ s/\@type\@/${type}/g ;
+ $line =~ s/\@Type\@/${Type}/g ;
+ $line =~ s/\@TYPE\@/${TYPE}/g ;
+ $line =~ s/\@isObject\@/${isObject}/g ;
+ if($isObject eq 'true') {
+ $line =~
+ s/\@READBUF\(([^\)]*)\)\@/((mpjbuf.Buffer) $1)/g ;
+ $line =~
+ s/\@WRITEBUF\(([^\)]*)\)\@/((mpjbuf.Buffer) $1)/g ;
+ }
+ else {
+ $line =~ s/\@READBUF\(([^\)]*)\)\@/$1/g ;
+ $line =~ s/\@WRITEBUF\(([^\)]*)\)\@/$1/g ;
+ }
+ print TARGET $line ;
+ }
+
+ close TARGET ;
+ close TEMPLATE ;
+ }
+
diff --git a/src/mpjbuf/Buddy1Buffer.java b/src/mpjbuf/Buddy1Buffer.java
new file mode 100644
index 0000000..e112f42
--- /dev/null
+++ b/src/mpjbuf/Buddy1Buffer.java
@@ -0,0 +1,45 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy1Buffer.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/08/12 19:12:25 $
+ *
+ */
+package mpjbuf ;
+
+import java.nio.ByteBuffer ;
+
+public class Buddy1Buffer extends mpjbuf.NIOBuffer {
+ int position ;
+ Buddy1RegionFreeList list ;
+
+
+ Buddy1Buffer () {
+ }
+
+ Buddy1Buffer(ByteBuffer slicedBuffer, int capacity,
+ Buddy1RegionFreeList list, int realOffset) {
+
+ super (capacity, slicedBuffer) ;
+ this.list = list ;
+ this.position = realOffset ;
+ }
+
+}
diff --git a/src/mpjbuf/Buddy1BufferFactory.java b/src/mpjbuf/Buddy1BufferFactory.java
new file mode 100644
index 0000000..5ee405e
--- /dev/null
+++ b/src/mpjbuf/Buddy1BufferFactory.java
@@ -0,0 +1,317 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy1BufferFactory.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.13 $
+ * Updated : $Date: 2006/04/25 19:26:14 $
+ *
+ */
+package mpjbuf ;
+
+import java.util.ArrayList ;
+import java.nio.ByteBuffer ;
+import java.io.FileOutputStream ;
+import java.io.PrintStream ;
+import java.io.File ;
+import org.apache.log4j.Logger ;
+
+public class Buddy1BufferFactory extends BufferFactory {
+ static Logger logger = Logger.getLogger ( "mpj" );
+
+ //static final boolean DEBUG = false;
+
+ private ArrayList<Buddy1FreeList> freeLists =
+ new ArrayList<Buddy1FreeList>() ;
+
+ public synchronized void init(){
+ //initialize the factory here ..
+ //create buffer creates the first region anyway ...!
+ }
+
+ public synchronized mpjbuf.RawBuffer createBuffer(int size) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("\n\n createBuffer "+size);
+
+ if(size == 0) {
+ //do something weird.
+ return null; // *** (But less weird than this !!!) ***
+ } else {
+ //+1 is the extra bit required by clever buddy ...
+ int numChunks = (size + 1 + BufferConstants.CHUNK_SIZE - 1) /
+ BufferConstants.CHUNK_SIZE;
+ int level = CustomMath.widthInBits(numChunks - 1);
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("required level "+level );
+
+ Buddy1RegionFreeList list ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("finding the right level ");
+ find : {
+
+ int numLevels = freeLists.size() ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("freeList.size() "+freeLists.size()) ;
+
+ for (int l = level ; l < numLevels ; l++) {
+
+ list = freeLists.get(l).getFront() ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("list @level <"+l+">="+list);
+ if(list != null) break find ;
+ }
+
+ // If we got here, we need to allocate a new region.
+ // Current policy is:
+ //
+ // newNumLevels =
+ // max(INIT_NUM_LEVELS, numLevels + 1, level + 1)
+
+ int newNumLevels = BufferConstants.INIT_NUM_LEVELS ;
+ if(numLevels + 1 > newNumLevels)
+ newNumLevels = numLevels + 1;
+ if(level + 1 > newNumLevels)
+ newNumLevels = level + 1;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("allocating a new region ");
+ list = initializeRegion(newNumLevels) ;
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("calling allocate ...");
+ return allocate(level, list) ;
+ }
+ }
+
+
+ public synchronized void destroyBuffer(mpjbuf.RawBuffer buffer) {
+ free((Buddy1Buffer) buffer) ;
+ }
+
+
+ /**
+ * Allocate a block of specified level from a non-empty free list
+ * with the same or higher level.
+ *
+ * If list level is higher than required, excess memory is returned
+ * to the appropriate lower free lists.
+ *
+ * @param level the level of the required block
+ * @param non-empty list
+ * @return allocate buffer
+ */
+ private Buddy1Buffer allocate(int level, Buddy1RegionFreeList list) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("--allocate--");
+ int position = list.front ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" level :"+level );
+ logger.debug(" list :"+list);
+ }
+
+ list.removeFront() ;
+
+ while(list.level > level) {
+ list = list.down ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("position "+position) ;
+ logger.debug("list.blockSize "+list.blockSize );
+ logger.debug("Adding buddy @ "+ (position ^ list.blockSize)) ;
+ }
+ list.memory.position(position ^ list.blockSize) ;
+ list.memory.put( (byte) list.level );
+ list.add(position ^ list.blockSize) ; // Add buddy to list
+ }
+
+ int cap = BufferConstants.CHUNK_SIZE << level ;
+ list.memory.position( position) ;
+ list.memory.put( BufferConstants.ALLOCATED );
+
+ list.memory.position( position+1 );
+ list.memory.limit ( cap+position);
+ ByteBuffer slicedBuffer = list.memory.slice() ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("slicedBuffer "+slicedBuffer );
+ logger.debug(" cap "+cap);
+ logger.debug("list "+list);
+ logger.debug("list.memory "+list.memory );
+ logger.debug("position "+position );
+ }
+ //.debug("(malloc) position "+ position );
+ return new Buddy1Buffer(slicedBuffer , cap , list , position ) ;
+ }
+
+ /**
+ * Free a buffer.
+ *
+ * Recursively aggregate block with free buddies where possible,
+ * returning aggregated block free list of appropriate level.
+ *
+ * @param buffer the buffer to free.
+ */
+ private void free(Buddy1Buffer buffer) {
+ if(buffer.list.front == buffer.position) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug("This can't happen, but returning ...");
+ return;
+ }
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("\n--free--");
+ logger.debug("buffer.list.front "+buffer.list.front) ;
+ }
+ Buddy1RegionFreeList list = buffer.list ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" list.level "+list.level);
+ }
+ int position = buffer.position ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" position "+ position ) ;
+ //.debug("(free) position "+ position );
+ }
+
+ ByteBuffer memory = buffer.list.memory ;
+ memory.clear() ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" memory (for region) "+ memory ) ;
+ }
+
+ while(list.up != null) { // Not top-level list of region
+
+ int buddy = position ^ list.blockSize ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" buddy "+ buddy ) ;
+ }
+ memory.position( buddy ) ;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" memory "+ memory ) ;
+ }
+
+ if(memory.get() != list.level ) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled())
+ logger.debug(" buddy is not FREE ");
+ break ;
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" buddy is free ...removing it ..");
+ }
+
+ list.remove(buddy) ;
+
+ if(position > buddy) {
+ position = buddy ;
+ }
+
+ list = list.up ;
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" adding the buffer at pos <"+position);
+ logger.debug("size of htis buffer is "+list.blockSize );
+ }
+
+ // problematic bits .. .. ..
+ list.add(position) ;
+ memory.position( position );
+ memory.put( (byte) list.level );
+
+ }
+
+ public synchronized void finalixe() {
+ //do something!
+ }
+
+ //int numberOfRegions = 0 ;
+
+ /**
+ * Initialize a new region.
+ *
+ * New memory is allocated, and free list nodes are initialized as
+ * required.
+ *
+ * @param numLevels the number of levels in the new region.
+ * @return reference to top-level local free list, initially containing
+ * all memory associated with region.
+ */
+ private Buddy1RegionFreeList initializeRegion(int numLevels) {
+
+ //System.out.println(" regions="+(++numberOfRegions) ) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--initializeRegion--") ;
+ }
+
+ int size = BufferConstants.CHUNK_SIZE << (numLevels - 1) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("size "+size ) ;
+ }
+
+ ByteBuffer memory = ByteBuffer.allocateDirect ( size );
+
+ // Create local free lists for all levels.
+
+ Buddy1RegionFreeList [] lists = new Buddy1RegionFreeList [numLevels] ;
+
+ int oldNumLevels = freeLists.size() ;
+ int blockSize = BufferConstants.CHUNK_SIZE ;
+
+ for(int l = 0 ; l < numLevels ; l++) {
+
+ Buddy1FreeList freeList ;
+
+ // Extend global free list table as necessary.
+
+ if(l < oldNumLevels)
+ freeList = freeLists.get(l) ;
+ else {
+ freeList = new Buddy1FreeList() ;
+ freeLists.add(freeList) ;
+ }
+
+ lists [l] = new Buddy1RegionFreeList(l, blockSize,
+ memory, freeList) ;
+ blockSize = blockSize << 1 ;
+ }
+
+ // Initialize `down' and `up' pointers connecting local free lists,
+ // for use in `allocate()' and `free()' methods.
+
+ for(int l = 0 ; l < numLevels ; l++) {
+
+ Buddy1RegionFreeList list = lists [l] ;
+
+ if(l > 0)
+ list.down = lists [l - 1] ;
+
+ if(l + 1 < numLevels)
+ list.up = lists [l + 1] ;
+ }
+
+ // Add whole of memory to top level local free list.
+
+ Buddy1RegionFreeList top = lists [numLevels - 1] ;
+
+ top.add(0) ;
+
+ return top ;
+ }
+}
diff --git a/src/mpjbuf/Buddy1FreeList.java b/src/mpjbuf/Buddy1FreeList.java
new file mode 100644
index 0000000..dc116f8
--- /dev/null
+++ b/src/mpjbuf/Buddy1FreeList.java
@@ -0,0 +1,69 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy1FreeList.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.2 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+package mpjbuf ;
+
+/**
+ * `FreeList' is implemented as a concatenated set of sublists, each
+ * of type `RegionFreeList'.
+ */
+
+public class Buddy1FreeList {
+ Buddy1RegionFreeList front ;
+
+ Buddy1RegionFreeList getFront() {
+ return front ;
+ }
+
+ /**
+ * Add new sublist to front of free list.
+ */
+ void add(Buddy1RegionFreeList sublist) {
+ if(front != null)
+ front.prevList = sublist ;
+
+ sublist.prevList = null ;
+ sublist.nextList = front ;
+ front = sublist ;
+ }
+
+ /**
+ * Remove sublist from any position in free list.
+ */
+ void remove(Buddy1RegionFreeList sublist) {
+ Buddy1RegionFreeList prev = sublist.prevList ;
+ Buddy1RegionFreeList next = sublist.nextList ;
+
+ if(prev == null)
+ front = next ;
+ else
+ prev.nextList = next ;
+
+ if(next != null)
+ next.prevList = prev ;
+ }
+}
+
+
+
diff --git a/src/mpjbuf/Buddy1RegionFreeList.java b/src/mpjbuf/Buddy1RegionFreeList.java
new file mode 100644
index 0000000..aaace5f
--- /dev/null
+++ b/src/mpjbuf/Buddy1RegionFreeList.java
@@ -0,0 +1,126 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy1RegionFreeList.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+package mpjbuf ;
+
+import java.nio.ByteBuffer ;
+
+/**
+ * Local free list associated with a particular region.
+ */
+public class Buddy1RegionFreeList {
+
+
+ // Whole of memory associated with region.
+ ByteBuffer memory ;
+
+ // The global free list this local list is associated with.
+ Buddy1FreeList globalFreeList ;
+
+ // Forward and backward pointers in global free list.
+ Buddy1RegionFreeList prevList, nextList ;
+ //up and down below are same ??? aamir :-)
+
+ int front ;
+ // Extra fields used by the buddy algorithm:
+ int level, blockSize ;
+
+ Buddy1RegionFreeList up, down ;
+
+ /**
+ * Empty local free list for a particular region.
+ *
+ * This free list (when non-empty) will become a local sublist of
+ * `globalFreeList'.
+ */
+ Buddy1RegionFreeList(int level, int blockSize, ByteBuffer memory,
+ Buddy1FreeList globalFreeList) {
+ this.level = level ;
+ this.blockSize = blockSize ;
+
+ this.memory = memory ;
+ this.globalFreeList = globalFreeList ;
+
+ front = BufferConstants.NULL ;
+ }
+
+ void add(int position) {
+ if (front == BufferConstants.NULL) { // Local free list empty
+ memory.position( position + BufferConstants.NEXT ) ;
+ memory.putInt(BufferConstants.NULL);
+ memory.position( position + BufferConstants.PREV ) ;
+ memory.putInt(BufferConstants.NULL);
+ front = position ;
+ globalFreeList.add(this) ; // Add to global free list
+ }
+
+ else {
+ memory.position( position + BufferConstants.NEXT );
+ memory.putInt( front ) ;
+ memory.position( position + BufferConstants.PREV );
+ memory.putInt( BufferConstants.NULL ) ;
+ memory.position( front + BufferConstants.PREV );
+ memory.putInt( position ) ;
+ front = position ;
+ }
+ }
+
+ void remove(int position) {
+ memory.position ( position + BufferConstants.PREV );
+ int prev = memory.getInt() ;
+ memory.position ( position + BufferConstants.NEXT );
+ int next = memory.getInt() ;
+
+ if (prev == BufferConstants.NULL)
+ front = next ;
+ else {
+ memory.position( prev + BufferConstants.NEXT );
+ memory.putInt( next );
+ }
+
+ if (next != BufferConstants.NULL) {
+ memory.position( next + BufferConstants.PREV );
+ memory.putInt( prev );
+ }
+
+ if (front == BufferConstants.NULL) { // Local free list now empty
+ globalFreeList.remove(this) ; // Remove from global free list
+ }
+ }
+
+ void removeFront() {
+ memory.clear() ;
+ memory.position(front + BufferConstants.NEXT );
+ front = memory.getInt() ;
+
+ if (front == BufferConstants.NULL) { // Local free list now empty
+ globalFreeList.remove(this) ; // Remove from global free list
+ }
+ else {
+ memory.position( front + BufferConstants.PREV );
+ memory.putInt( BufferConstants.NULL );
+ }
+ }
+
+}
diff --git a/src/mpjbuf/Buddy2Buffer.java b/src/mpjbuf/Buddy2Buffer.java
new file mode 100644
index 0000000..133cd32
--- /dev/null
+++ b/src/mpjbuf/Buddy2Buffer.java
@@ -0,0 +1,56 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy2Buffer.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.4 $
+ * Updated : $Date: 2005/08/12 19:12:25 $
+ *
+ */
+package mpjbuf ;
+
+import java.nio.ByteBuffer ;
+
+public class Buddy2Buffer extends mpjbuf.NIOBuffer {
+
+ Buddy2Buffer () {
+ }
+
+ public Buddy2Buffer(ByteBuffer slicedBuffer, int bufoffset, int capacity,
+ int level, Buddy2Region region, int realOffset ) {
+
+ super(capacity, slicedBuffer) ;
+ this.free = true;
+ this.level = level;
+ this.region = region ;
+ this.realOffset = realOffset ;
+ this.capacity = capacity ;
+
+ }
+
+ public int level, realOffset;
+
+ int capacity ; //there is a capacity in Buffer class but with private access
+
+ public boolean free ;
+
+ public Buddy2Region region;
+
+ Buddy2Buffer next, prev ;
+
+}
diff --git a/src/mpjbuf/Buddy2BufferFactory.java b/src/mpjbuf/Buddy2BufferFactory.java
new file mode 100644
index 0000000..563bca1
--- /dev/null
+++ b/src/mpjbuf/Buddy2BufferFactory.java
@@ -0,0 +1,588 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy2BufferFactory.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/09/11 00:14:35 $
+ *
+ */
+package mpjbuf ;
+
+import java.util.ArrayList;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.File;
+import org.apache.log4j.Logger ;
+
+public class Buddy2BufferFactory extends BufferFactory {
+ //static final boolean DEBUG = false;
+
+ private ArrayList<Buddy2Region> regionLists =
+ new ArrayList<Buddy2Region>();
+ static Logger logger = Logger.getLogger ( "mpj");
+
+
+ public synchronized void init() {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("creating region of size "+
+ BufferConstants.DEFAULT_REGION_SIZE );
+ }
+ Buddy2Region region = new Buddy2Region (
+ BufferConstants.DEFAULT_REGION_SIZE);
+ regionLists.add( region );
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Filling regionLists"+regionLists );
+ logger.debug("init completes ");
+ }
+
+ }
+
+ public synchronized void finalixe() {
+
+ mpjbuf.Buddy2Buffer current = null ;
+
+ for(Buddy2Region reg : regionLists) {
+
+ int numLevels = reg.freeLists.size() ;
+
+ for(int l=0 ; l<numLevels ; l++) {
+
+ Buddy2FreeList fList = reg.freeLists.get(l);
+
+ if(!fList.isEmpty()) {
+
+ current = (mpjbuf.Buddy2Buffer) fList.head ;
+
+ do {
+ current.free() ;
+ current = (mpjbuf.Buddy2Buffer) current.prev;
+ } while(current != (mpjbuf.Buddy2Buffer) fList.head);
+
+ }
+
+ fList = null ;
+
+ }
+
+ reg.buffer = null ;
+
+ reg = null;
+
+ }
+
+ regionLists = null ;
+ }
+
+/**
+ * Return a free buffer of level greater than or equal to `level'.
+ */
+ mpjbuf.Buddy2Buffer findInAllRegions (int level) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--findInAllRegions--");
+ }
+ mpjbuf.Buddy2Buffer freeBuffer = null ;
+ foundIt:
+ for(Buddy2Region reg : regionLists) {
+
+ int numLevels = reg.freeLists.size() ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" reg<"+reg+"> has "+numLevels+" levels");
+ }
+
+ if(level < numLevels) {
+ for (int l = level ; l < numLevels ; l++) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" searching for a buffer at level "+l);
+ }
+
+ Buddy2FreeList freeList = reg.freeLists.get(l) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" got list "+freeList);
+ }
+
+ if(!freeList.isEmpty()) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" got list "+freeList);
+ }
+
+ if(freeList.head == null) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" freeList.head is null ");
+ }
+ continue;
+ }
+ else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" freeList.head is not null ");
+ }
+ mpjbuf.Buddy2Buffer current =
+ (mpjbuf.Buddy2Buffer) freeList.head;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" head "+current);
+ logger.debug(" current "+current);
+ logger.debug(" tail " + (mpjbuf.Buddy2Buffer) freeList.tail );
+ }
+
+ do {
+ if(current.free) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" current is free ");
+ }
+ freeBuffer = current;
+ break foundIt;
+ } else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" current is not free ");
+ }
+ }
+ current = (mpjbuf.Buddy2Buffer) current.prev;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" next current "+current);
+ }
+ } while(current != (mpjbuf.Buddy2Buffer) freeList.head);
+
+ }//end else.
+ }//end if.
+ else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" list is empty ");
+ }
+ }
+ }//end for.
+ }//end if.
+ }//end for iterating the regions ..
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--findInAllRegions ends--");
+ }
+ return freeBuffer ;
+ }
+
+ mpjbuf.Buddy2Buffer find(Buddy2Region inRegion, int level ) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--find--");
+ }
+ mpjbuf.Buddy2Buffer freeBuffer = null ;
+
+ int numLevels = inRegion.freeLists.size() ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("inRegion <"+inRegion+"> has "+numLevels+" levels");
+ }
+
+ if(level < numLevels) {
+ foundIt:
+ for (int l = level ; l < numLevels ; l++) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" searching for a buffer at level "+l);
+ }
+ Buddy2FreeList freeList = inRegion.freeLists.get(l) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" got list "+freeList);
+ }
+
+ if(!freeList.isEmpty()) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" got list "+freeList);
+ }
+ if(freeList.head == null) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" freeList.head is null ");
+ }
+ continue;
+ }
+ else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" freeList.head is not null ");
+ }
+ mpjbuf.Buddy2Buffer current =
+ (mpjbuf.Buddy2Buffer) freeList.head;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" current "+current);
+ }
+
+ do {
+ if(current.free) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" current is free ");
+ }
+ freeBuffer = current;
+ break foundIt;
+ } else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" current is not free ");
+ }
+ }
+ current = (mpjbuf.Buddy2Buffer) current.prev;
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" next current "+(mpjbuf.Buddy2Buffer) current);
+ }
+ } while(current !=
+ (mpjbuf.Buddy2Buffer) freeList.tail);
+ }//end else.
+ }//end if.
+ else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" list is empty ");
+ }
+ }
+ }//end for.
+ }//end if.
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--find ends--");
+ }
+ return freeBuffer ;
+ }
+
+ public synchronized mpjbuf.RawBuffer createBuffer (int size) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--createBuffer--"+size);
+ }
+ if(size == 0) {
+
+ //do something weird.
+ return null;
+
+ } else {
+
+ int numChunks = (size+BufferConstants.CHUNK_SIZE-1)
+ /BufferConstants.CHUNK_SIZE;
+ int level = CustomMath.widthInBits( numChunks-1 );
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Required level "+level);
+ }
+
+ mpjbuf.Buddy2Buffer freeNode = findInAllRegions(level);
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("findInAllRegions returned freeNode "+freeNode );
+ }
+
+ if(freeNode == null) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("creating newRegion");
+ }
+ int newRegionSize = -1;
+
+ if(size > BufferConstants.DEFAULT_REGION_SIZE) {
+ for(int h=2 ; ; h=h*2) {
+ if( size < BufferConstants.DEFAULT_REGION_SIZE * h) {
+ newRegionSize = BufferConstants.DEFAULT_REGION_SIZE * h ;
+ break;
+ }
+ }
+
+ } else {
+ newRegionSize = BufferConstants.DEFAULT_REGION_SIZE;
+ }
+
+ Buddy2Region reg = new Buddy2Region( newRegionSize );
+ regionLists.add( reg );
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Filling regionLists"+regionLists );
+ logger.debug(" we just finished creating a new region ...");
+ }
+
+ freeNode = find(reg, level);
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" freeNode "+freeNode );
+ logger.debug("the level of freeNode is "+freeNode.level );
+ }
+
+ mpjbuf.Buddy2Buffer output = block(freeNode ,freeNode.region , level) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("block returned "+output);
+ logger.debug("at level "+output.level);
+ logger.debug("output.realOffset "+output.realOffset );
+ logger.debug("output.free (false?) "+output.free );
+ logger.debug("--createBuffer ends --");
+ }
+
+ return output;
+
+ }
+ }
+
+ /**
+ * return a buffer of level 'level' from freeBuffer and return
+ * remainder of freeBuffer (if any) to the freeList
+ */
+ private mpjbuf.Buddy2Buffer block(mpjbuf.Buddy2Buffer freeBuffer,
+ Buddy2Region region, int level) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--block--");
+ }
+
+ int l = freeBuffer.level;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" level of the buffer found is <"+l+">");
+ }
+
+ mpjbuf.Buddy2Buffer buddy = null;
+
+ /* luckily we found a freeBuffer that is at the level we wanted */
+ if(level == l) {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("luckily the level we were looking for");
+ }
+
+ freeBuffer.free = false;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--block ends--");
+ }
+
+ return freeBuffer;
+ } else {
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("removing the buffer at level <"+l+">");
+ }
+
+ region.freeLists.get(l).remove(freeBuffer);
+
+ for( l=l-1 ; l>=level ; l-- ) {
+ int childCap = freeBuffer.capacity/2;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("childCap "+childCap);
+ logger.debug("realOffset "+freeBuffer.realOffset);
+ }
+
+ region.buffer.position( freeBuffer.realOffset );
+ region.buffer.limit( freeBuffer.realOffset +childCap);
+ freeBuffer = new mpjbuf.Buddy2Buffer(region.buffer.slice(),
+ 0 , childCap, l, region ,
+ freeBuffer.realOffset );
+ region.buffer.position( freeBuffer.realOffset +childCap );
+ region.buffer.limit( freeBuffer.realOffset +(2*childCap) );
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buddy real offset "+
+ (freeBuffer.realOffset +childCap) );
+ logger.debug("buddy limit "+ (freeBuffer.realOffset+2*childCap) );
+ }
+
+ buddy = new mpjbuf.Buddy2Buffer (region.buffer.slice(),
+ 0 , childCap, l, region ,
+ (freeBuffer.realOffset +childCap) );
+ region.buffer.clear(); //dodgy ...
+ region.freeLists.get(l).add(buddy);
+
+ if(l == level) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Adding freeBuf to freeLists at level <"+l+">");
+ }
+
+ region.freeLists.get(l).add(freeBuffer);
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Adding buddy to freeLists at level <"+l+">");
+ }
+
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" setting free as false ... ");
+ }
+
+ freeBuffer.free = false;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--block ends--");
+ }
+
+ return freeBuffer;
+ }
+ }
+
+ private mpjbuf.Buddy2Buffer calculateBuddy(
+ mpjbuf.Buddy2Buffer buffer) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--calculateBuddy--" + buffer.region );
+ logger.debug("calculating buddy at level "+buffer.level);
+ }
+
+ Buddy2FreeList fList = buffer.region.freeLists.get(buffer.level);
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("fList.size "+fList.size );
+ logger.debug("buffer.realOffset "+buffer.realOffset);
+ logger.debug("buffer.region.regionSize "+ buffer.region.regionSize );
+ logger.debug("blockSize"+(BufferConstants.CHUNK_SIZE << buffer.level));
+ }
+
+ int buddyOffset = buffer.realOffset ^
+ (BufferConstants.CHUNK_SIZE << buffer.level) ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buddyRealOffset (offset looking for) "+buddyOffset );
+ logger.debug("tihs buffers realOffset "+buffer.realOffset );
+ }
+
+ mpjbuf.Buddy2Buffer current= (mpjbuf.Buddy2Buffer) fList.head ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("current "+current);
+ }
+
+ mpjbuf.Buddy2Buffer buddy = null;
+
+ do {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("current.realOffset "+current.realOffset );
+ }
+
+ if(current.realOffset == buddyOffset) {
+ if(current.free) {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" found buddy and its free "+current);
+ }
+
+ buddy = current;
+ break;
+ } else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" found buddy but its not free ");
+ }
+
+ //this means we've found the buddy, but its not free ..so there's
+ //not much we can do except set buffer.free = true and exit ..
+ break;
+ }
+ } else {
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" no buddy in this iteratoin at least ");
+ }
+
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("current(1) "+current);
+ }
+
+ current = (mpjbuf.Buddy2Buffer) current.prev;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("current "+current);
+ logger.debug("fList.head "+ (mpjbuf.Buddy2Buffer) fList.head );
+ }
+
+ } while(current != (mpjbuf.Buddy2Buffer) fList.head );
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--calculateBuddy ends--");
+ }
+
+ return buddy;
+ }
+
+ public synchronized void destroyBuffer (mpjbuf.RawBuffer buffer ) {
+ mpjbuf.Buddy2Buffer buf = (mpjbuf.Buddy2Buffer) buffer ;
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--destroyBuffer--" + buf);
+ }
+
+ mpjbuf.Buddy2Buffer buddy = calculateBuddy( buf);
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("called calculateBuddy"+buf+"the firstTime "+buddy);
+ }
+
+ if(buddy == null) {
+ buf.free = true;
+ try {
+ ((NIOBuffer)buf).clear() ;
+ }catch(Exception e) {
+ e.printStackTrace() ;
+ }
+ return;
+ }
+
+ int numLevels = buf.region.freeLists.size();
+ int level = buf.level ;
+ Buddy2FreeList fList, topLevelList ;
+
+ while (buddy != null) {
+ fList = buf.region.freeLists.get(level);
+
+ if(buf.region.freeLists.size() == (level+1) ) {
+ topLevelList = new Buddy2FreeList();
+ buf.region.freeLists.add(topLevelList);
+ } else {
+ topLevelList = buf.region.freeLists.get(level+1);
+ }
+
+ int parentOffset = -1;
+
+ if(buddy.realOffset > buf.realOffset ) {
+ parentOffset = buf.realOffset ;
+ } else {
+ parentOffset = buddy.realOffset ;
+ }
+
+ int parentbufoffset = 0 ;
+
+ try {
+ ((NIOBuffer)buf).clear() ;
+ buf.free = false ;
+ ((NIOBuffer)buddy).clear() ;
+ buddy.free = false ;
+ }catch(Exception e) {
+ e.printStackTrace() ;
+ }
+
+ fList.remove(buddy); //we know buddy is free ...
+ fList.remove(buf);
+ buf.region.buffer.position( parentOffset);
+ buf.region.buffer.limit(parentOffset+(buf.capacity*2) );
+ buf = new mpjbuf.Buddy2Buffer (buf.region.buffer.slice() ,
+ parentbufoffset, buf.capacity*2, (level+1) ,
+ buf.region, parentOffset );
+ topLevelList.add(buf);
+ buf.region.buffer.clear() ;
+ buddy = calculateBuddy(buf);
+ level++;
+
+ }
+
+ if(mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--destroyBuffer ends --");
+ }
+
+ }
+
+}
diff --git a/src/mpjbuf/Buddy2FreeList.java b/src/mpjbuf/Buddy2FreeList.java
new file mode 100644
index 0000000..52b3d64
--- /dev/null
+++ b/src/mpjbuf/Buddy2FreeList.java
@@ -0,0 +1,96 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy2FreeList.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.2 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+package mpjbuf ;
+
+import java.util.ArrayList;
+
+
+ /* Buddy2FreeList has no memory associated withit i mean when no args
+ * constructor is called ..it still is like an entry in the freelist
+ * but there is no associated memory or anything like that ...how
+ * does that work?
+ */
+public class Buddy2FreeList { //extends Buddy2FreeListNode
+
+ Buddy2Buffer head, tail;
+ int size = 0;
+
+ Buddy2FreeList() {
+ //next = this;
+ head = null;
+ //prev = this;
+ tail = null;
+ size = 0;
+ }
+
+ boolean isEmpty() {
+ //return (next == this);
+ return (head == null && tail == null);
+ }
+
+ void add(Buddy2Buffer node) {
+ if(head == null && tail == null) {
+ this.head = node;
+ this.tail = node;
+ node.next = node;
+ node.prev = node;
+ } else {
+ head.next.prev = node;
+ node.next = head.next;
+ head.next = node;
+ node.prev = head;
+ tail = node;
+ }
+ size++;
+ }
+
+ void remove(Buddy2Buffer node) {
+ if(head == tail) {
+ head = null;
+ tail = null;
+ } else if(head == node) {
+ head.prev.next = head.next;
+ head.next.prev = head.prev;
+ head = head.prev;
+ } else if(tail == node) {
+ tail.prev.next = tail.next;
+ tail.next.prev = tail.prev;
+ tail = tail.next;
+ } else {
+ node.prev.next = node.next;
+ node.next.prev = node.prev;
+ }
+ size--;
+ }
+
+ Buddy2Buffer front() {
+ return head;
+ }
+
+ Buddy2Buffer rear() {
+ return tail;
+ }
+
+}
diff --git a/src/mpjbuf/Buddy2Region.java b/src/mpjbuf/Buddy2Region.java
new file mode 100644
index 0000000..643897c
--- /dev/null
+++ b/src/mpjbuf/Buddy2Region.java
@@ -0,0 +1,67 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : Buddy2Region.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/11/27 19:40:12 $
+ *
+ */
+package mpjbuf ;
+
+import java.util.ArrayList;
+import java.nio.ByteBuffer ;
+
+public class Buddy2Region {
+
+ int regionSize = -1;
+ ArrayList<Buddy2FreeList> freeLists =
+ new ArrayList<Buddy2FreeList>();
+ ByteBuffer buffer = null;
+
+ Buddy2Region(int size) {
+
+ this.buffer = ByteBuffer.allocateDirect (size);
+ this.regionSize = size ;
+ int numChunks = (this.regionSize + BufferConstants.CHUNK_SIZE -1)
+ /BufferConstants.CHUNK_SIZE ;
+ int level = CustomMath.widthInBits( numChunks-1);
+ //System.out.println("initial buffer is at level "+level);
+ Buddy2FreeList fList ;
+
+ for(int i=0 ; i<level ; i++) {
+ fList = new Buddy2FreeList();
+ freeLists.add(fList);
+ //System.out.println("Filling level "+i+" with empty List "+fList);
+ }
+
+ int bufoffset = 0;
+ int realOffset = 0;
+ int capacity = this.regionSize ;
+ // FreeListNode node = new FreeListNode( this.buffer, bufoffset, capacity,
+// level, this, realOffset );
+ mpjbuf.Buddy2Buffer bufferNode = new mpjbuf.Buddy2Buffer( this.buffer,
+ bufoffset, capacity , level, this, realOffset );
+ fList = new Buddy2FreeList();
+ fList.add( bufferNode );
+ //System.out.println("Filling level "+level+" with List "+fList);
+ freeLists.add(fList);
+
+ }
+
+}
diff --git a/src/mpjbuf/Buffer.java b/src/mpjbuf/Buffer.java
new file mode 100644
index 0000000..eff52fe
--- /dev/null
+++ b/src/mpjbuf/Buffer.java
@@ -0,0 +1,5480 @@
+/* This file generated automatically from template Buffer.java.in. */
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+
+import java.io.IOException;
+
+import java.nio.ByteOrder ;
+import java.nio.ByteBuffer ;
+
+/**
+ * A buffer object, for holding an mpjdev message.
+ * <p>
+ * Through appropriate use of <i>sections</i>, described below,
+ * a single buffer object can contain a mixture of elements of any Java type.
+ * A single buffer object can be reused both for sending and receiving
+ * messages, although at any given time a buffer is either in
+ * a <i>readable</i> state or a <i>writeable</i> state.
+ * A buffer is created with a fixed <i>static capacity</i> which does
+ * not change during the lifetime of the buffer. However a
+ * buffer can also (under user control) store data in a dynamically
+ * allocated region---this is necessary in particular to support
+ * serialized objects. A characteristic feature of the
+ * {@link mpjbuf.Buffer mpjbuf.Buffer}
+ * is that is supports transfer of data from and to non-contiguous
+ * sections of a Java array through various gather and scatter methods.
+ *
+ * <h3>Sections</h3>
+ * A message is considered to consist of zero or more "sections".
+ * Each section holds a sequence of elements which
+ * are either all of the same primitive type, or all have Object type.
+ * When a buffer is in writeable mode,
+ * a new section is started by invoking
+ * {@link #putSectionHeader(Type) putSectionHeader()}
+ * to mark the start of the section. This is followed by a series
+ * {@link #write(byte[],int,int) write()},
+ * {@link #gather(byte[],int,int,int[]) gather()}, and/or
+ * {@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operations to write the data to the section. When a buffer is
+ * in readable mode, one starts reading a section by invoking
+ * {@link #getSectionHeader() getSectionHeader()}
+ * to determine the type of elements in the next section,
+ * and to make it the current section.
+ * This is followed by a series
+ * {@link #read(byte[],int,int) read()},
+ * {@link #scatter(byte[],int,int,int[]) scatter()}, and/or
+ * {@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operations to read the data from the section. Buffers may
+ * only be written and read sequentially, from beginning to end.
+ * <p>
+ * In general a buffer object comprises two regions: a <i>primary</i> or
+ * <i>static</i> buffer, and a <i>secondary</i> or <i>dynamic</i> buffer.
+ * The static buffer has a fixed capacity, specified when the buffer is
+ * created. The size of the dynamic buffer grows automatically as new
+ * data is written to it. Any section can be created as a <i>static
+ * section</i> or a <i>dynamic section</i>, and this controls which region
+ * of the buffer the section data is stored in.
+ * It is important to note that in general writing to or reading
+ * from a static section is <i>much</i> faster than the corresponding
+ * operation on a dynamic section. Dynamic sections are required to
+ * support storing serialized objects in the buffer. As a convenience
+ * to the programmer, dynamic sections holding primitive types
+ * are also supported. But in general use of the dynamic buffer is
+ * is only recommended for short or infrequent message exchanges.
+ *
+ * <h3>Physical layout of buffer</h3>
+ * Numeric data in the static buffer can be represented in big-endian
+ * or little-endian format. This is determined by the <tt>encoding</tt>
+ * property of the buffer, which takes on of the values
+ * <tt>java.nio.ByteOrder.BIG_ENDIAN</tt> or
+ * <tt>java.nio.ByteOrder.LITTLE_ENDIAN</tt>. The <tt>encoding</tt> property
+ * of a newly created buffer is determined by the return value of
+ * <tt>java.nio.ByteOrder.nativeOrder()</tt>.
+ * <p>
+ * The overall layout of the static buffer is illustrated in the following
+ * figure:
+ * <p>
+ * <img src="../../images/mpj-static.png"/>
+ * <p>
+ * In practise many messages will contain only a single section.
+ * There are up to 7 bytes of padding after each section
+ * to ensure that the next section header begins on a boundary that is a
+ * multiple of {@link #ALIGNMENT_UNIT ALIGNMENT_UNIT}, which has value 8.
+ * <p>
+ * The general layout of an individual section in the static buffer
+ * is illustrated in the following figure:
+ * <p>
+ * <img src="../../images/mpj-section.png"/>
+ * <p>
+ * The first byte of the section header defines the type of the section,
+ * encoding one of the possible values
+ * {@link Type#BYTE BYTE},
+ * {@link Type#CHAR CHAR},
+ * {@link Type#SHORT SHORT},
+ * {@link Type#BOOLEAN BOOLEAN},
+ * {@link Type#INT INT},
+ * {@link Type#LONG LONG},
+ * {@link Type#FLOAT FLOAT}, or
+ * {@link Type#DOUBLE DOUBLE}, if the section is static, or one of
+ * {@link Type#OBJECT OBJECT},
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC} if the section is dynamic.
+ * The second 4 bytes of the header holds the number of elements
+ * in the section. This numeric value is represented according to the
+ * <tt>encoding</tt> property of the buffer. The size of the header
+ * in bytes is {@link #SECTION_OVERHEAD SECTION_OVERHEAD}, which has value 8.
+ * If the section is static, the header is followed by the values of
+ * the elements, again represented according to the
+ * <tt>encoding</tt> property of the buffer. If the section is dynamic,
+ * the "Section data" is absent from the diagram above (because the
+ * data is in the dynamic buffer).
+ * <p>
+ * The format of the <i>dynamic buffer</i>
+ * is entirely determined by the standard Java serialization classes
+ * <tt>java.io.ObjectOutputStream</tt> and <tt>java.io.ObjectInputStream</tt>.
+ * <p>
+ * <h3>Read and write operations</h3>
+ * There are 3 basic kinds of operation for writing data to a buffer
+ * section, and 3 basic kinds of operation for reading data from a buffer
+ * section. The simplest data transfer operations are
+ * {@link #write(byte[],int,int) write()} and
+ * {@link #read(byte[],int,int) read()},
+ * which transfer contiguous sections of a Java
+ * array. The generic forms are respectively:
+ <pre><code>
+ <b>write</b>(<i>type</i>[] source,
+ int srcOff,
+ int numEls)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>read</b>(<i>type</i>[] dest,
+ int dstOff,
+ int numEls)
+ </code></pre>
+ * The {@link #write(byte[],int,int) write()}
+ * operation copies the values of elements:
+ <pre><code>
+ source [srcOff], source [srcOff + 1], ..., source [srcOff + numEls - 1]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely the {@link #read(byte[],int,int) read()},
+ * operation reads <tt>numEls</tt> values from the buffer and writes
+ * them to the elements:
+ <pre><code>
+ dest [dstOff], dest [dstOff + 1], ..., dest [dstOff + numEls - 1]
+ </code></pre>
+ * <p>
+ * The operations {@link #gather(byte[],int,int,int[]) gather()} and
+ * {@link #scatter(byte[],int,int,int[]) scatter()} transfer
+ * data from or to a subset of elements of a Java array, selected by
+ * giving an index vector. The generic forms are respectively:
+ <pre><code>
+ <b>gather</b>(<i>type</i>[] source,
+ int numEls,
+ int idxOff,
+ int[] indexes)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>scatter</b>(<i>type</i>[] dest,
+ int numEls,
+ int idxOff,
+ int[] indexes)
+ </code></pre>
+ * The {@link #gather(byte[],int,int,int[]) gather()}
+ * operation copies the values of elements:
+ <pre><code>
+ source [indexes [idxOff]], source [indexes [idxOff + 1]], ..., source [indexes [idxOff + numEls - 1]]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely the {@link #scatter(byte[],int,int,int[]) scatter()}
+ * operation reads <tt>numEls</tt> values from the buffer and writes
+ * them to the elements:
+ <pre><code>
+ dest [indexes [idxOff]], dest [indexes [idxOff + 1]], ..., dest [indexes [idxOff + numEls - 1]]
+ </code></pre>
+ * <p>
+ * The operations
+ * {@link #strGather(byte[],int,int,int,int,int[]) strGather()} and
+ * {@link #strScatter(byte[],int,int,int,int,int[]) strScatter()} likewise
+ * transfer data from or to a subset of elements of a Java array, but
+ * in these cases the selected subset is a "multi-strided region"
+ * of the Java array. The specification is fairly complex, but these
+ * are useful operations for dealing with multidimensional data
+ * structures, which occur often in scientific programming.
+ * The generic forms are respectively:
+ <pre><code>
+ <b>strGather</b>(<i>type</i>[] source,
+ int srcOff,
+ int rank,
+ int exts,
+ int srs,
+ int[] shape)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>strScatter</b>(<i>type</i>[] dest,
+ int dstOff,
+ int rank,
+ int exts,
+ int srs,
+ int[] shape)
+ </code></pre>
+ * A multi-strided region is characterized a <i>rank</i>, or
+ * <i>dimensionality</i>, which we will call <i>r</i>. The detailed shape of
+ * the region is represented by a vector of <i>r</i> <i>extents</i> or
+ * <i>sizes</i>, which we will call
+ * <i>n</i><sub>1</sub>,
+ * <i>n</i><sub>2</sub>, ...,
+ * <i>n</i><sub><i>r</i></sub>,
+ * and a vector of <i>r</i> <i>strides</i>, which we will call
+ * <i>s</i><sub>1</sub>,
+ * <i>s</i><sub>2</sub>, ...,
+ * <i>s</i><sub><i>r</i></sub>.
+ * <p>
+ * In the one dimensional case (<i>r</i> = 1), for example, a
+ * {@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operation copies values of the elements:
+ <pre><code>
+ source[srcOff], source[srcOff + s<sub>1</sub>], ..., source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub>],
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely a rank-1
+ * {@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operation reads <i>n</i><sub>1</sub>
+ * values from the buffer and writes them to the elements:
+ <pre><code>
+ dest[dstOff], dest[dstOff + s<sub>1</sub>], ..., dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub>],
+ </code></pre>
+ * In the two dimensional case, a
+ * {@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operation copies values of the elements:
+ <pre><code>
+ source[srcOff], source[srcOff + s<sub>2</sub>], ..., source[srcOff + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ source[srcOff + s<sub>1</sub>], source[srcOff + s<sub>1</sub> + s<sub>2</sub>], ..., source[srcOff + s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ ...,
+ source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub>], source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub> + s<sub>2</sub>], ..., source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * A rank-2
+ * {@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operation reads
+ * <i>n</i><sub>1</sub> <i>n</i><sub>2</sub>
+ * values from the buffer and writes them to the elements:
+ <pre><code>
+ dest[dstOff], dest[dstOff + s<sub>2</sub>], ..., dest[dstOff + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ dest[dstOff + s<sub>1</sub>], dest[dstOff + s<sub>1</sub> + s<sub>2</sub>], ..., dest[dstOff + s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ ...,
+ dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub>], dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub> + s<sub>2</sub>], ..., dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>]
+ </code></pre>
+ * This pattern generalizes to any rank.
+ * In the concrete parameters lists, the sizes
+ * <i>n</i><sub>1</sub>,
+ * <i>n</i><sub>2</sub>, ...,
+ * <i>n</i><sub><i>r</i></sub> are given by the <tt>shape</tt>
+ * elements:
+ <pre><code>
+ shape[exts], shape[exts + 1], ..., shape[exts + rank - 1]
+ </code></pre>
+ * and the strides
+ * <i>s</i><sub>1</sub>,
+ * <i>s</i><sub>2</sub>, ...,
+ * <i>s</i><sub><i>r</i></sub> are given by the <tt>shape</tt>
+ * elements:
+ <pre><code>
+ shape[strs], shape[strs + 1], ..., shape[strs + rank - 1]
+ </code></pre>
+ * <p>
+ *
+ * <h3>Read-write modes</h3>
+ * When a buffer object is initially created, the buffer is in a
+ * <i>writable</i> state. In this state, new sections and data can
+ * be added to the buffer. However read operations are <i>not</i>
+ * allowed while a buffer is in the writable state. When writing
+ * is completed, the {@link #commit() commit()} method "freezes" the buffer,
+ * putting it in a <i>readable</i> state, and moves the read pointer to
+ * the start of the buffer. Now read operations can begin; but
+ * write operations are no longer allowed.
+ * <p>
+ * After the data has been read, you may want to put the buffer back
+ * into a writable state, ready for more data. To do this use the
+ * {@link #clear() clear()} method. This erases the original data, and moves
+ * the write pointer to the start of the buffer.
+ * If on the other hand you need to re-read the same buffer contents from
+ * the beginning, the {@link #commit() commit()} method can be called
+ * again to rewind the read pointer back to the start of the buffer,
+ * without changing contents.
+ *
+ * <h3>Miscellany</h3>
+ * Where consistent with efficiency, operations reading from or writing
+ * to the buffer attempt to check whether the operation will succeed
+ * <i>before</i> transfering any data. In some circumstances
+ * this is difficult to guarantee; if an operation resulting
+ * in an exception <i>does</i> result in a partial read or write,
+ * subsequent calls to {@link #getRemaining() getRemaining()} or
+ * {@link #getSectionSize() getSectionSize()}
+ * will generally reflect how much data was transferred before
+ * the exception occurred. But even this behavior cannot be guaranteed
+ * in the case of {@link Type#OBJECT OBJECT} sections,
+ * where an individual object may be incompletely transferred.
+ */
+public class Buffer {
+
+ /*
+ * Every section has a header that occupies
+ * <tt>SECTION_OVERHEAD</tt> units of capacity.
+ * Note this increases the effective
+ * space occupied by a section.
+ */
+ public static final int SECTION_OVERHEAD = 8 ;
+
+ /*
+ * Padding is added after each section in the buffer
+ * to ensure every section starts on a boundary that is a multiple
+ * of <tt>ALIGNMENT_UNIT</tt> units of buffer capacity.
+ * Note this increases the effective space occupied by a section.
+ */
+ public static final int ALIGNMENT_UNIT = 8 ;
+ // For beginning of sections.
+
+
+ private static final ByteOrder localEncoding = ByteOrder.nativeOrder() ;
+
+ private int capacity ;
+
+ private ByteOrder encoding ;
+
+ private boolean freed ;
+
+ private boolean writeable ;
+
+ private Type currentSectionType ;
+
+ private int size ;
+ private int bufoffset ; // delete it later
+ private int sectionHeader ;
+ private int sectionSize ;
+
+ private int readPtr ;
+ private int elementsRemaining ;
+ // Elements remaining to be read in current section.
+
+ /*
+ * Streams used for dynamic part of buffer ("secondary payload")
+ */
+
+ private ByteArrayOutputStream byteOut;
+ private ObjectOutputStream out;
+
+ private ObjectInputStream in;
+
+ private byte [] dynamicBuffer ;
+ private RawBuffer staticBuffer ;
+
+ private CustomObjectInputStream inn;
+
+ /**
+ * Default constructor
+ */
+ protected Buffer( ) {
+ }
+
+ /**
+ * Creates a buffer with specified static capacity, and
+ * static buffer encoding given by
+ * <tt>java.nio.ByteOrder.nativeEncoding()</tt>.
+ * When created the buffer is empty, and it is in a writeable state.
+ * @param capacity the capacity of the static buffer, in bytes.
+ */
+ public Buffer(int capacity) {
+ //why needed:
+ // src/mpjdev/Comm.java is using this constr.
+ // no factory at that level ...
+ encoding = localEncoding ;
+
+ currentSectionType = null ;
+ writeable = true ;
+
+ //staticBuffer = new NativeBuffer(capacity) ;
+ // In principle, can slot in other implementations
+ // of `RawBuffer' here.
+ staticBuffer = new NIOBuffer(capacity);
+ freed = false ;
+ }
+
+ public int offset() {
+ return bufoffset ;
+ }
+
+ /**
+ * Creates a buffer with specified rawbuffer, and staring
+ * at the offset specified. Encoding given by
+ * <tt>java.nio.ByteOrder.nativeEncoding()</tt>.
+ * When created the buffer is not necessarily empty, but
+ * is in a writeable state.
+ * This constructor supports the Buffered mode of send at the higher
+ * level.
+ * buffer Rawbuffer
+ * offset the starting offset of this buffer
+ * need level argument ...
+ * public access required for bsend object is made in BasicType.java
+ * in 'createWriteBuffer' method.
+ */
+ public Buffer(RawBuffer buffer, int bufoffset, int capacity) {
+
+ encoding = localEncoding;
+
+ currentSectionType = null;
+ writeable = true;
+
+ staticBuffer = buffer;
+ freed = false;
+ this.bufoffset = bufoffset;
+ //this.offset = offset ;
+ this.capacity = capacity;
+ }
+
+ /* not well thought ..instead of sending bits n pieces of Buffer,
+ * why not just send the reference of buffer itself and then
+ * figure out things within this method like geting the reference
+ * of static buffer and dynamic buffer
+ */
+ public void copy(ByteBuffer srcStaticBuffer, int srcOffset,
+ int staticBufferLength, int dstOffset,
+ byte[] srcDynamicBuffer, int dynamicBufferLength) {
+
+ staticBuffer.copy(srcStaticBuffer, srcOffset,
+ staticBufferLength,
+ dstOffset) ;
+
+ setSize( staticBufferLength ) ;
+
+ if(dynamicBufferLength > 0) {
+ setDynamicBuffer( srcDynamicBuffer) ;
+ }
+
+ }
+
+ /**
+ * Free resources associated with this buffer. The only
+ * method invocations allowed on the buffer instance after this
+ * method has been called are further calls to <tt>free()</tt>
+ * or {@link #finalize() finalize()}, none of which have any effect
+ * after the first invocation.
+ */
+ public void free() {
+
+ if(!freed) {
+
+ closeObjectStreams() ;
+
+ dynamicBuffer = null ;
+
+ staticBuffer.free() ;
+
+ freed = true ;
+ }
+ }
+
+ /**
+ * Freeze buffer, putting it into a readable state, and setting the
+ * read pointer to the start of the buffer. This method can
+ * also be used to "rewind" a buffer that is already in readable
+ * state.
+ * @throws DynamicBufferException if there are unforseen problems
+ * saving the state of the dynamic buffer.
+ * @throws WrongStateException if buffer has already been freed.
+ */
+ public void commit() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+ // Save size of last section to buffer.
+ if(currentSectionType != null) {
+ staticBuffer.putInt(sectionSize, sectionHeader+4+bufoffset ) ;
+ }
+
+ if (out != null) {
+ try {
+ out.flush() ;
+ dynamicBuffer = byteOut.toByteArray();
+ //System.out.println(" length ="+dynamicBuffer.length) ;
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ closeObjectStreams() ;
+
+ currentSectionType = null ;
+ readPtr = 0 ;
+ elementsRemaining = 0 ;
+
+ writeable = false ;
+ }
+
+ /**
+ * Empty the buffer and put it in a writeable state.
+ * @throws WrongStateException if buffer has already been freed.
+ */
+ public void clear() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ closeObjectStreams() ;
+
+ encoding = localEncoding ;
+
+ currentSectionType = null ;
+ size = 0 ;
+ sectionHeader = 0 ;
+
+ dynamicBuffer = null ;
+
+ writeable = true ;
+ }
+
+ private void closeObjectStreams() {
+
+ if (in != null) {
+ try {
+ in.close();
+ in = null;
+ } catch(IOException e){
+ // IO error should not occur when we close
+ // byte array inputstream.
+ }
+ }
+
+ if (out != null) {
+ try {
+ out.close() ;
+ out = null ;
+ byteOut = null ;
+ } catch (IOException e){
+ // IO error should not occur when we close
+ // byte array inputstream.
+ }
+ }
+ }
+
+ /**
+ * Start a new section in the buffer: write a section header to
+ * the buffer and make the new section the current section.
+ * The header requires
+ * {@link #SECTION_OVERHEAD SECTION_OVERHEAD}
+ * bytes of static buffer capacity.
+ * Any preceding section will be padded with the minimum
+ * number of bytes necessary to ensure that the new section starts on
+ * a boundary that is a multiple of
+ * {@link #ALIGNMENT_UNIT ALIGNMENT_UNIT} bytes.
+ * This may require up to <tt>ALIGNMENT_UNIT - 1</tt> bytes of
+ * additional buffer capacity.
+ * @param type the type of this section. One of
+ * {@link Type#BYTE BYTE},
+ * {@link Type#CHAR CHAR},
+ * {@link Type#SHORT SHORT},
+ * {@link Type#BOOLEAN BOOLEAN},
+ * {@link Type#INT INT},
+ * {@link Type#LONG LONG},
+ * {@link Type#FLOAT FLOAT}, or
+ * {@link Type#DOUBLE DOUBLE}, if this is a static section, or one of
+ * {@link Type#OBJECT OBJECT},
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}
+ * if this is a dynamic section.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or buffer has already been freed.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ */
+ public void putSectionHeader(Type type) throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ // Save size of previous section to buffer.
+ if(currentSectionType != null) {
+ staticBuffer.putInt(sectionSize, bufoffset+sectionHeader + 4) ;
+ }
+
+ int newSectionHeader = ALIGNMENT_UNIT *
+ ((size + ALIGNMENT_UNIT - 1) / ALIGNMENT_UNIT) ;
+ // Round up to multiple of ALIGNMENT_UNIT.
+
+ int newSize = newSectionHeader + SECTION_OVERHEAD ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for new section header.") ;
+
+ staticBuffer.putByte(type.getCode() , newSectionHeader + bufoffset) ;
+
+ size = newSize ;
+ sectionHeader = newSectionHeader ;
+ currentSectionType = type ;
+ sectionSize = 0 ;
+ }
+
+ /**
+ * Read a section header from the buffer,
+ * and make this the current section.
+ * @return the type of the expected section. One of
+ * {@link Type#BYTE BYTE},
+ * {@link Type#CHAR CHAR},
+ * {@link Type#SHORT SHORT},
+ * {@link Type#BOOLEAN BOOLEAN},
+ * {@link Type#INT INT},
+ * {@link Type#LONG LONG},
+ * {@link Type#FLOAT FLOAT},
+ * {@link Type#DOUBLE DOUBLE},
+ * {@link Type#OBJECT OBJECT},
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or buffer has already been freed.
+ * @throws TypeMismatchException if the value of the type
+ * parameter does not precisely match the value specified when the
+ * section was originally created by {@link #putSectionHeader(Type)
+ * putSectionHeader()}.
+ * @throws SectionSizeMismatchException if there are elements remaining
+ * to be read in the previous section.
+ * @throws BufferUnderflowException if there there are no more
+ * sections remaining to be read in the buffer.
+ */
+ public Type getSectionHeader() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(elementsRemaining != 0)
+ throw new SectionSizeMismatchException("Previous " +
+ "section was not completely read.") ;
+
+ int headerStart = 8 * ((readPtr + 7) / 8) ;
+ // Round up to multiple of 8.
+ // System.out.println("headerStart = "+headerStart+" bufoffset = "+bufoffset);
+ int newReadPtr = headerStart + SECTION_OVERHEAD ;
+
+ if(newReadPtr > size) {
+ throw new BufferUnderflowException("Trying to read " +
+ "past end of buffer. < newReadPtr > size > "+newReadPtr+" > "+size) ;
+ }
+
+ int typeCode = staticBuffer.getByte(headerStart+bufoffset) ;
+ sectionSize = staticBuffer.getInt(headerStart + 4 +bufoffset,
+ encoding != localEncoding) ;
+ // System.out.println("typeCode = "+typeCode+" sectionSize = "+sectionSize);
+ readPtr = newReadPtr ;
+ currentSectionType = Type.getType(typeCode) ;
+ elementsRemaining = sectionSize ;
+
+ return currentSectionType ;
+ }
+
+ /**
+ * Size of current section.
+ * If buffer is currently readable, return value is fixed for this section.
+ * If buffer is currently writable, return value is number of elements
+ * written to this section so far.
+ * @return number of elements in this section.
+ * @throws WrongStateException if current section is undefined,
+ * or buffer has already been freed.
+ */
+ public int getSectionSize() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'getSectionHeader' or 'putSectionHeader'") ;
+
+ return sectionSize ;
+ }
+
+ /**
+ * Returns number of elements remaining to be read in the current
+ * section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or buffer has already been freed.
+ */
+ public int getRemaining() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ return elementsRemaining ;
+ }
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive byte elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 1 * numEls
+ * units of static buffer capacity.
+ * @param source the byte array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(byte [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.BYTE) {
+
+ int newSize = size + 1 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeByte(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive short elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 2 * numEls
+ * units of static buffer capacity.
+ * @param source the short array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(short [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.SHORT) {
+
+ int newSize = size + 2 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeShort(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive int elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 4 * numEls
+ * units of static buffer capacity.
+ * @param source the int array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(int [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.INT) {
+
+ int newSize = size + 4 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeInt(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive long elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 8 * numEls
+ * units of static buffer capacity.
+ * @param source the long array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(long [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.LONG) {
+
+ int newSize = size + 8 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeLong(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive char elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 2 * numEls
+ * units of static buffer capacity.
+ * @param source the char array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(char [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.CHAR) {
+
+ int newSize = size + 2 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeChar(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive float elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 4 * numEls
+ * units of static buffer capacity.
+ * @param source the float array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(float [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.FLOAT) {
+
+ int newSize = size + 4 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeFloat(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive double elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 8 * numEls
+ * units of static buffer capacity.
+ * @param source the double array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(double [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+
+ int newSize = size + 8 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeDouble(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive boolean elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires 1 * numEls
+ * units of static buffer capacity.
+ * @param source the boolean array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(boolean [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+
+ int newSize = size + 1 * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeBoolean(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> consecutive Object elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer.
+ * @param source the Object array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(Object [] source, int srcOff, int numEls)
+ throws BufferException {
+
+ //System.out.println("Reaching in the write method2");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section, or missing call to 'putSectionHeader'") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeObject(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `write()' methods.
+ */
+ private void writeCheckArgs(int sourceLen, int srcOff, int numEls)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'putSectionHeader'") ;
+
+ if(srcOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + srcOff) ;
+
+ if(srcOff + numEls > sourceLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + (srcOff + numEls - 1)) ;
+ }
+
+
+ /**
+ * Append <tt>numEls</tt> selected byte elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 1 * numEls
+ * units of static buffer capacity.
+ * @param source the byte array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(byte [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.BYTE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 1 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 1 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeByte(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected short elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 2 * numEls
+ * units of static buffer capacity.
+ * @param source the short array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(short [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.SHORT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 2 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 2 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeShort(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected int elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 4 * numEls
+ * units of static buffer capacity.
+ * @param source the int array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(int [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.INT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 4 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 4 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeInt(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected long elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 8 * numEls
+ * units of static buffer capacity.
+ * @param source the long array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(long [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.LONG) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 8 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 8 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeLong(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected char elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 2 * numEls
+ * units of static buffer capacity.
+ * @param source the char array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(char [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.CHAR) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 2 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 2 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeChar(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected float elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 4 * numEls
+ * units of static buffer capacity.
+ * @param source the float array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(float [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.FLOAT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 4 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 4 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeFloat(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected double elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 8 * numEls
+ * units of static buffer capacity.
+ * @param source the double array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(double [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 8 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 8 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeDouble(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected boolean elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires 1 * numEls
+ * units of static buffer capacity.
+ * @param source the boolean array from which data is taken.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(boolean [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + 1 * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += 1 * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeBoolean(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+
+ /**
+ * Append <tt>numEls</tt> selected Object elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param source the Object array from which data is taken.
+ * @param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(Object [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+ out.writeObject(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `gather()' methods.
+ */
+ private void gatherCheckArgs(int numEls, int idxOff, int indexesLen)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'putSectionHeader'") ;
+
+ if(idxOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + idxOff) ;
+
+ if(idxOff + numEls > indexesLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + (idxOff + numEls - 1)) ;
+ }
+
+
+
+ /**
+ * Append selected byte elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 1 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the byte array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(byte [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.BYTE) {
+ if(volume != 0) {
+ int newSize = size + 1 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(byte [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeByte(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected short elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 2 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the short array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(short [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.SHORT) {
+ if(volume != 0) {
+ int newSize = size + 2 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(short [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeShort(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected int elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 4 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the int array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(int [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.INT) {
+ if(volume != 0) {
+ int newSize = size + 4 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(int [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeInt(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected long elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 8 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the long array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(long [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.LONG) {
+ if(volume != 0) {
+ int newSize = size + 8 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(long [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeLong(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected char elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 2 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the char array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(char [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.CHAR) {
+ if(volume != 0) {
+ int newSize = size + 2 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(char [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeChar(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected float elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 4 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the float array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(float [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.FLOAT) {
+ if(volume != 0) {
+ int newSize = size + 4 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(float [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeFloat(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected double elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 8 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the double array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(double [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+ if(volume != 0) {
+ int newSize = size + 8 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(double [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeDouble(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected boolean elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires 1 * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * @param source the boolean array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(boolean [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+ if(volume != 0) {
+ int newSize = size + 1 * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather(boolean [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeBoolean(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+ /**
+ * Append selected boolean elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param source the boolean array from which data is taken.
+ * @param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * @param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(Object [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ private void doStrGather(Object [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeObject(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `strGather()' methods.
+ */
+ private int strGatherCheckArgs(int sourceLen, int srcOff, int rank,
+ int exts, int strs, int [] shape)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'putSectionHeader'") ;
+
+ if(rank < 0)
+ throw new mpjbuf.IllegalArgumentException("Negative rank " +
+ "specified") ;
+
+ int minIndex = srcOff, maxIndex = srcOff ;
+ int volume = 1;
+
+ for (int i = 0; i < rank; i++) {
+
+ int ext = shape [exts + i] ;
+ int str = shape [strs + i] ;
+
+ if (ext < 0)
+ throw new ArrayIndexOutOfBoundsException("Patch has " +
+ "negative extent.") ;
+
+ if (ext == 0)
+ return 0 ;
+
+ if (str < 0)
+ minIndex += str * (ext - 1);
+ else
+ maxIndex += str * (ext - 1);
+
+ volume *= ext ;
+ }
+
+ if(minIndex < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + minIndex) ;
+
+ if(maxIndex >= sourceLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + maxIndex) ;
+
+ return volume ;
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> byte items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the byte array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(byte [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.BYTE) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readByte();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> short items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the short array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(short [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.SHORT) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readShort();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> int items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the int array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(int [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.INT) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readInt();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> long items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the long array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(long [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.LONG) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readLong();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> char items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the char array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(char [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.CHAR) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readChar();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> float items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the float array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(float [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.FLOAT) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readFloat();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> double items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the double array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(double [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readDouble();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> boolean items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the boolean array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read(boolean [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.readBoolean();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> Object items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * @param dest the Object array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void read(Object [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section, or missing call to 'getSectionHeader'") ;
+
+ try {
+ if (inn == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+ Object obj;
+ for (int i = 0; i < numEls; i++) {
+ obj = in.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(ClassNotFoundException ce){
+
+ //throw new DynamicBufferException("Problem reading " +
+ // "dynamic buffer", e) ;
+
+ try {
+ ByteArrayInputStream o = new ByteArrayInputStream(dynamicBuffer);
+ inn = new CustomObjectInputStream(o);
+ for (int i = 0; i < numEls; i++) {
+ Object obj =inn.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(Exception ioe){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", ioe) ;
+ }
+
+ }
+ catch(Exception e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `read()' methods.
+ */
+ private void readCheckArgs(int destLen, int dstOff, int numEls)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'getSectionHeader'") ;
+
+ if(dstOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + dstOff) ;
+
+ if(dstOff + numEls > destLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + (dstOff + numEls - 1)) ;
+
+ if(numEls > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+ }
+
+
+ /**
+ * Read the next <tt>numEls</tt> byte items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the byte array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(byte [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.BYTE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readByte()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readByte();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> short items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the short array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(short [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.SHORT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readShort()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readShort();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> int items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the int array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(int [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.INT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readInt()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readInt();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> long items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the long array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(long [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.LONG) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readLong()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readLong();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> char items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the char array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(char [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.CHAR) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readChar()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readChar();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> float items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the float array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(float [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.FLOAT) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readFloat()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readFloat();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> double items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the double array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(double [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readDouble()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readDouble();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> boolean items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the boolean array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter(boolean [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `readBoolean()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readBoolean();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+
+ /**
+ * Read the next <tt>numEls</tt> Object items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {@link mpjbuf.Buffer class description} for further details.
+ * @param dest the Object array to which data will be written.
+ * @param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * @param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * @param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void scatter(Object [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls ; i++) {
+
+ // `readObject()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readObject();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ catch(ClassNotFoundException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `scatter()' methods.
+ */
+ private void scatterCheckArgs(int numEls, int idxOff, int indexesLen)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "'getSectionHeader'") ;
+
+ if(numEls > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+
+ if(idxOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + idxOff) ;
+
+ if(idxOff + numEls > indexesLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + (idxOff + numEls - 1)) ;
+ }
+
+
+
+ /**
+ * Read byte items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the byte array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BYTE BYTE} or
+ * {@link Type#BYTE_DYNAMIC BYTE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(byte [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.BYTE) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.BYTE_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(byte [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readByte();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read short items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the short array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#SHORT SHORT} or
+ * {@link Type#SHORT_DYNAMIC SHORT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(short [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.SHORT) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.SHORT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(short [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readShort();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read int items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the int array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#INT INT} or
+ * {@link Type#INT_DYNAMIC INT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(int [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.INT) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.INT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(int [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readInt();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read long items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the long array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#LONG LONG} or
+ * {@link Type#LONG_DYNAMIC LONG_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(long [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.LONG) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.LONG_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(long [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readLong();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read char items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the char array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#CHAR CHAR} or
+ * {@link Type#CHAR_DYNAMIC CHAR_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(char [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.CHAR) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 2 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.CHAR_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(char [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readChar();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read float items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the float array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#FLOAT FLOAT} or
+ * {@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(float [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.FLOAT) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 4 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.FLOAT_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(float [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readFloat();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read double items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the double array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#DOUBLE DOUBLE} or
+ * {@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(double [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.DOUBLE) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 8 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.DOUBLE_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(double [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readDouble();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read boolean items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the boolean array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#BOOLEAN BOOLEAN} or
+ * {@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter(boolean [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.BOOLEAN) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += 1 * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.BOOLEAN_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter(boolean [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readBoolean();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+
+ /**
+ * Read Object items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {@link mpjbuf.Buffer class description} for details.
+ * @param dest the Object array to which data will be written.
+ * @param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * @param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * @param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * @param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * @param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * @throws TypeMismatchException if the current section was not
+ * created with type {@link Type#OBJECT OBJECT}.
+ * @throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * @throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * @throws IllegalArgumentException if the specified rank is negative.
+ * @throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * @throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void strScatter(Object [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ strScatterCheckArgs(dest.length, dstOff, rank, exts, strs, shape) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (inn == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+ }
+ catch(ClassNotFoundException e){
+
+ //throw new DynamicBufferException("Problem reading " +
+ // "dynamic buffer", e) ;
+ try{
+ ByteArrayInputStream o = new ByteArrayInputStream(dynamicBuffer);
+ inn = new CustomObjectInputStream(o);
+ for (int i = 0; i < strs; i++) {
+ Object obj =inn.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(Exception ioe){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", ioe) ;
+ }
+ }
+ catch(Exception e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ private void doStrScatter(Object [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException, ClassNotFoundException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readObject();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `strScatter()' methods.
+ */
+ private int strScatterCheckArgs(int destLen, int dstOff, int rank,
+ int exts, int strs, int [] shape)
+ throws BufferException {
+
+ // Also implicitly checks that `shape' != null,
+ // and `shape' subscripts in range.
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(rank < 0)
+ throw new mpjbuf.IllegalArgumentException("Negative rank" +
+ " specified") ;
+
+ if(currentSectionType == null)
+ throw new TypeMismatchException("Missing call to " +
+ "'getSectionHeader'") ;
+
+ int minIndex = dstOff, maxIndex = dstOff ;
+ int volume = 1;
+
+ for (int i = 0; i < rank; i++) {
+
+ int ext = shape [exts + i] ;
+ int str = shape [strs + i] ;
+
+ if (ext < 0)
+ throw new ArrayIndexOutOfBoundsException("Patch has " +
+ "negative extent.") ;
+
+ if (ext == 0)
+ return 0 ;
+
+ if (str < 0)
+ minIndex += str * (ext - 1);
+ else
+ maxIndex += str * (ext - 1);
+
+ volume *= ext ;
+ }
+
+ if(minIndex < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + minIndex) ;
+
+ if(maxIndex >= destLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + maxIndex) ;
+
+ if(volume > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+
+ return volume ;
+ }
+
+
+ // Low-level methods used for sending and receiving the buffer.
+
+ /**
+ * Returns a representation of the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public RawBuffer getStaticBuffer() {
+ return staticBuffer ;
+ }
+
+ /**
+ * Set representation of the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setStaticBuffer(RawBuffer staticBuffer) {
+ this.staticBuffer = staticBuffer ;
+ }
+
+ /**
+ * Returns encoding of numeric data in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public ByteOrder getEncoding() {
+ return encoding ;
+ }
+
+ /**
+ * Set encoding of numeric data in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setEncoding(ByteOrder encoding) {
+ //not sure if we need it ...? aamir.
+ if(staticBuffer instanceof NIOBuffer) {
+ ((NIOBuffer) staticBuffer).setEncoding(encoding);
+ }
+ this.encoding = encoding ;
+ }
+
+ /**
+ * Get total number of bytes of data currently in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public int getSize() {
+ return size ;
+ }
+
+ /**
+ * Set total number of bytes of data currently in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setSize(int size) {
+ this.size = size ;
+ }
+ /**
+ * Get total number of bytes -- capacity of the static buffer.
+ * Low-level method used for in native device for receiving the buffer.
+ */
+ public int getCapacity() {
+ return capacity ;
+ }
+ /**
+ * Get bytes of the dynamic buffer.
+ * Low-level method used for sending and receiving the buffer.
+ * Only use this on a commited (readable) buffer.
+ */
+ public byte [] getDynamicBuffer() {
+
+ // Note return value may not be up to date if the buffer
+ // has not been commited.
+
+ return dynamicBuffer ;
+ }
+
+ /**
+ * Set bytes of the dynamic buffer.
+ * Low-level method used for sending and receiving the buffer.
+ * Buffer should be empty prior to this call.
+ */
+ public void setDynamicBuffer(byte [] dynamicBuffer) {
+
+ // Note if buffer is not empty, `out' may not be `null'.
+ // This may result in the new value of `dynamicBuffer' being
+ // overwritten if, for example, there is a subsequent call
+ // `commit()'.
+
+ this.dynamicBuffer = dynamicBuffer ;
+ }
+
+ /**
+ * Determine read-write mode of buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public boolean isWritable() {
+ return writeable ;
+ }
+}
+
diff --git a/src/mpjbuf/Buffer.java.in b/src/mpjbuf/Buffer.java.in
new file mode 100644
index 0000000..a3bc9b1
--- /dev/null
+++ b/src/mpjbuf/Buffer.java.in
@@ -0,0 +1,2101 @@
+
+# File : Buffer.java.in
+# Author : Sang Lim, Bryan Carpenter, Aamir Shafi
+# Created : Thu Jan 17 17:31:40 2002
+# Revision : $Revision: 1.13 $
+# Updated : $Date: 2006/04/25 19:26:15 $
+
+# Primitive types
+
+ at ptypes = ('byte', 'short', 'int', 'long',
+ 'char', 'float', 'double', 'boolean') ;
+ at pTYPEs = ('BYTE', 'SHORT', 'INT', 'LONG',
+ 'CHAR', 'FLOAT', 'DOUBLE', 'BOOLEAN') ;
+ at pTypes = ('Byte', 'Short', 'Int', 'Long',
+ 'Char', 'Float', 'Double', 'Boolean') ;
+ at psizes = ( 1, 2, 4, 8,
+ 2, 4, 8, 1) ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+
+import java.io.IOException;
+
+import java.nio.ByteOrder ;
+import java.nio.ByteBuffer ;
+
+/**
+ * A buffer object, for holding an mpjdev message.
+ * <p>
+ * Through appropriate use of <i>sections</i>, described below,
+ * a single buffer object can contain a mixture of elements of any Java type.
+ * A single buffer object can be reused both for sending and receiving
+ * messages, although at any given time a buffer is either in
+ * a <i>readable</i> state or a <i>writeable</i> state.
+ * A buffer is created with a fixed <i>static capacity</i> which does
+ * not change during the lifetime of the buffer. However a
+ * buffer can also (under user control) store data in a dynamically
+ * allocated region---this is necessary in particular to support
+ * serialized objects. A characteristic feature of the
+ * {\@link mpjbuf.Buffer mpjbuf.Buffer}
+ * is that is supports transfer of data from and to non-contiguous
+ * sections of a Java array through various gather and scatter methods.
+ *
+ * <h3>Sections</h3>
+ * A message is considered to consist of zero or more "sections".
+ * Each section holds a sequence of elements which
+ * are either all of the same primitive type, or all have Object type.
+ * When a buffer is in writeable mode,
+ * a new section is started by invoking
+ * {\@link #putSectionHeader(Type) putSectionHeader()}
+ * to mark the start of the section. This is followed by a series
+ * {\@link #write(byte[],int,int) write()},
+ * {\@link #gather(byte[],int,int,int[]) gather()}, and/or
+ * {\@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operations to write the data to the section. When a buffer is
+ * in readable mode, one starts reading a section by invoking
+ * {\@link #getSectionHeader() getSectionHeader()}
+ * to determine the type of elements in the next section,
+ * and to make it the current section.
+ * This is followed by a series
+ * {\@link #read(byte[],int,int) read()},
+ * {\@link #scatter(byte[],int,int,int[]) scatter()}, and/or
+ * {\@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operations to read the data from the section. Buffers may
+ * only be written and read sequentially, from beginning to end.
+ * <p>
+ * In general a buffer object comprises two regions: a <i>primary</i> or
+ * <i>static</i> buffer, and a <i>secondary</i> or <i>dynamic</i> buffer.
+ * The static buffer has a fixed capacity, specified when the buffer is
+ * created. The size of the dynamic buffer grows automatically as new
+ * data is written to it. Any section can be created as a <i>static
+ * section</i> or a <i>dynamic section</i>, and this controls which region
+ * of the buffer the section data is stored in.
+ * It is important to note that in general writing to or reading
+ * from a static section is <i>much</i> faster than the corresponding
+ * operation on a dynamic section. Dynamic sections are required to
+ * support storing serialized objects in the buffer. As a convenience
+ * to the programmer, dynamic sections holding primitive types
+ * are also supported. But in general use of the dynamic buffer is
+ * is only recommended for short or infrequent message exchanges.
+ *
+ * <h3>Physical layout of buffer</h3>
+ * Numeric data in the static buffer can be represented in big-endian
+ * or little-endian format. This is determined by the <tt>encoding</tt>
+ * property of the buffer, which takes on of the values
+ * <tt>java.nio.ByteOrder.BIG_ENDIAN</tt> or
+ * <tt>java.nio.ByteOrder.LITTLE_ENDIAN</tt>. The <tt>encoding</tt> property
+ * of a newly created buffer is determined by the return value of
+ * <tt>java.nio.ByteOrder.nativeOrder()</tt>.
+ * <p>
+ * The overall layout of the static buffer is illustrated in the following
+ * figure:
+ * <p>
+ * <img src="../../images/mpj-static.png"/>
+ * <p>
+ * In practise many messages will contain only a single section.
+ * There are up to 7 bytes of padding after each section
+ * to ensure that the next section header begins on a boundary that is a
+ * multiple of {\@link #ALIGNMENT_UNIT ALIGNMENT_UNIT}, which has value 8.
+ * <p>
+ * The general layout of an individual section in the static buffer
+ * is illustrated in the following figure:
+ * <p>
+ * <img src="../../images/mpj-section.png"/>
+ * <p>
+ * The first byte of the section header defines the type of the section,
+ * encoding one of the possible values
+ * {\@link Type#BYTE BYTE},
+ * {\@link Type#CHAR CHAR},
+ * {\@link Type#SHORT SHORT},
+ * {\@link Type#BOOLEAN BOOLEAN},
+ * {\@link Type#INT INT},
+ * {\@link Type#LONG LONG},
+ * {\@link Type#FLOAT FLOAT}, or
+ * {\@link Type#DOUBLE DOUBLE}, if the section is static, or one of
+ * {\@link Type#OBJECT OBJECT},
+ * {\@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {\@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {\@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {\@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {\@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {\@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {\@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {\@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC} if the section is dynamic.
+ * The second 4 bytes of the header holds the number of elements
+ * in the section. This numeric value is represented according to the
+ * <tt>encoding</tt> property of the buffer. The size of the header
+ * in bytes is {\@link #SECTION_OVERHEAD SECTION_OVERHEAD}, which has value 8.
+ * If the section is static, the header is followed by the values of
+ * the elements, again represented according to the
+ * <tt>encoding</tt> property of the buffer. If the section is dynamic,
+ * the "Section data" is absent from the diagram above (because the
+ * data is in the dynamic buffer).
+ * <p>
+ * The format of the <i>dynamic buffer</i>
+ * is entirely determined by the standard Java serialization classes
+ * <tt>java.io.ObjectOutputStream</tt> and <tt>java.io.ObjectInputStream</tt>.
+ * <p>
+ * <h3>Read and write operations</h3>
+ * There are 3 basic kinds of operation for writing data to a buffer
+ * section, and 3 basic kinds of operation for reading data from a buffer
+ * section. The simplest data transfer operations are
+ * {\@link #write(byte[],int,int) write()} and
+ * {\@link #read(byte[],int,int) read()},
+ * which transfer contiguous sections of a Java
+ * array. The generic forms are respectively:
+ <pre><code>
+ <b>write</b>(<i>type</i>[] source,
+ int srcOff,
+ int numEls)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>read</b>(<i>type</i>[] dest,
+ int dstOff,
+ int numEls)
+ </code></pre>
+ * The {\@link #write(byte[],int,int) write()}
+ * operation copies the values of elements:
+ <pre><code>
+ source [srcOff], source [srcOff + 1], ..., source [srcOff + numEls - 1]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely the {\@link #read(byte[],int,int) read()},
+ * operation reads <tt>numEls</tt> values from the buffer and writes
+ * them to the elements:
+ <pre><code>
+ dest [dstOff], dest [dstOff + 1], ..., dest [dstOff + numEls - 1]
+ </code></pre>
+ * <p>
+ * The operations {\@link #gather(byte[],int,int,int[]) gather()} and
+ * {\@link #scatter(byte[],int,int,int[]) scatter()} transfer
+ * data from or to a subset of elements of a Java array, selected by
+ * giving an index vector. The generic forms are respectively:
+ <pre><code>
+ <b>gather</b>(<i>type</i>[] source,
+ int numEls,
+ int idxOff,
+ int[] indexes)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>scatter</b>(<i>type</i>[] dest,
+ int numEls,
+ int idxOff,
+ int[] indexes)
+ </code></pre>
+ * The {\@link #gather(byte[],int,int,int[]) gather()}
+ * operation copies the values of elements:
+ <pre><code>
+ source [indexes [idxOff]], source [indexes [idxOff + 1]], ..., source [indexes [idxOff + numEls - 1]]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely the {\@link #scatter(byte[],int,int,int[]) scatter()}
+ * operation reads <tt>numEls</tt> values from the buffer and writes
+ * them to the elements:
+ <pre><code>
+ dest [indexes [idxOff]], dest [indexes [idxOff + 1]], ..., dest [indexes [idxOff + numEls - 1]]
+ </code></pre>
+ * <p>
+ * The operations
+ * {\@link #strGather(byte[],int,int,int,int,int[]) strGather()} and
+ * {\@link #strScatter(byte[],int,int,int,int,int[]) strScatter()} likewise
+ * transfer data from or to a subset of elements of a Java array, but
+ * in these cases the selected subset is a "multi-strided region"
+ * of the Java array. The specification is fairly complex, but these
+ * are useful operations for dealing with multidimensional data
+ * structures, which occur often in scientific programming.
+ * The generic forms are respectively:
+ <pre><code>
+ <b>strGather</b>(<i>type</i>[] source,
+ int srcOff,
+ int rank,
+ int exts,
+ int srs,
+ int[] shape)
+ </code></pre>
+ * and
+ <pre><code>
+ <b>strScatter</b>(<i>type</i>[] dest,
+ int dstOff,
+ int rank,
+ int exts,
+ int srs,
+ int[] shape)
+ </code></pre>
+ * A multi-strided region is characterized a <i>rank</i>, or
+ * <i>dimensionality</i>, which we will call <i>r</i>. The detailed shape of
+ * the region is represented by a vector of <i>r</i> <i>extents</i> or
+ * <i>sizes</i>, which we will call
+ * <i>n</i><sub>1</sub>,
+ * <i>n</i><sub>2</sub>, ...,
+ * <i>n</i><sub><i>r</i></sub>,
+ * and a vector of <i>r</i> <i>strides</i>, which we will call
+ * <i>s</i><sub>1</sub>,
+ * <i>s</i><sub>2</sub>, ...,
+ * <i>s</i><sub><i>r</i></sub>.
+ * <p>
+ * In the one dimensional case (<i>r</i> = 1), for example, a
+ * {\@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operation copies values of the elements:
+ <pre><code>
+ source[srcOff], source[srcOff + s<sub>1</sub>], ..., source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub>],
+ </code></pre>
+ * to the buffer, in the order shown.
+ * Conversely a rank-1
+ * {\@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operation reads <i>n</i><sub>1</sub>
+ * values from the buffer and writes them to the elements:
+ <pre><code>
+ dest[dstOff], dest[dstOff + s<sub>1</sub>], ..., dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub>],
+ </code></pre>
+ * In the two dimensional case, a
+ * {\@link #strGather(byte[],int,int,int,int,int[]) strGather()}
+ * operation copies values of the elements:
+ <pre><code>
+ source[srcOff], source[srcOff + s<sub>2</sub>], ..., source[srcOff + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ source[srcOff + s<sub>1</sub>], source[srcOff + s<sub>1</sub> + s<sub>2</sub>], ..., source[srcOff + s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ ...,
+ source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub>], source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub> + s<sub>2</sub>], ..., source[srcOff + (n<sub>1</sub> - 1)s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>]
+ </code></pre>
+ * to the buffer, in the order shown.
+ * A rank-2
+ * {\@link #strScatter(byte[],int,int,int,int,int[]) strScatter()}
+ * operation reads
+ * <i>n</i><sub>1</sub> <i>n</i><sub>2</sub>
+ * values from the buffer and writes them to the elements:
+ <pre><code>
+ dest[dstOff], dest[dstOff + s<sub>2</sub>], ..., dest[dstOff + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ dest[dstOff + s<sub>1</sub>], dest[dstOff + s<sub>1</sub> + s<sub>2</sub>], ..., dest[dstOff + s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>],
+ ...,
+ dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub>], dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub> + s<sub>2</sub>], ..., dest[dstOff + (n<sub>1</sub> - 1)s<sub>1</sub> + (n<sub>2</sub> - 1)s<sub>2</sub>]
+ </code></pre>
+ * This pattern generalizes to any rank.
+ * In the concrete parameters lists, the sizes
+ * <i>n</i><sub>1</sub>,
+ * <i>n</i><sub>2</sub>, ...,
+ * <i>n</i><sub><i>r</i></sub> are given by the <tt>shape</tt>
+ * elements:
+ <pre><code>
+ shape[exts], shape[exts + 1], ..., shape[exts + rank - 1]
+ </code></pre>
+ * and the strides
+ * <i>s</i><sub>1</sub>,
+ * <i>s</i><sub>2</sub>, ...,
+ * <i>s</i><sub><i>r</i></sub> are given by the <tt>shape</tt>
+ * elements:
+ <pre><code>
+ shape[strs], shape[strs + 1], ..., shape[strs + rank - 1]
+ </code></pre>
+ * <p>
+ *
+ * <h3>Read-write modes</h3>
+ * When a buffer object is initially created, the buffer is in a
+ * <i>writable</i> state. In this state, new sections and data can
+ * be added to the buffer. However read operations are <i>not</i>
+ * allowed while a buffer is in the writable state. When writing
+ * is completed, the {\@link #commit() commit()} method "freezes" the buffer,
+ * putting it in a <i>readable</i> state, and moves the read pointer to
+ * the start of the buffer. Now read operations can begin; but
+ * write operations are no longer allowed.
+ * <p>
+ * After the data has been read, you may want to put the buffer back
+ * into a writable state, ready for more data. To do this use the
+ * {\@link #clear() clear()} method. This erases the original data, and moves
+ * the write pointer to the start of the buffer.
+ * If on the other hand you need to re-read the same buffer contents from
+ * the beginning, the {\@link #commit() commit()} method can be called
+ * again to rewind the read pointer back to the start of the buffer,
+ * without changing contents.
+ *
+ * <h3>Miscellany</h3>
+ * Where consistent with efficiency, operations reading from or writing
+ * to the buffer attempt to check whether the operation will succeed
+ * <i>before</i> transfering any data. In some circumstances
+ * this is difficult to guarantee; if an operation resulting
+ * in an exception <i>does</i> result in a partial read or write,
+ * subsequent calls to {\@link #getRemaining() getRemaining()} or
+ * {\@link #getSectionSize() getSectionSize()}
+ * will generally reflect how much data was transferred before
+ * the exception occurred. But even this behavior cannot be guaranteed
+ * in the case of {\@link Type#OBJECT OBJECT} sections,
+ * where an individual object may be incompletely transferred.
+ */
+public class Buffer {
+
+ /*
+ * Every section has a header that occupies
+ * <tt>SECTION_OVERHEAD</tt> units of capacity.
+ * Note this increases the effective
+ * space occupied by a section.
+ */
+ public static final int SECTION_OVERHEAD = 8 ;
+
+ /*
+ * Padding is added after each section in the buffer
+ * to ensure every section starts on a boundary that is a multiple
+ * of <tt>ALIGNMENT_UNIT</tt> units of buffer capacity.
+ * Note this increases the effective space occupied by a section.
+ */
+ public static final int ALIGNMENT_UNIT = 8 ;
+ // For beginning of sections.
+
+
+ private static final ByteOrder localEncoding = ByteOrder.nativeOrder() ;
+
+ private int capacity ;
+
+ private ByteOrder encoding ;
+
+ private boolean freed ;
+
+ private boolean writeable ;
+
+ private Type currentSectionType ;
+
+ private int size ;
+ private int bufoffset ; // delete it later
+ private int sectionHeader ;
+ private int sectionSize ;
+
+ private int readPtr ;
+ private int elementsRemaining ;
+ // Elements remaining to be read in current section.
+
+ /*
+ * Streams used for dynamic part of buffer ("secondary payload")
+ */
+
+ private ByteArrayOutputStream byteOut;
+ private ObjectOutputStream out;
+
+ private ObjectInputStream in;
+
+ private byte [] dynamicBuffer ;
+ private RawBuffer staticBuffer ;
+
+ private CustomObjectInputStream inn;
+
+ /**
+ * Default constructor
+ */
+ protected Buffer( ) {
+ }
+
+ /**
+ * Creates a buffer with specified static capacity, and
+ * static buffer encoding given by
+ * <tt>java.nio.ByteOrder.nativeEncoding()</tt>.
+ * When created the buffer is empty, and it is in a writeable state.
+ * \@param capacity the capacity of the static buffer, in bytes.
+ */
+ public Buffer(int capacity) {
+ //why needed:
+ // src/mpjdev/Comm.java is using this constr.
+ // no factory at that level ...
+ encoding = localEncoding ;
+
+ currentSectionType = null ;
+ writeable = true ;
+
+ //staticBuffer = new NativeBuffer(capacity) ;
+ // In principle, can slot in other implementations
+ // of `RawBuffer' here.
+ staticBuffer = new NIOBuffer(capacity);
+ freed = false ;
+ }
+
+ public int offset() {
+ return bufoffset ;
+ }
+
+ /**
+ * Creates a buffer with specified rawbuffer, and staring
+ * at the offset specified. Encoding given by
+ * <tt>java.nio.ByteOrder.nativeEncoding()</tt>.
+ * When created the buffer is not necessarily empty, but
+ * is in a writeable state.
+ * This constructor supports the Buffered mode of send at the higher
+ * level.
+ * @param buffer Rawbuffer
+ * @param offset the starting offset of this buffer
+ * need level argument ...
+ * public access required for bsend object is made in BasicType.java
+ * in 'createWriteBuffer' method.
+ */
+ public Buffer(RawBuffer buffer, int bufoffset, int capacity) {
+
+ encoding = localEncoding;
+
+ currentSectionType = null;
+ writeable = true;
+
+ staticBuffer = buffer;
+ freed = false;
+ this.bufoffset = bufoffset;
+ //this.offset = offset ;
+ this.capacity = capacity;
+ }
+
+ /* not well thought ..instead of sending bits n pieces of Buffer,
+ * why not just send the reference of buffer itself and then
+ * figure out things within this method like geting the reference
+ * of static buffer and dynamic buffer
+ */
+ public void copy(ByteBuffer srcStaticBuffer, int srcOffset,
+ int staticBufferLength, int dstOffset,
+ byte[] srcDynamicBuffer, int dynamicBufferLength) {
+
+ staticBuffer.copy(srcStaticBuffer, srcOffset,
+ staticBufferLength,
+ dstOffset) ;
+
+ setSize( staticBufferLength ) ;
+
+ if(dynamicBufferLength > 0) {
+ setDynamicBuffer( srcDynamicBuffer) ;
+ }
+
+ }
+
+ /**
+ * Free resources associated with this buffer. The only
+ * method invocations allowed on the buffer instance after this
+ * method has been called are further calls to <tt>free()</tt>
+ * or {\@link #finalize() finalize()}, none of which have any effect
+ * after the first invocation.
+ */
+ public void free() {
+
+ if(!freed) {
+
+ closeObjectStreams() ;
+
+ dynamicBuffer = null ;
+
+ staticBuffer.free() ;
+
+ freed = true ;
+ }
+ }
+
+ /**
+ * Freeze buffer, putting it into a readable state, and setting the
+ * read pointer to the start of the buffer. This method can
+ * also be used to "rewind" a buffer that is already in readable
+ * state.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * saving the state of the dynamic buffer.
+ * \@throws WrongStateException if buffer has already been freed.
+ */
+ public void commit() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+ // Save size of last section to buffer.
+ if(currentSectionType != null) {
+ staticBuffer.putInt(sectionSize, sectionHeader+4+bufoffset ) ;
+ }
+
+ if (out != null) {
+ try {
+ out.flush() ;
+ dynamicBuffer = byteOut.toByteArray();
+ //System.out.println(" length ="+dynamicBuffer.length) ;
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ closeObjectStreams() ;
+
+ currentSectionType = null ;
+ readPtr = 0 ;
+ elementsRemaining = 0 ;
+
+ writeable = false ;
+ }
+
+ /**
+ * Empty the buffer and put it in a writeable state.
+ * \@throws WrongStateException if buffer has already been freed.
+ */
+ public void clear() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ closeObjectStreams() ;
+
+ encoding = localEncoding ;
+
+ currentSectionType = null ;
+ size = 0 ;
+ sectionHeader = 0 ;
+
+ dynamicBuffer = null ;
+
+ writeable = true ;
+ }
+
+ private void closeObjectStreams() {
+
+ if (in != null) {
+ try {
+ in.close();
+ in = null;
+ } catch(IOException e){
+ // IO error should not occur when we close
+ // byte array inputstream.
+ }
+ }
+
+ if (out != null) {
+ try {
+ out.close() ;
+ out = null ;
+ byteOut = null ;
+ } catch (IOException e){
+ // IO error should not occur when we close
+ // byte array inputstream.
+ }
+ }
+ }
+
+ /**
+ * Start a new section in the buffer: write a section header to
+ * the buffer and make the new section the current section.
+ * The header requires
+ * {\@link #SECTION_OVERHEAD SECTION_OVERHEAD}
+ * bytes of static buffer capacity.
+ * Any preceding section will be padded with the minimum
+ * number of bytes necessary to ensure that the new section starts on
+ * a boundary that is a multiple of
+ * {\@link #ALIGNMENT_UNIT ALIGNMENT_UNIT} bytes.
+ * This may require up to <tt>ALIGNMENT_UNIT - 1</tt> bytes of
+ * additional buffer capacity.
+ * \@param type the type of this section. One of
+ * {\@link Type#BYTE BYTE},
+ * {\@link Type#CHAR CHAR},
+ * {\@link Type#SHORT SHORT},
+ * {\@link Type#BOOLEAN BOOLEAN},
+ * {\@link Type#INT INT},
+ * {\@link Type#LONG LONG},
+ * {\@link Type#FLOAT FLOAT}, or
+ * {\@link Type#DOUBLE DOUBLE}, if this is a static section, or one of
+ * {\@link Type#OBJECT OBJECT},
+ * {\@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {\@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {\@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {\@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {\@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {\@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {\@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {\@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}
+ * if this is a dynamic section.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or buffer has already been freed.
+ * \@throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ */
+ public void putSectionHeader(Type type) throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ // Save size of previous section to buffer.
+ if(currentSectionType != null) {
+ staticBuffer.putInt(sectionSize, bufoffset+sectionHeader + 4) ;
+ }
+
+ int newSectionHeader = ALIGNMENT_UNIT *
+ ((size + ALIGNMENT_UNIT - 1) / ALIGNMENT_UNIT) ;
+ // Round up to multiple of ALIGNMENT_UNIT.
+
+ int newSize = newSectionHeader + SECTION_OVERHEAD ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for new section header.") ;
+
+ staticBuffer.putByte(type.getCode() , newSectionHeader + bufoffset) ;
+
+ size = newSize ;
+ sectionHeader = newSectionHeader ;
+ currentSectionType = type ;
+ sectionSize = 0 ;
+ }
+
+ /**
+ * Read a section header from the buffer,
+ * and make this the current section.
+ * \@return the type of the expected section. One of
+ * {\@link Type#BYTE BYTE},
+ * {\@link Type#CHAR CHAR},
+ * {\@link Type#SHORT SHORT},
+ * {\@link Type#BOOLEAN BOOLEAN},
+ * {\@link Type#INT INT},
+ * {\@link Type#LONG LONG},
+ * {\@link Type#FLOAT FLOAT},
+ * {\@link Type#DOUBLE DOUBLE},
+ * {\@link Type#OBJECT OBJECT},
+ * {\@link Type#BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {\@link Type#CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {\@link Type#SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {\@link Type#BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {\@link Type#INT_DYNAMIC INT_DYNAMIC},
+ * {\@link Type#LONG_DYNAMIC LONG_DYNAMIC},
+ * {\@link Type#FLOAT_DYNAMIC FLOAT_DYNAMIC}, or
+ * {\@link Type#DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or buffer has already been freed.
+ * \@throws TypeMismatchException if the value of the type
+ * parameter does not precisely match the value specified when the
+ * section was originally created by {\@link #putSectionHeader(Type)
+ * putSectionHeader()}.
+ * \@throws SectionSizeMismatchException if there are elements remaining
+ * to be read in the previous section.
+ * \@throws BufferUnderflowException if there there are no more
+ * sections remaining to be read in the buffer.
+ */
+ public Type getSectionHeader() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(elementsRemaining != 0)
+ throw new SectionSizeMismatchException("Previous " +
+ "section was not completely read.") ;
+
+ int headerStart = 8 * ((readPtr + 7) / 8) ;
+ // Round up to multiple of 8.
+ // System.out.println("headerStart = "+headerStart+" bufoffset = "+bufoffset);
+ int newReadPtr = headerStart + SECTION_OVERHEAD ;
+
+ if(newReadPtr > size) {
+ throw new BufferUnderflowException("Trying to read " +
+ "past end of buffer. < newReadPtr > size > "+newReadPtr+" > "+size) ;
+ }
+
+ int typeCode = staticBuffer.getByte(headerStart+bufoffset) ;
+ sectionSize = staticBuffer.getInt(headerStart + 4 +bufoffset,
+ encoding != localEncoding) ;
+ // System.out.println("typeCode = "+typeCode+" sectionSize = "+sectionSize);
+ readPtr = newReadPtr ;
+ currentSectionType = Type.getType(typeCode) ;
+ elementsRemaining = sectionSize ;
+
+ return currentSectionType ;
+ }
+
+ /**
+ * Size of current section.
+ * If buffer is currently readable, return value is fixed for this section.
+ * If buffer is currently writable, return value is number of elements
+ * written to this section so far.
+ * \@return number of elements in this section.
+ * \@throws WrongStateException if current section is undefined,
+ * or buffer has already been freed.
+ */
+ public int getSectionSize() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'getSectionHeader\' or \'putSectionHeader\'") ;
+
+ return sectionSize ;
+ }
+
+ /**
+ * Returns number of elements remaining to be read in the current
+ * section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or buffer has already been freed.
+ */
+ public int getRemaining() throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ return elementsRemaining ;
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $Type = $pTypes [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append <tt>numEls</tt> consecutive $type elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer. If the current section
+ * is a static section this requires $size * numEls
+ * units of static buffer capacity.
+ * \@param source the $type array from which data is taken.
+ * \@param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * \@param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write($type [] source, int srcOff, int numEls)
+ throws BufferException {
+ //System.out.println("Reaching in the write method");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType == Type.$TYPE) {
+
+ int newSize = size + $size * numEls ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.write(source, srcOff, numEls, size+bufoffset) ;
+
+ sectionSize += numEls ;
+ size = newSize ;
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.write${Type}(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append <tt>numEls</tt> consecutive Object elements from array
+ * <tt>source</tt>, starting at index <tt>srcOff</tt>,
+ * to the current section of buffer.
+ * \@param source the Object array from which data is taken.
+ * \@param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * \@param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>srcOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void write(Object [] source, int srcOff, int numEls)
+ throws BufferException {
+
+ //System.out.println("Reaching in the write method2");
+ writeCheckArgs(source.length, srcOff, numEls) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section, or missing call to \'putSectionHeader\'") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.writeObject(source[srcOff + i]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `write()' methods.
+ */
+ private void writeCheckArgs(int sourceLen, int srcOff, int numEls)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'putSectionHeader\'") ;
+
+ if(srcOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + srcOff) ;
+
+ if(srcOff + numEls > sourceLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + (srcOff + numEls - 1)) ;
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $Type = $pTypes [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append <tt>numEls</tt> selected $type elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {\@link mpjbuf.Buffer class description} for further details.
+ * If the current section of the buffer
+ * is a static section this requires $size * numEls
+ * units of static buffer capacity.
+ * \@param source the $type array from which data is taken.
+ * \@param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * \@param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * \@param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather($type [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.$TYPE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(source == null)
+ throw new NullPointerException("null") ;
+
+ if(size + $size * numEls > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ int transfered =
+ staticBuffer.gather(source, numEls, idxOff, indexes,
+ size+bufoffset) ;
+
+ size += $size * transfered ;
+ sectionSize += transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ out.write${Type}(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append <tt>numEls</tt> selected Object elements from array
+ * <tt>source</tt> to the current section of buffer.
+ * The elements copied from <tt>source</tt> are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {\@link mpjbuf.Buffer class description} for further details.
+ * \@param source the Object array from which data is taken.
+ * \@param numEls the total number of elements to be copied from
+ * <tt>source</tt>
+ * \@param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * \@param indexes an int array containing subscripts into
+ * <tt>source</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void gather(Object [] source,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ gatherCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+ out.writeObject(source[indexes[idxOff + i]]);
+ sectionSize++ ;
+ }
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `gather()' methods.
+ */
+ private void gatherCheckArgs(int numEls, int idxOff, int indexesLen)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'putSectionHeader\'") ;
+
+ if(idxOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + idxOff) ;
+
+ if(idxOff + numEls > indexesLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + (idxOff + numEls - 1)) ;
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $Type = $pTypes [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append selected $type elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {\@link mpjbuf.Buffer class description} for details.
+ * If the current section of the buffer
+ * is a static section this requires $size * <i>volume</i>
+ * units of static buffer capacity, where <i>volume</i>
+ * is the product of the extents of the specified region.
+ * \@param source the $type array from which data is taken.
+ * \@param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * \@param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * \@param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * \@param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * \@param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws BufferOverflowException if there is insufficient space
+ * left in the static buffer.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws IllegalArgumentException if the specified rank is negative.
+ * \@throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather($type [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.$TYPE) {
+ if(volume != 0) {
+ int newSize = size + $size * volume ;
+ if(newSize > staticBuffer.getCapacity())
+ throw new BufferOverflowException("Buffer capacity " +
+ "too small for attempted write.") ;
+
+ staticBuffer.strGather(source, srcOff,
+ rank, exts, strs, shape,
+ size+bufoffset) ;
+
+ sectionSize += volume ;
+ size = newSize ;
+ }
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+ private void doStrGather($type [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.write${Type}(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Append selected $type elements from a multistrided region of array
+ * <tt>source</tt> to the current section of buffer.
+ * See {\@link mpjbuf.Buffer class description} for details.
+ * \@param source the $type array from which data is taken.
+ * \@param srcOff the subscript of the first element in the
+ * <tt>source</tt> array that is to be copied.
+ * \@param rank the rank or dimensionality of the region to
+ * be copied from <tt>source</tt>
+ * \@param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * \@param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * \@param shape an int array holding extent and stride information
+ * for the region to be copied from <tt>source</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws WrongStateException if buffer is not in a writeable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws IllegalArgumentException if the specified rank is negative.
+ * \@throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>source</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * writing to the dynamic buffer.
+ */
+ public void strGather(Object [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strGatherCheckArgs(source.length, srcOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (out == null){
+ byteOut = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(byteOut);
+ }
+
+ doStrGather(source, srcOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem writing " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ private void doStrGather(Object [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ out.writeObject(source[srcOff]);
+ sectionSize++ ;
+ }
+ else{
+ int str = shape[strs];
+ for (int i = 0; i < shape[exts]; i++)
+ doStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `strGather()' methods.
+ */
+ private int strGatherCheckArgs(int sourceLen, int srcOff, int rank,
+ int exts, int strs, int [] shape)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(!writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a writeable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'putSectionHeader\'") ;
+
+ if(rank < 0)
+ throw new mpjbuf.IllegalArgumentException("Negative rank " +
+ "specified") ;
+
+ int minIndex = srcOff, maxIndex = srcOff ;
+ int volume = 1;
+
+ for (int i = 0; i < rank; i++) {
+
+ int ext = shape [exts + i] ;
+ int str = shape [strs + i] ;
+
+ if (ext < 0)
+ throw new ArrayIndexOutOfBoundsException("Patch has " +
+ "negative extent.") ;
+
+ if (ext == 0)
+ return 0 ;
+
+ if (str < 0)
+ minIndex += str * (ext - 1);
+ else
+ maxIndex += str * (ext - 1);
+
+ volume *= ext ;
+ }
+
+ if(minIndex < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + minIndex) ;
+
+ if(maxIndex >= sourceLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in source array: " + maxIndex) ;
+
+ return volume ;
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $Type = $pTypes [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read the next <tt>numEls</tt> $type items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * \@param dest the $type array to which data will be written.
+ * \@param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * \@param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+
+ public void read($type [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType == Type.$TYPE) {
+
+ staticBuffer.read(dest, dstOff, numEls, readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += $size * numEls ;
+ elementsRemaining -= numEls ;
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (in == null) {
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0; i < numEls; i++) {
+ dest[dstOff + i] = in.read${Type}();
+ elementsRemaining-- ;
+ }
+
+ } catch(IOException e) {
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section.") ;
+ }
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read the next <tt>numEls</tt> Object items from the current section
+ * of the buffer, and write them to consecutive elements of the array
+ * <tt>dest</tt>, starting at index <tt>dstOff</tt>.
+ * \@param dest the Object array to which data will be written.
+ * \@param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * \@param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>dstOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void read(Object [] dest, int dstOff, int numEls)
+ throws BufferException {
+
+ readCheckArgs(dest.length, dstOff, numEls) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section, or missing call to \'getSectionHeader\'") ;
+
+ try {
+ if (inn == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+ Object obj;
+ for (int i = 0; i < numEls; i++) {
+ obj = in.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(ClassNotFoundException ce){
+
+ //throw new DynamicBufferException("Problem reading " +
+ // "dynamic buffer", e) ;
+
+ try {
+ ByteArrayInputStream o = new ByteArrayInputStream(dynamicBuffer);
+ inn = new CustomObjectInputStream(o);
+ for (int i = 0; i < numEls; i++) {
+ Object obj =inn.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(Exception ioe){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", ioe) ;
+ }
+
+ }
+ catch(Exception e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `read()' methods.
+ */
+ private void readCheckArgs(int destLen, int dstOff, int numEls)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'getSectionHeader\'") ;
+
+ if(dstOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + dstOff) ;
+
+ if(dstOff + numEls > destLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + (dstOff + numEls - 1)) ;
+
+ if(numEls > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $Type = $pTypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read the next <tt>numEls</tt> $type items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {\@link mpjbuf.Buffer class description} for further details.
+ * \@param dest the $type array to which data will be written.
+ * \@param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * \@param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * \@param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void scatter($type [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType == Type.$TYPE) {
+
+ // Convenient to do explicit check before we go into native code.
+ if(dest == null)
+ throw new NullPointerException("null") ;
+
+ int transfered =
+ staticBuffer.scatter(dest, numEls, idxOff, indexes,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += $size * transfered ;
+ elementsRemaining -= transfered ;
+
+ if(transfered < numEls) {
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + indexes [idxOff + transfered]) ;
+ // Only reason this can happen.
+ }
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls; i++) {
+
+ // `read${Type}()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.read${Type}();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read the next <tt>numEls</tt> Object items from the current section
+ * of the buffer, and write them to selected elements of the array
+ * <tt>dest</tt>.
+ * The elements of <tt>dest</tt> to which data is copied are selected
+ * by subscripts taken from <tt>numEls</tt> consecutive
+ * elements of the array <tt>indexes</tt>, starting
+ * at index <tt>idxOff</tt> in the latter array.
+ * See {\@link mpjbuf.Buffer class description} for further details.
+ * \@param dest the Object array to which data will be written.
+ * \@param numEls the total number of items to be copied from
+ * the buffer to elements of <tt>dest</tt>.
+ * \@param idxOff the subscript of the first element in the array
+ * <tt>indexes</tt> to be used as an index into <tt>source</tt>.
+ * \@param indexes an int array containing subscripts into
+ * <tt>dest</tt>.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws ArrayIndexOutOfBoundsException if the specified
+ * combination of <tt>idxOff</tt> and <tt>numEls</tt> would imply
+ * access to elements outside the bounds of <tt>indexes</tt>,
+ * or if a selected element of <tt>indexes</tt> requires access
+ * to an element outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void scatter(Object [] dest,
+ int numEls, int idxOff, int [] indexes)
+ throws BufferException {
+
+ scatterCheckArgs(numEls, idxOff, indexes.length) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ for (int i = 0 ; i < numEls ; i++) {
+
+ // `readObject()' must not occur if LHS raises exception.
+
+ int idx = indexes[idxOff + i] ;
+ if(idx >= 0 && idx < dest.length) {
+ dest[idx] = in.readObject();
+ elementsRemaining-- ;
+ }
+ else
+ throw new ArrayIndexOutOfBoundsException("Out of " +
+ "bounds in dest array: " + idx) ;
+ }
+
+ }
+ catch(IOException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ catch(ClassNotFoundException e){
+
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `scatter()' methods.
+ */
+ private void scatterCheckArgs(int numEls, int idxOff, int indexesLen)
+ throws BufferException {
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(currentSectionType == null)
+ throw new WrongStateException("Missing call to " +
+ "\'getSectionHeader\'") ;
+
+ if(numEls > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+
+ if(idxOff < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + idxOff) ;
+
+ if(idxOff + numEls > indexesLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in indexes array: " + (idxOff + numEls - 1)) ;
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+ $TYPE = $pTYPEs [$i] ;
+ $Type = $pTypes [$i] ;
+ $size = $psizes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read $type items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {\@link mpjbuf.Buffer class description} for details.
+ * \@param dest the $type array to which data will be written.
+ * \@param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * \@param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * \@param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * \@param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * \@param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#$TYPE $TYPE} or
+ * {\@link Type#${TYPE}_DYNAMIC ${TYPE}_DYNAMIC}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws IllegalArgumentException if the specified rank is negative.
+ * \@throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are unforseen problems
+ * reading the dynamic buffer.
+ */
+ public void strScatter($type [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ int volume = strScatterCheckArgs(dest.length, dstOff,
+ rank, exts, strs, shape) ;
+
+ if(currentSectionType == Type.$TYPE) {
+ if(volume != 0) {
+
+ staticBuffer.strScatter(dest, dstOff, rank, exts, strs, shape,
+ readPtr+bufoffset,
+ encoding != localEncoding) ;
+
+ readPtr += $size * volume ;
+ elementsRemaining -= volume ;
+ }
+ }
+ else if(currentSectionType == Type.${TYPE}_DYNAMIC) {
+
+ try {
+ if (in == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+
+ } catch(IOException e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+ else {
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+ }
+ }
+
+ private void doStrScatter($type [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.read${Type}();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /**
+ * Read Object items from the current section of the buffer,
+ * and write them to a multistrided region of the array <tt>dest</tt>.
+ * See {\@link mpjbuf.Buffer class description} for details.
+ * \@param dest the Object array to which data will be written.
+ * \@param dstOff the subscript of the first element in the
+ * <tt>dest</tt> array that will be overwritten.
+ * \@param rank the rank or dimensionality of the region in
+ * <tt>dest</tt> to which data is to be copied.
+ * \@param exts the offset in the <tt>shape</tt> array of
+ * the first of rank extents.
+ * \@param strs the offset in the <tt>shape</tt> array of
+ * the first of rank strides.
+ * \@param shape an int array holding extent and stride information
+ * for the region in <tt>dest</tt> to which data is to be copied.
+ * \@throws TypeMismatchException if the current section was not
+ * created with type {\@link Type#OBJECT OBJECT}.
+ * \@throws SectionSizeMismatchException if this operation
+ * would imply reading past the end of the current section.
+ * \@throws WrongStateException if buffer is not in a readable state,
+ * or the current section is undefined, or the buffer has already been
+ * freed.
+ * \@throws IllegalArgumentException if the specified rank is negative.
+ * \@throws ArrayIndexOutOfBoundsException if the values of <tt>rank</tt>
+ * and <tt>exts</tt> and <tt>strs</tt> would imply
+ * access to elements outside the bounds of <tt>shape</tt>, or
+ * if the region defined by the resulting extents and strides would
+ * imply access to elements outside the bounds of <tt>dest</tt>.
+ * \@throws DynamicBufferException if there are problems
+ * reading objects from the dynamic buffer.
+ */
+ public void strScatter(Object [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws BufferException {
+
+ strScatterCheckArgs(dest.length, dstOff, rank, exts, strs, shape) ;
+
+ if(currentSectionType != Type.OBJECT)
+ throw new TypeMismatchException("Wrong type for current " +
+ "section") ;
+
+ try {
+ if (inn == null){
+ ByteArrayInputStream o =
+ new ByteArrayInputStream(dynamicBuffer);
+ in = new ObjectInputStream(o);
+ }
+
+ doStrScatter(dest, dstOff, rank, exts, strs, shape);
+ }
+ catch(ClassNotFoundException e){
+
+ //throw new DynamicBufferException("Problem reading " +
+ // "dynamic buffer", e) ;
+ try{
+ ByteArrayInputStream o = new ByteArrayInputStream(dynamicBuffer);
+ inn = new CustomObjectInputStream(o);
+ for (int i = 0; i < strs; i++) {
+ Object obj =inn.readObject();
+ dest[dstOff + i] = obj;
+ elementsRemaining-- ;
+ }
+ }
+ catch(Exception ioe){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", ioe) ;
+ }
+ }
+ catch(Exception e){
+ throw new DynamicBufferException("Problem reading " +
+ "dynamic buffer", e) ;
+ }
+ }
+
+ private void doStrScatter(Object [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape)
+ throws IOException, ClassNotFoundException {
+
+ if (rank == 0) {
+ dest[dstOff] = in.readObject();
+ elementsRemaining-- ;
+ }
+ else {
+ for (int i = 0; i < shape[exts]; i++)
+ doStrScatter(dest, dstOff + shape[strs] * i,
+ rank - 1, exts + 1, strs + 1, shape);
+ }
+ }
+
+ /*
+ * Common argument sanity checks for `strScatter()' methods.
+ */
+ private int strScatterCheckArgs(int destLen, int dstOff, int rank,
+ int exts, int strs, int [] shape)
+ throws BufferException {
+
+ // Also implicitly checks that `shape' != null,
+ // and `shape' subscripts in range.
+
+ if(freed)
+ throw new WrongStateException("Buffer has already been freed.") ;
+
+ if(writeable)
+ throw new WrongStateException("Buffer is not in " +
+ "a readable state.") ;
+
+ if(rank < 0)
+ throw new mpjbuf.IllegalArgumentException("Negative rank" +
+ " specified") ;
+
+ if(currentSectionType == null)
+ throw new TypeMismatchException("Missing call to " +
+ "\'getSectionHeader\'") ;
+
+ int minIndex = dstOff, maxIndex = dstOff ;
+ int volume = 1;
+
+ for (int i = 0; i < rank; i++) {
+
+ int ext = shape [exts + i] ;
+ int str = shape [strs + i] ;
+
+ if (ext < 0)
+ throw new ArrayIndexOutOfBoundsException("Patch has " +
+ "negative extent.") ;
+
+ if (ext == 0)
+ return 0 ;
+
+ if (str < 0)
+ minIndex += str * (ext - 1);
+ else
+ maxIndex += str * (ext - 1);
+
+ volume *= ext ;
+ }
+
+ if(minIndex < 0)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + minIndex) ;
+
+ if(maxIndex >= destLen)
+ throw new ArrayIndexOutOfBoundsException("Out of bounds " +
+ "in dest array: " + maxIndex) ;
+
+ if(volume > elementsRemaining)
+ throw new SectionSizeMismatchException("Trying to read past " +
+ "end of current section.") ;
+
+ return volume ;
+ }
+
+
+ // Low-level methods used for sending and receiving the buffer.
+
+ /**
+ * Returns a representation of the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public RawBuffer getStaticBuffer() {
+ return staticBuffer ;
+ }
+
+ /**
+ * Set representation of the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setStaticBuffer(RawBuffer staticBuffer) {
+ this.staticBuffer = staticBuffer ;
+ }
+
+ /**
+ * Returns encoding of numeric data in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public ByteOrder getEncoding() {
+ return encoding ;
+ }
+
+ /**
+ * Set encoding of numeric data in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setEncoding(ByteOrder encoding) {
+ //not sure if we need it ...? aamir.
+ if(staticBuffer instanceof NIOBuffer) {
+ ((NIOBuffer) staticBuffer).setEncoding(encoding);
+ }
+ this.encoding = encoding ;
+ }
+
+ /**
+ * Get total number of bytes of data currently in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public int getSize() {
+ return size ;
+ }
+
+ /**
+ * Set total number of bytes of data currently in the static buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public void setSize(int size) {
+ this.size = size ;
+ }
+ /**
+ * Get total number of bytes -- capacity of the static buffer.
+ * Low-level method used for in native device for receiving the buffer.
+ */
+ public int getCapacity() {
+ return capacity ;
+ }
+ /**
+ * Get bytes of the dynamic buffer.
+ * Low-level method used for sending and receiving the buffer.
+ * Only use this on a commited (readable) buffer.
+ */
+ public byte [] getDynamicBuffer() {
+
+ // Note return value may not be up to date if the buffer
+ // has not been commited.
+
+ return dynamicBuffer ;
+ }
+
+ /**
+ * Set bytes of the dynamic buffer.
+ * Low-level method used for sending and receiving the buffer.
+ * Buffer should be empty prior to this call.
+ */
+ public void setDynamicBuffer(byte [] dynamicBuffer) {
+
+ // Note if buffer is not empty, `out' may not be `null'.
+ // This may result in the new value of `dynamicBuffer' being
+ // overwritten if, for example, there is a subsequent call
+ // `commit()'.
+
+ this.dynamicBuffer = dynamicBuffer ;
+ }
+
+ /**
+ * Determine read-write mode of buffer.
+ * Low-level method used for sending and receiving the buffer.
+ */
+ public boolean isWritable() {
+ return writeable ;
+ }
+}
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+# To do:
+#
+# 1) Introduce string constants for error messages.
+#
diff --git a/src/mpjbuf/BufferConstants.java b/src/mpjbuf/BufferConstants.java
new file mode 100644
index 0000000..084a324
--- /dev/null
+++ b/src/mpjbuf/BufferConstants.java
@@ -0,0 +1,35 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : BufferConstants.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.4 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+package mpjbuf ;
+
+public class BufferConstants {
+ static int DEFAULT_REGION_SIZE = 8 * 1024 * 1024 ;
+ static int CHUNK_SIZE = 128 ;
+ static int INIT_NUM_LEVELS = 17 ;
+ static final int NULL = -1 ;
+ static final int PREV = 1;
+ static final int NEXT = 5;
+ static final byte ALLOCATED = -1;
+}
diff --git a/src/mpjbuf/BufferException.java b/src/mpjbuf/BufferException.java
new file mode 100644
index 0000000..886ba57
--- /dev/null
+++ b/src/mpjbuf/BufferException.java
@@ -0,0 +1,58 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BufferException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Thu Jul 8 13:33:13 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class BufferException
+ extends Exception {
+
+ public BufferException() {
+
+ super();
+ }
+
+ public BufferException(String s) {
+
+ super(s);
+ }
+
+ public BufferException(String s, Throwable cause) {
+
+ super(s, cause);
+ }
+}
diff --git a/src/mpjbuf/BufferFactory.java b/src/mpjbuf/BufferFactory.java
new file mode 100644
index 0000000..1f98436
--- /dev/null
+++ b/src/mpjbuf/BufferFactory.java
@@ -0,0 +1,121 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : BufferFactory.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat July 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.13 $
+ * Updated : $Date: 2005/08/12 19:12:25 $
+ *
+ */
+package mpjbuf ;
+import mpi.MPIException ;
+
+public abstract class BufferFactory {
+
+ static BufferFactory factory ;
+
+ static {
+ init("Buddy1") ;
+ }
+
+ /**
+ * Initialize BufferFactory.
+ * @param str The current options are 'Buddy1' and 'Buddy2'
+ */
+ public static void init (String str) {
+
+ if(str.equals("Buddy1")) {
+ if(factory == null) {
+ factory = new Buddy1BufferFactory() ;
+ factory.init() ;
+ }
+ else {
+ System.out.println(" attempt to initialize bufferFactory again" +
+ " with strategy represented by string <"+str+">");
+ }
+ }
+ else if(str.equals("Buddy2")) {
+ if(factory == null) {
+ factory = new Buddy2BufferFactory() ;
+ factory.init() ;
+ }
+ else {
+ System.out.println(" attempt to initialize bufferFactory again" +
+ " with strategy represented by string <"+str+">");
+ }
+ }
+ else {
+ throw new MPIException (" No matching buffering strategy for <"+
+ str+">");
+ }
+
+ }
+
+ /**
+ * Create a buffer
+ * @param size Size of the buffer in bytes. The user need to care
+ * about headers and all that kind of stuff ..
+ */
+ public static mpjbuf.RawBuffer create(int size) {
+ if(factory != null) {
+ return factory.createBuffer( size );
+ }
+ else {
+ throw new MPIException("BufferFactory has not been initialized") ;
+ }
+ }
+
+ /**
+ * Destroy the buffer and add it back to factory
+ * @param buffer RawBuffer object.
+ */
+ public static void destroy(mpjbuf.RawBuffer buffer) {
+ if(factory != null) {
+ factory.destroyBuffer( buffer );
+ } else {
+ throw new MPIException("BufferFactory has not been initialized") ;
+ }
+ }
+
+ public static boolean initialized() {
+ if(factory != null) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Finalize factory ...not important to call ..but if you do that's
+ * great. This is re-entrant so xdev/mpjdev/mpi packages can call it
+ * without any detrimental effect.
+ */
+ public static void shut () {
+ if(factory != null) {
+ factory.finalixe();
+ }
+ factory = null ;
+ }
+
+ public abstract void init() ;
+ public abstract void finalixe() ;
+ public abstract void destroyBuffer(mpjbuf.RawBuffer buffer) ;
+ public abstract mpjbuf.RawBuffer createBuffer(int size) ;
+
+}
diff --git a/src/mpjbuf/BufferOverflowException.java b/src/mpjbuf/BufferOverflowException.java
new file mode 100644
index 0000000..26e95c8
--- /dev/null
+++ b/src/mpjbuf/BufferOverflowException.java
@@ -0,0 +1,39 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BufferOverflowException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Thu Jul 8 13:33:13 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class BufferOverflowException
+ extends BufferException {
+
+ public BufferOverflowException() {
+
+ super();
+ }
+
+ public BufferOverflowException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/BufferUnderflowException.java b/src/mpjbuf/BufferUnderflowException.java
new file mode 100644
index 0000000..4f40b4c
--- /dev/null
+++ b/src/mpjbuf/BufferUnderflowException.java
@@ -0,0 +1,53 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : BufferUnderflowException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Thu Jul 8 13:33:13 EST 2005
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class BufferUnderflowException
+ extends BufferException {
+
+ public BufferUnderflowException() {
+
+ super();
+ }
+
+ public BufferUnderflowException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/CustomMath.java b/src/mpjbuf/CustomMath.java
new file mode 100644
index 0000000..4f2a817
--- /dev/null
+++ b/src/mpjbuf/CustomMath.java
@@ -0,0 +1,212 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/*
+ * File : CustomMath.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2005
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+package mpjbuf;
+
+/**
+ * A class that helps calculate natural log
+ * @author Dirk Bosmans Dirk.Bosmans at tijd.com
+ */
+public class CustomMath {
+
+/**
+* natural log method.
+* Calculate how many bits wide a number is,
+* i.e. position of highest 1 bit.
+* @return p where 2**p is first power of two >= n.
+* e.g. binary 0001_0101 -> 5, 0xffffffff -> 32,
+* 0 -> 0, 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 3
+*/
+static public int widthInBits1(int n )
+ {
+ if ( n < 0 )
+ {
+ return 32;
+ }
+ if ( n > 0x3fffffff )
+ {
+ return 31;
+ }
+ return(int)Math.ceil( Math.log( n+1 ) * invln2 );
+ } // end widthInBits1
+
+private static double invln2 = 1.0 / Math.log(2.0);
+
+/**
+* Calculate how many bits wide a number is,
+* i.e. position of highest 1 bit.
+* Fully unraveled binary search method.
+* @return p where 2**p is first power of two >= n.
+* e.g. binary 0001_0101 -> 5, 0xffffffff -> 32,
+* 0 -> 0, 1 -> 1, 2 -> 2, 3 -> 2, 4 -> 3 */
+static public final int widthInBits( int n )
+ {
+ if ( n < 0 ) return 32;
+ if ( n > 0x0000ffff )
+ {
+ if ( n > 0x00ffffff )
+ {
+ if ( n > 0x0fffffff )
+ {
+ if ( n > 0x3fffffff )
+ {
+ // if ( n > 0x7fffffff )
+ // return 32
+ // else
+ return 31;
+ }
+ else
+ {
+ // !( n > 0x3fffffff )
+ if ( n > 0x1fffffff ) return 30;
+ else return 29;
+ }
+ }
+ else
+ {
+ // !( n > 0x0fffffff )
+ if ( n > 0x03ffffff )
+ {
+ if ( n > 0x07ffffff ) return 28;
+ else return 27;
+ }
+ else
+ {
+ // !( n > 0x03ffffff )
+ if ( n > 0x01ffffff ) return 26;
+ else return 25;
+ }
+ }
+ }
+ else
+ {
+ // !( n > 0x00ffffff )
+ if ( n > 0x000fffff )
+ {
+ if ( n > 0x003fffff )
+ {
+ if ( n > 0x007fffff ) return 24;
+ else return 23;
+ }
+ else
+ {
+ // !( n > 0x003fffff )
+ if ( n > 0x001fffff ) return 22;
+ else return 21;
+ }
+ }
+ else
+ {
+ // !( n > 0x000fffff )
+ if ( n > 0x0003ffff )
+ {
+ if ( n > 0x0007ffff ) return 20;
+ else return 19;
+ }
+ else
+ {
+ // !( n > 0x0003ffff )
+ if ( n > 0x0001ffff ) return 18;
+ else return 17;
+ }
+ }
+ }
+ }
+ else
+ {
+ // !( n > 0x0000ffff )
+ if ( n > 0x000000ff )
+ {
+ if ( n > 0x00000fff )
+ {
+ if ( n > 0x00003fff )
+ {
+ if ( n > 0x00007fff ) return 16;
+ else return 15;
+ }
+ else
+ {
+ // !( n > 0x00003fff )
+ if ( n > 0x00001fff ) return 14;
+ else return 13;
+ }
+ }
+ else
+ {
+ // !( n > 0x00000fff )
+ if ( n > 0x000003ff )
+ {
+ if ( n > 0x000007ff ) return 12;
+ else return 11;
+ }
+ else
+ {
+ // !( n > 0x000003ff )
+ if ( n > 0x000001ff ) return 10;
+ else return 9;
+ }
+ }
+ }
+ else
+ {
+ // !( n > 0x000000ff )
+ if ( n > 0x0000000f )
+ {
+ if ( n > 0x0000003f )
+ {
+ if ( n > 0x0000007f ) return 8;
+ else return 7;
+ }
+ else
+ {
+ // !( n > 0x0000003f )
+ if ( n > 0x0000001f ) return 6;
+ else return 5;
+ }
+ }
+ else
+ {
+ // !( n > 0x0000000f )
+ if ( n > 0x00000003 )
+ {
+ if ( n > 0x00000007 ) return 4;
+ else return 3;
+ }
+ else
+ {
+ // !( n > 0x00000003 )
+ if ( n > 0x00000001 ) return 2;
+ return n;
+ /*
+ else if ( n > 0x00000000 )
+ return 1;
+ else
+ return 0;
+ */
+ }
+ }
+ }
+ }
+ } // end widthInBits
+}
diff --git a/src/mpjbuf/CustomObjectInputStream.java b/src/mpjbuf/CustomObjectInputStream.java
new file mode 100644
index 0000000..fd23176
--- /dev/null
+++ b/src/mpjbuf/CustomObjectInputStream.java
@@ -0,0 +1,56 @@
+/*
+
+/*
+ * File : Type.java
+ * Author : Jawad Manzoor
+ * Created : Tue Jul 21 2004
+ * Revision :
+ * Updated : $Date: 2009/07/21
+ *
+ */
+package mpjbuf;
+
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamClass;
+import java.net.URLClassLoader;
+
+public class CustomObjectInputStream extends ObjectInputStream {
+
+
+ URLClassLoader urlCl;
+
+ protected CustomObjectInputStream() throws IOException {
+ }
+
+ public CustomObjectInputStream(InputStream in) throws IOException {
+ super(in);
+ }
+
+ public void setClassLoader(URLClassLoader ucl){
+ urlCl = ucl;
+ }
+
+
+ @Override
+ public Class resolveClass(ObjectStreamClass desc) throws IOException {
+
+ String name = desc.getName();
+ try {
+ URLClassLoader u = (URLClassLoader)Thread.currentThread().getContextClassLoader();
+ // System.out.println("CL "+u.toString());
+ return Class.forName(name, false, u);
+ } catch (ClassNotFoundException ex) {
+ /* Class cl = (Class) primClasses.get(name);
+ if (cl != null) {
+ return cl;
+ } else {
+ throw ex;
+ }
+ */
+ return null;
+ }
+ }
+}
+
diff --git a/src/mpjbuf/DynamicBufferException.java b/src/mpjbuf/DynamicBufferException.java
new file mode 100644
index 0000000..76d687d
--- /dev/null
+++ b/src/mpjbuf/DynamicBufferException.java
@@ -0,0 +1,48 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : DynamicBufferException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Thu Jul 8 13:33:13 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class DynamicBufferException
+ extends BufferException {
+
+ public DynamicBufferException(String s, Throwable cause) {
+
+ super(s, cause);
+ }
+}
diff --git a/src/mpjbuf/IllegalArgumentException.java b/src/mpjbuf/IllegalArgumentException.java
new file mode 100644
index 0000000..240716b
--- /dev/null
+++ b/src/mpjbuf/IllegalArgumentException.java
@@ -0,0 +1,53 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : IllegalArgumentException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Fri Jul 9 17:24:39 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class IllegalArgumentException
+ extends BufferException {
+
+ public IllegalArgumentException() {
+
+ super();
+ }
+
+ public IllegalArgumentException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/NIOBuffer.java b/src/mpjbuf/NIOBuffer.java
new file mode 100644
index 0000000..028c5a5
--- /dev/null
+++ b/src/mpjbuf/NIOBuffer.java
@@ -0,0 +1,859 @@
+/* This file generated automatically from template NIOBuffer.java.in. */
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+import java.nio.*;
+
+/**
+ * Native methods implementation of `RawBuffer'.
+ *
+ * Apart from array bounds checking in `gather' and `scatter', none of these
+ * methods check validity of arguments. Passing invalid arguments will
+ * generally crash the JVM. So direct use of this class is <i>very unsafe</i>.
+ * This class is designed specifically for use from `mpjbuf.Buffer', which
+ * provides all the necessary guarantees.
+ */
+public class NIOBuffer implements RawBuffer {
+ private ByteBuffer buffer = null;
+ private int capacity ;
+
+ NIOBuffer() {
+ }
+
+ NIOBuffer(int capacity) {
+ this.capacity = capacity ;
+ //for native device we introduce allocateDirect
+ buffer = ByteBuffer.allocateDirect(capacity);
+ }
+
+ public NIOBuffer(int capacity, ByteBuffer slicedBuffer) {
+ this.capacity = capacity ;
+ this.buffer = slicedBuffer ;
+ }
+
+ public void copy(ByteBuffer srcBuffer, int srcOffset, int srcLength,
+ int dstOffset) {
+ this.buffer.position( dstOffset );
+ srcBuffer.limit( srcLength + srcOffset );
+ srcBuffer.position( srcOffset );
+ this.buffer.put(srcBuffer) ;
+ this.buffer.flip() ;
+ }
+
+
+ public int getCapacity() {
+ return capacity ;
+ }
+
+ /* introduced for NIODevice */
+ public void setBuffer(ByteBuffer buf) {
+ this.buffer.put(buf);
+ }
+
+ /* introduced for NIODevice */
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+
+ /* introduced for NIODevice ?*/
+ public void setEncoding(ByteOrder order) {
+ buffer.order(order);
+ }
+
+ public void free() {
+ buffer.clear();
+ }
+
+ public void clear() {
+ buffer.clear();
+ }
+
+ public void putByte(int value, int bufOff) {
+ buffer.position(bufOff);
+ buffer.put((byte)value);
+ }
+
+ public int getByte(int bufOff) {
+ buffer.clear() ;
+ buffer.position(bufOff);
+ byte b = buffer.get();
+ return b;
+ }
+
+ public void putInt(int value, int bufOff) {
+ buffer.position(bufOff);
+ buffer.putInt(value);
+ }
+
+ public int getInt(int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int i = buffer.getInt();
+ return i;
+ }
+
+ /******************************* BYTE **********************************/
+
+ public void write(byte[] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ buffer.put(source, srcOff, numEls); //(byte only)
+ }
+
+ public int gather(byte[] source,
+ int numEls, int offs, int[] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.put(source[index]); //byte only
+ }
+
+ return numEls;
+ }
+
+ public void strGather(byte[] source, int srcOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape, Type.BYTE);
+ }
+
+ public void read(byte[] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ buffer.get(dest, dstOff, numEls); //byte only
+ }
+
+ public int scatter(byte[] dest,
+ int numEls, int offs, int[] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ indx = indexes[offs + i];
+ dest[indx] = buffer.get(); //byte only
+ }
+
+ return numEls;
+ }
+
+
+ public void strScatter(byte[] dest, int dstOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape, Type.BYTE);
+ }
+
+
+ /******************************* SHORT **********************************/
+
+ public void write(short [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ ShortBuffer ShortBuffer = buffer.asShortBuffer() ;
+ ShortBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putShort(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(short [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putShort(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(short [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.SHORT);
+ }
+
+ public void read(short [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ ShortBuffer ShortBuffer = buffer.asShortBuffer() ;
+ ShortBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getShort();
+ //}
+
+ }
+
+ public int scatter(short [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getShort();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(short [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.SHORT);
+ }
+
+
+ /******************************* INT **********************************/
+
+ public void write(int [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ IntBuffer IntBuffer = buffer.asIntBuffer() ;
+ IntBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putInt(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(int [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putInt(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(int [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.INT);
+ }
+
+ public void read(int [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ IntBuffer IntBuffer = buffer.asIntBuffer() ;
+ IntBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getInt();
+ //}
+
+ }
+
+ public int scatter(int [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getInt();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(int [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.INT);
+ }
+
+
+ /******************************* LONG **********************************/
+
+ public void write(long [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ LongBuffer LongBuffer = buffer.asLongBuffer() ;
+ LongBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putLong(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(long [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putLong(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(long [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.LONG);
+ }
+
+ public void read(long [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ LongBuffer LongBuffer = buffer.asLongBuffer() ;
+ LongBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getLong();
+ //}
+
+ }
+
+ public int scatter(long [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getLong();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(long [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.LONG);
+ }
+
+
+ /******************************* CHAR **********************************/
+
+ public void write(char [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ CharBuffer CharBuffer = buffer.asCharBuffer() ;
+ CharBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putChar(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(char [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putChar(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(char [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.CHAR);
+ }
+
+ public void read(char [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ CharBuffer CharBuffer = buffer.asCharBuffer() ;
+ CharBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getChar();
+ //}
+
+ }
+
+ public int scatter(char [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getChar();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(char [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.CHAR);
+ }
+
+
+ /******************************* FLOAT **********************************/
+
+ public void write(float [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ FloatBuffer FloatBuffer = buffer.asFloatBuffer() ;
+ FloatBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putFloat(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(float [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putFloat(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(float [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.FLOAT);
+ }
+
+ public void read(float [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ FloatBuffer FloatBuffer = buffer.asFloatBuffer() ;
+ FloatBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getFloat();
+ //}
+
+ }
+
+ public int scatter(float [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getFloat();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(float [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.FLOAT);
+ }
+
+
+ /******************************* DOUBLE **********************************/
+
+ public void write(double [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ DoubleBuffer DoubleBuffer = buffer.asDoubleBuffer() ;
+ DoubleBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.putDouble(source[i + srcOff]);
+ //}
+ }
+
+ public int gather(double [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.putDouble(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather(double [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.DOUBLE);
+ }
+
+ public void read(double [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ DoubleBuffer DoubleBuffer = buffer.asDoubleBuffer() ;
+ DoubleBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.getDouble();
+ //}
+
+ }
+
+ public int scatter(double [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.getDouble();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(double [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.DOUBLE);
+ }
+
+
+ /******************************* BOOLEAN **********************************/
+
+ public void write(boolean[] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+
+ for (int i = 0; i < numEls; i++) {
+ buffer.put( (byte) (source[i + srcOff] ? 1 : 0)); //boolean
+ }
+ }
+
+ public int gather(boolean[] source,
+ int numEls, int offs, int[] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.put( (byte) (source[index] ? 1 : 0)); //boolean
+ }
+
+ return numEls;
+ }
+
+ public void strGather(boolean[] source, int srcOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.BOOLEAN);
+ }
+
+ public void read(boolean[] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+
+ for (int i = 0; i < numEls; i++) {
+ dest[i + dstOff] = (buffer.get() == 1) ;
+ }
+
+ }
+
+ public int scatter(boolean[] dest,
+ int numEls, int offs, int[] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ indx = indexes[offs + i];
+
+ dest[indx] = buffer.get() == 1 ;
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(boolean[] dest, int dstOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.BOOLEAN);
+ }
+
+ private void writeStrGatherBuffer(Object source, int off, Type type){
+ switch( type.getCode() ) {
+ case 0: // "byte";
+ buffer.put(((byte[])source)[off]);
+ break;
+
+ case 1: // "char";
+ buffer.putChar(((char[])source)[off]);
+ break;
+
+ case 2: // "short";
+ buffer.putShort(((short[])source)[off]);
+ break;
+
+ case 3: // "boolean";
+ if((((boolean[])source)[off]) == true) {
+ buffer.put(((byte)1));
+ }else {
+ buffer.put(((byte)0));
+ }
+ break;
+
+ case 4: // "int";
+ buffer.putInt(((int[])source)[off]);
+ break;
+
+ case 5: // "long";
+ buffer.putLong(((long[])source)[off]);
+ break;
+
+ case 6: // "float";
+ buffer.putFloat(((float[])source)[off]);
+ break;
+
+ case 7: // "double";
+ buffer.putDouble(((double[])source)[off]);
+ break;
+
+ default:
+ throw new RuntimeException("WriteBuffer::writeStrGatherBuffer:"+
+ "Unknown type "+type+".");
+ }
+ }
+
+ private void writeStrGather(Object source, int srcOff, int rank,
+ int exts, int strs, int[] indexes,
+ Type type) {
+ switch(rank){
+ case 0:
+ writeStrGatherBuffer(source, srcOff, type);
+ break;
+ case 1:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ writeStrGatherBuffer(source, index0, type);
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 2:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ writeStrGatherBuffer(source, index1, type);
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 3:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ int index2 = index1;
+ for(int k = 0; k < indexes[exts + 2]; k++){
+
+ writeStrGatherBuffer(source, index2, type);
+ index2 += indexes[strs + 2];
+ }
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ default:
+ int str = indexes[strs];
+ for (int i = 0; i < indexes[exts]; i++)
+ writeStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, indexes, type);
+ break;
+ }
+ }
+
+ private void readStrScatterBuffer(Object source, int off, Type type){
+
+ switch( type.getCode() ) {
+ case 0: // "byte";
+ try {
+ ((byte[])source)[off] = buffer.get();
+ }catch(Exception e) { e.printStackTrace(); System.exit(0); }
+ break;
+
+ case 1: // "char";
+ ((char[])source)[off] = buffer.getChar();
+ break;
+
+ case 2: // "short";
+ ((short[])source)[off] = buffer.getShort();
+ break;
+
+ case 3: // "boolean";
+ if(buffer.get() == 1) {
+ ((boolean[])source)[off] = true;
+ }else {
+ ((boolean[])source)[off] = false;
+ }
+ break;
+ case 4: // "int";
+ ((int[])source)[off] = buffer.getInt();
+ break;
+ case 5: // "long";
+ ((long[])source)[off] = buffer.getLong();
+ break;
+ case 6: // "float";
+ ((float[])source)[off] = buffer.getFloat();
+ break;
+ case 7: // "double";
+ ((double[])source)[off] = buffer.getDouble();
+ break;
+ default:
+ throw new RuntimeException("WriteBuffer::readStrGatherBuffer:"+
+ "Unknown type "+type+".");
+ }
+ }
+
+ private void readStrScatter(Object dest, int dstOff, int rank,
+ int exts, int strs, int[] indexes, Type type) {
+ switch(rank){
+ case 0:
+ readStrScatterBuffer(dest, dstOff, type);
+ break;
+ case 1: {
+ int index0 = dstOff;
+
+ for(int i = 0; i < indexes[exts]; i++){
+ readStrScatterBuffer(dest, index0, type);
+ index0 += indexes[strs];
+ }
+
+ break;
+ }
+
+
+ case 2:{
+ int index0 = dstOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ readStrScatterBuffer(dest, index1, type);
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 3:{
+
+ int index0 = dstOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ int index2 = index1;
+ for(int k = 0; k < indexes[exts + 2]; k++){
+
+ readStrScatterBuffer(dest, index2, type);
+ index2 += indexes[strs + 2];
+ }
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ default:
+ int str = indexes[strs];
+ for (int i = 0; i < indexes[exts]; i++)
+ readStrScatter(dest, dstOff + str * i,
+ rank - 1, exts + 1, strs + 1, indexes, type);
+ break;
+ }
+ }
+
+}
diff --git a/src/mpjbuf/NIOBuffer.java.in b/src/mpjbuf/NIOBuffer.java.in
new file mode 100644
index 0000000..cc5d8f6
--- /dev/null
+++ b/src/mpjbuf/NIOBuffer.java.in
@@ -0,0 +1,553 @@
+# File : NIOBuffer.java.in
+# Author : Bryan Carpenter, Aamir Shafi
+# Created : Fri Jul 16 15:21:38 BST 2004
+# Revision : $Revision: 1.13 $
+# Updated : $Date: 2014/03/11 13:26:15 PKT $
+
+# Numeric types, excluding byte
+
+ at ntypes = ('short', 'int', 'long',
+ 'char', 'float', 'double') ;
+
+ at NTYPES = ('SHORT', 'INT', 'LONG',
+ 'CHAR', 'FLOAT', 'DOUBLE') ;
+
+ at NTypes = ('Short', 'Int', 'Long',
+ 'Char', 'Float', 'Double') ;
+
+ at TypesBuf = ('ShortBuffer', 'IntBuffer', 'LongBuffer',
+ 'CharBuffer', 'FloatBuffer', 'DoubleBuffer') ;
+
+ at typesBuf = ('ShortBuffer', 'IntBuffer', 'LongBuffer',
+ 'CharBuffer', 'FloatBuffer', 'DoubleBuffer') ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+import java.nio.*;
+
+/**
+ * Native methods implementation of `RawBuffer'.
+ *
+ * Apart from array bounds checking in `gather' and `scatter', none of these
+ * methods check validity of arguments. Passing invalid arguments will
+ * generally crash the JVM. So direct use of this class is <i>very unsafe</i>.
+ * This class is designed specifically for use from `mpjbuf.Buffer', which
+ * provides all the necessary guarantees.
+ */
+public class NIOBuffer implements RawBuffer {
+ private ByteBuffer buffer = null;
+ private int capacity ;
+
+ NIOBuffer() {
+ }
+
+ NIOBuffer(int capacity) {
+ this.capacity = capacity ;
+ //for native device we introduce allocateDirect
+ buffer = ByteBuffer.allocateDirect(capacity);
+ }
+
+ public NIOBuffer(int capacity, ByteBuffer slicedBuffer) {
+ this.capacity = capacity ;
+ this.buffer = slicedBuffer ;
+ }
+
+ public void copy(ByteBuffer srcBuffer, int srcOffset, int srcLength,
+ int dstOffset) {
+ this.buffer.position( dstOffset );
+ srcBuffer.limit( srcLength + srcOffset );
+ srcBuffer.position( srcOffset );
+ this.buffer.put(srcBuffer) ;
+ this.buffer.flip() ;
+ }
+
+
+ public int getCapacity() {
+ return capacity ;
+ }
+
+ /* introduced for NIODevice */
+ public void setBuffer(ByteBuffer buf) {
+ this.buffer.put(buf);
+ }
+
+ /* introduced for NIODevice */
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+
+ /* introduced for NIODevice ?*/
+ public void setEncoding(ByteOrder order) {
+ buffer.order(order);
+ }
+
+ public void free() {
+ buffer.clear();
+ }
+
+ public void clear() {
+ buffer.clear();
+ }
+
+ public void putByte(int value, int bufOff) {
+ buffer.position(bufOff);
+ buffer.put((byte)value);
+ }
+
+ public int getByte(int bufOff) {
+ buffer.clear() ;
+ buffer.position(bufOff);
+ byte b = buffer.get();
+ return b;
+ }
+
+ public void putInt(int value, int bufOff) {
+ buffer.position(bufOff);
+ buffer.putInt(value);
+ }
+
+ public int getInt(int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int i = buffer.getInt();
+ return i;
+ }
+
+ /******************************* BYTE **********************************/
+
+ public void write(byte[] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ buffer.put(source, srcOff, numEls); //(byte only)
+ }
+
+ public int gather(byte[] source,
+ int numEls, int offs, int[] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.put(source[index]); //byte only
+ }
+
+ return numEls;
+ }
+
+ public void strGather(byte[] source, int srcOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape, Type.BYTE);
+ }
+
+ public void read(byte[] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ buffer.get(dest, dstOff, numEls); //byte only
+ }
+
+ public int scatter(byte[] dest,
+ int numEls, int offs, int[] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ indx = indexes[offs + i];
+ dest[indx] = buffer.get(); //byte only
+ }
+
+ return numEls;
+ }
+
+
+ public void strScatter(byte[] dest, int dstOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape, Type.BYTE);
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ntypes ; $i++) {
+
+ $type = $ntypes [$i];
+ $TYPE = $NTYPES [$i];
+ $Type = $NTypes [$i];
+ $TypeBuffer = $TypesBuf [$i];
+ $typeBuffer = $typesBuf [$i];
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /******************************* $TYPE **********************************/
+
+ public void write($type [] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+ $TypeBuffer $typeBuffer = buffer.as$TypeBuffer() ;
+ $typeBuffer.put(source, srcOff, numEls);
+
+ //for(int i=0 ; i<numEls ; i++) {
+ // buffer.put$Type(source[i + srcOff]);
+ //}
+ }
+
+ public int gather($type [] source,
+ int numEls, int offs, int [] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for(int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.put$Type(source[index]);
+ }
+
+ return numEls;
+ }
+
+
+ public void strGather($type [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.$TYPE);
+ }
+
+ public void read($type [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ $TypeBuffer $typeBuffer = buffer.as$TypeBuffer() ;
+ $typeBuffer.get(dest, dstOff, numEls);
+ //for (int i = 0; i < numEls; i++) {
+ // dest[i + dstOff] = buffer.get$Type();
+ //}
+
+ }
+
+ public int scatter($type [] dest,
+ int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++){
+ indx = indexes[offs + i];
+ dest[indx] = buffer.get$Type();
+ }
+
+ return numEls;
+ }
+
+ public void strScatter($type [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.$TYPE);
+ }
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+}
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ /******************************* BOOLEAN **********************************/
+
+ public void write(boolean[] source, int srcOff, int numEls,
+ int bufOff) {
+ buffer.position(bufOff);
+
+ for (int i = 0; i < numEls; i++) {
+ buffer.put( (byte) (source[i + srcOff] ? 1 : 0)); //boolean
+ }
+ }
+
+ public int gather(boolean[] source,
+ int numEls, int offs, int[] indexes,
+ int bufOff) {
+ buffer.position(bufOff);
+ int index = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ index = indexes[offs + i];
+ buffer.put( (byte) (source[index] ? 1 : 0)); //boolean
+ }
+
+ return numEls;
+ }
+
+ public void strGather(boolean[] source, int srcOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff) {
+ buffer.position(bufOff);
+ writeStrGather(source, srcOff, rank, exts, strs, shape,
+ Type.BOOLEAN);
+ }
+
+ public void read(boolean[] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+
+ for (int i = 0; i < numEls; i++) {
+ dest[i + dstOff] = (buffer.get() == 1) ;
+ }
+
+ }
+
+ public int scatter(boolean[] dest,
+ int numEls, int offs, int[] indexes,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ int indx = 0;
+
+ for (int i = 0; i < numEls; i++) {
+ indx = indexes[offs + i];
+
+ dest[indx] = buffer.get() == 1 ;
+ }
+
+ return numEls;
+ }
+
+ public void strScatter(boolean[] dest, int dstOff,
+ int rank, int exts, int strs, int[] shape,
+ int bufOff, boolean revBytes) {
+ buffer.position(bufOff);
+ readStrScatter(dest, dstOff, rank, exts, strs, shape,
+ Type.BOOLEAN);
+ }
+
+ private void writeStrGatherBuffer(Object source, int off, Type type){
+ switch( type.getCode() ) {
+ case 0: // "byte";
+ buffer.put(((byte[])source)[off]);
+ break;
+
+ case 1: // "char";
+ buffer.putChar(((char[])source)[off]);
+ break;
+
+ case 2: // "short";
+ buffer.putShort(((short[])source)[off]);
+ break;
+
+ case 3: // "boolean";
+ if((((boolean[])source)[off]) == true) {
+ buffer.put(((byte)1));
+ }else {
+ buffer.put(((byte)0));
+ }
+ break;
+
+ case 4: // "int";
+ buffer.putInt(((int[])source)[off]);
+ break;
+
+ case 5: // "long";
+ buffer.putLong(((long[])source)[off]);
+ break;
+
+ case 6: // "float";
+ buffer.putFloat(((float[])source)[off]);
+ break;
+
+ case 7: // "double";
+ buffer.putDouble(((double[])source)[off]);
+ break;
+
+ default:
+ throw new RuntimeException("WriteBuffer::writeStrGatherBuffer:"+
+ "Unknown type "+type+".");
+ }
+ }
+
+ private void writeStrGather(Object source, int srcOff, int rank,
+ int exts, int strs, int[] indexes,
+ Type type) {
+ switch(rank){
+ case 0:
+ writeStrGatherBuffer(source, srcOff, type);
+ break;
+ case 1:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ writeStrGatherBuffer(source, index0, type);
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 2:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ writeStrGatherBuffer(source, index1, type);
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 3:{
+ int index0 = srcOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ int index2 = index1;
+ for(int k = 0; k < indexes[exts + 2]; k++){
+
+ writeStrGatherBuffer(source, index2, type);
+ index2 += indexes[strs + 2];
+ }
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ default:
+ int str = indexes[strs];
+ for (int i = 0; i < indexes[exts]; i++)
+ writeStrGather(source, srcOff + str * i,
+ rank - 1, exts + 1, strs + 1, indexes, type);
+ break;
+ }
+ }
+
+ private void readStrScatterBuffer(Object source, int off, Type type){
+
+ switch( type.getCode() ) {
+ case 0: // "byte";
+ try {
+ ((byte[])source)[off] = buffer.get();
+ }catch(Exception e) { e.printStackTrace(); System.exit(0); }
+ break;
+
+ case 1: // "char";
+ ((char[])source)[off] = buffer.getChar();
+ break;
+
+ case 2: // "short";
+ ((short[])source)[off] = buffer.getShort();
+ break;
+
+ case 3: // "boolean";
+ if(buffer.get() == 1) {
+ ((boolean[])source)[off] = true;
+ }else {
+ ((boolean[])source)[off] = false;
+ }
+ break;
+ case 4: // "int";
+ ((int[])source)[off] = buffer.getInt();
+ break;
+ case 5: // "long";
+ ((long[])source)[off] = buffer.getLong();
+ break;
+ case 6: // "float";
+ ((float[])source)[off] = buffer.getFloat();
+ break;
+ case 7: // "double";
+ ((double[])source)[off] = buffer.getDouble();
+ break;
+ default:
+ throw new RuntimeException("WriteBuffer::readStrGatherBuffer:"+
+ "Unknown type "+type+".");
+ }
+ }
+
+ private void readStrScatter(Object dest, int dstOff, int rank,
+ int exts, int strs, int[] indexes, Type type) {
+ switch(rank){
+ case 0:
+ readStrScatterBuffer(dest, dstOff, type);
+ break;
+ case 1: {
+ int index0 = dstOff;
+
+ for(int i = 0; i < indexes[exts]; i++){
+ readStrScatterBuffer(dest, index0, type);
+ index0 += indexes[strs];
+ }
+
+ break;
+ }
+
+
+ case 2:{
+ int index0 = dstOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ readStrScatterBuffer(dest, index1, type);
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ case 3:{
+
+ int index0 = dstOff;
+ for(int i = 0; i < indexes[exts]; i++){
+
+ int index1 = index0;
+ for(int j = 0; j < indexes[exts + 1]; j++){
+
+ int index2 = index1;
+ for(int k = 0; k < indexes[exts + 2]; k++){
+
+ readStrScatterBuffer(dest, index2, type);
+ index2 += indexes[strs + 2];
+ }
+ index1 += indexes[strs + 1];
+ }
+ index0 += indexes[strs];
+ }
+ break;
+ }
+ default:
+ int str = indexes[strs];
+ for (int i = 0; i < indexes[exts]; i++)
+ readStrScatter(dest, dstOff + str * i,
+ rank - 1, exts + 1, strs + 1, indexes, type);
+ break;
+ }
+ }
+
+}
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+
+# NIOBuffer has three new methods, getBuffer() setBuffer() and
+# setEncoding() ..and these are public methods ...
+# which are not present on RawBuffer but its OK co we dont want to use them from MPJ pt2pt/coll layer but these methods
+# are used in NIOComm.java ...
diff --git a/src/mpjbuf/RawBuffer.java b/src/mpjbuf/RawBuffer.java
new file mode 100644
index 0000000..4b8b319
--- /dev/null
+++ b/src/mpjbuf/RawBuffer.java
@@ -0,0 +1,205 @@
+/* This file generated automatically from template RawBuffer.java.in. */
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+
+import java.nio.ByteBuffer ;
+
+/**
+ * Interface implemented by static component of buffer.
+ */
+public interface RawBuffer {
+
+ int getCapacity() ;
+
+ void free() ;
+
+ void putByte(int value, int bufOff) ;
+
+ int getByte(int bufOff) ;
+
+ void putInt(int value, int bufOff) ;
+
+ int getInt(int bufOff, boolean revBytes) ;
+
+ void copy(ByteBuffer srcBuffer, int srcOffset, int srcLength,
+ int dstOffset) ;
+
+
+
+ void write(byte [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(byte [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(byte [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(byte [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(byte [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(byte [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(short [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(short [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(short [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(short [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(short [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(short [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(int [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(int [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(int [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(int [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(int [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(int [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(long [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(long [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(long [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(long [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(long [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(long [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(char [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(char [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(char [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(char [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(char [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(char [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(float [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(float [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(float [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(float [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(float [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(float [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(double [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(double [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(double [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(double [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(double [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(double [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+
+ void write(boolean [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather(boolean [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather(boolean [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read(boolean [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter(boolean [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter(boolean [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+}
+
diff --git a/src/mpjbuf/RawBuffer.java.in b/src/mpjbuf/RawBuffer.java.in
new file mode 100644
index 0000000..58af158
--- /dev/null
+++ b/src/mpjbuf/RawBuffer.java.in
@@ -0,0 +1,96 @@
+
+# File : RawBuffer.java.in
+# Author : Bryan Carpenter
+# Created : Fri Jul 16 15:21:38 BST 2004
+# Revision : $Revision: 1.6 $
+# Updated : $Date: 2005/07/30 19:01:26 $
+
+# Primitive types
+
+ at ptypes = ('byte', 'short', 'int', 'long',
+ 'char', 'float', 'double', 'boolean') ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+package mpjbuf;
+
+import java.nio.ByteBuffer ;
+
+/**
+ * Interface implemented by static component of buffer.
+ */
+public interface RawBuffer {
+
+ int getCapacity() ;
+
+ void free() ;
+
+ void putByte(int value, int bufOff) ;
+
+ int getByte(int bufOff) ;
+
+ void putInt(int value, int bufOff) ;
+
+ int getInt(int bufOff, boolean revBytes) ;
+
+ void copy(ByteBuffer srcBuffer, int srcOffset, int srcLength,
+ int dstOffset) ;
+
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+for ($i = 0 ; $i < @ptypes ; $i++) {
+
+ $type = $ptypes [$i] ;
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+ void write($type [] source, int srcOff, int numEls, int bufOff) ;
+
+ int gather($type [] source, int numEls, int offs, int [] indexes,
+ int bufOff) ;
+
+ void strGather($type [] source, int srcOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff) ;
+
+ void read($type [] dest, int dstOff, int numEls,
+ int bufOff, boolean revBytes) ;
+
+ int scatter($type [] dest, int numEls, int offs, int [] indexes,
+ int bufOff, boolean revBytes) ;
+
+ void strScatter($type [] dest, int dstOff,
+ int rank, int exts, int strs, int [] shape,
+ int bufOff, boolean revBytes) ;
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+}
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+}
+
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+
+# To do:
+#
+# 6) Think about order of arguments to `gather()'. Somewhat
+# inconsistent with order for `write().
+
diff --git a/src/mpjbuf/SectionSizeMismatchException.java b/src/mpjbuf/SectionSizeMismatchException.java
new file mode 100644
index 0000000..b2c9e20
--- /dev/null
+++ b/src/mpjbuf/SectionSizeMismatchException.java
@@ -0,0 +1,52 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SectionSizeMismatchException.java
+ * Author : Sang Lim
+ * Created : Mon Feb 04 22:07:42 2001
+ * Revision : $Revision: 1.4 $
+ * Updated : $Date: 2005/06/27 16:17:07 $
+ */
+
+package mpjbuf;
+
+public class SectionSizeMismatchException
+ extends BufferException {
+
+ public SectionSizeMismatchException() {
+ super();
+ }
+
+ public SectionSizeMismatchException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/Type.java b/src/mpjbuf/Type.java
new file mode 100644
index 0000000..26dbbf3
--- /dev/null
+++ b/src/mpjbuf/Type.java
@@ -0,0 +1,136 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Type.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+
+package mpjbuf;
+
+/**
+ * Type of argument for
+ * {\@link #putSectionHeader(Buffer.Type) putSectionHeader()} and
+ * {\@link #getSectionHeader(Buffer.Type) getSectionHeader()}
+ * Type-safe enumeration pattern. Instances are
+ * {\@link #BYTE BYTE},
+ * {\@link #CHAR CHAR},
+ * {\@link #SHORT SHORT},
+ * {\@link #BOOLEAN BOOLEAN},
+ * {\@link #INT INT},
+ * {\@link #LONG LONG},
+ * {\@link #FLOAT FLOAT},
+ * {\@link #DOUBLE DOUBLE},
+ * {\@link #OBJECT OBJECT},
+ * {\@link #BYTE_DYNAMIC BYTE_DYNAMIC},
+ * {\@link #CHAR_DYNAMIC CHAR_DYNAMIC},
+ * {\@link #SHORT_DYNAMIC SHORT_DYNAMIC},
+ * {\@link #BOOLEAN_DYNAMIC BOOLEAN_DYNAMIC},
+ * {\@link #INT_DYNAMIC INT_DYNAMIC},
+ * {\@link #LONG_DYNAMIC LONG_DYNAMIC},
+ * {\@link #FLOAT_DYNAMIC FLOAT_DYNAMIC}, and
+ * {\@link #DOUBLE_DYNAMIC DOUBLE_DYNAMIC}.
+ */
+public class Type {
+
+ public final static Type BYTE = new Type(0);
+ public final static Type CHAR = new Type(1);
+ public final static Type SHORT = new Type(2);
+ public final static Type BOOLEAN = new Type(3);
+ public final static Type INT = new Type(4);
+ public final static Type LONG = new Type(5);
+ public final static Type FLOAT = new Type(6);
+ public final static Type DOUBLE = new Type(7);
+
+ public final static Type OBJECT = new Type(8);
+
+ // Data for sections specified with following types goes in
+ // dynamic buffer, along with objects.
+
+ public final static Type BYTE_DYNAMIC = new Type(9);
+ public final static Type CHAR_DYNAMIC = new Type(10);
+ public final static Type SHORT_DYNAMIC = new Type(11);
+ public final static Type BOOLEAN_DYNAMIC = new Type(12);
+ public final static Type INT_DYNAMIC = new Type(13);
+ public final static Type LONG_DYNAMIC = new Type(14);
+ public final static Type FLOAT_DYNAMIC = new Type(15);
+ public final static Type DOUBLE_DYNAMIC = new Type(16);
+
+ public final static Type UNDEFINED = new Type(17);
+
+ private int code ;
+
+ private Type(int code) {
+ this.code = code ;
+ }
+
+ /**
+ * Convenience method for serializing `Type' object.
+ */
+ public int getCode() {
+ return code ;
+ }
+
+ /**
+ * Convenience method for deserializing `Type' object.
+ */
+ public static Type getType(int code) {
+ return table [code] ;
+ }
+
+ private static Type [] table = {
+
+ BYTE,
+ CHAR,
+ SHORT,
+ BOOLEAN,
+ INT,
+ LONG,
+ FLOAT,
+ DOUBLE,
+
+ OBJECT,
+
+ BYTE_DYNAMIC,
+ CHAR_DYNAMIC,
+ SHORT_DYNAMIC,
+ BOOLEAN_DYNAMIC,
+ INT_DYNAMIC,
+ LONG_DYNAMIC,
+ FLOAT_DYNAMIC,
+ DOUBLE_DYNAMIC,
+
+ UNDEFINED
+ } ;
+}
+
diff --git a/src/mpjbuf/TypeMismatchException.java b/src/mpjbuf/TypeMismatchException.java
new file mode 100644
index 0000000..7e59a7b
--- /dev/null
+++ b/src/mpjbuf/TypeMismatchException.java
@@ -0,0 +1,52 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : TypeMismatchException.java
+ * Author : Sang Lim
+ * Created : Mon Feb 04 22:07:42 BST 2001
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class TypeMismatchException
+ extends BufferException {
+
+ public TypeMismatchException() {
+ super();
+ }
+
+ public TypeMismatchException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/WrongStateException.java b/src/mpjbuf/WrongStateException.java
new file mode 100644
index 0000000..f247ed6
--- /dev/null
+++ b/src/mpjbuf/WrongStateException.java
@@ -0,0 +1,53 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : WrongStateException.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Fri Jul 9 17:24:39 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+package mpjbuf;
+
+public class WrongStateException
+ extends BufferException {
+
+ public WrongStateException() {
+
+ super();
+ }
+
+ public WrongStateException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjbuf/clean.pl b/src/mpjbuf/clean.pl
new file mode 100644
index 0000000..50654be
--- /dev/null
+++ b/src/mpjbuf/clean.pl
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+# File : generate.pl
+# Author : Bryan Carpenter
+# Created : Thu Jul 15 10:44:32 BST 2004
+# Revision : $Revision: 1.3 $
+# Updated : $Date: 2005/08/16 21:44:13 $
+
+unlink "Buffer.java" ;
+unlink "RawBuffer.java" ;
+unlink "NIOBuffer.java" ;
diff --git a/src/mpjbuf/generate.pl b/src/mpjbuf/generate.pl
new file mode 100644
index 0000000..4083d2c
--- /dev/null
+++ b/src/mpjbuf/generate.pl
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+
+# File : generate.pl
+# Author : Bryan Carpenter
+# Created : Thu Jul 15 10:44:32 BST 2004
+# Revision : $Revision: 1.4 $
+# Updated : $Date: 2005/07/29 14:03:10 $
+
+ at targets = ('Buffer.java', 'RawBuffer.java', 'NIOBuffer.java') ;
+
+for($itarg = 0 ; $itarg < @targets ; $itarg++) {
+
+ $target = $targets [$itarg] ;
+ $template = $targets [$itarg] . '.in' ;
+
+ open(TEMPLATE, $template) or die "Can't open $template: $!\n" ;
+
+ $script = "\n" . '$target = "' . $target . '"' . " ;\n" ;
+
+ $script .= <<'EOF' ;
+
+open(TARGET, ">$target") or die "Can't create $target: $!\n" ;
+
+print TARGET "/* This file generated automatically ",
+ "from template $template. */\n" ;
+
+EOF
+
+
+ while($line = <TEMPLATE>) {
+ if($line =~ m/^<<<<<<</) {
+ $script .= "print TARGET <<EOF ;\n" ;
+ }
+ elsif($line =~ m/^>>>>>>>/) {
+ $script .= "EOF\n" ;
+ }
+ else {
+ $script .= $line ;
+ }
+ }
+
+
+ $script .= <<'EOF' ;
+
+close TARGET ;
+close TEMPLATE ;
+
+EOF
+
+
+ #print $script ; # debug
+ eval $script ;
+
+ # Failure to create target file probably indicates the generated script
+ # compiled with errors, due to errors in perl parts of the template.
+
+ # To trace, uncomment the "debug" line above, redirect standard output
+ # to a file, and manually feed that file to the `perl' command.
+
+}
+
diff --git a/src/mpjdev/Comm.java b/src/mpjdev/Comm.java
new file mode 100644
index 0000000..2f9f51d
--- /dev/null
+++ b/src/mpjdev/Comm.java
@@ -0,0 +1,118 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Comm.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+package mpjdev;
+
+import mpjbuf.*;
+
+public abstract class Comm {
+
+ public int sendctxt = 0;
+ public int recvctxt = 0;
+ public int collctxt = 0;
+
+ public mpjdev.Group group;
+ public mpjdev.Group localgroup;
+
+ /**
+ * this method will create intracommunicators. One way is to use create(grp),
+ * or get ids from grp at MPJ level and give the argument. contexts will be
+ * managed in this device and intercomms will be created by create(grp1,grp2)
+ * or whatever it may require.
+ */
+
+ public abstract Comm create(int[] ids) throws MPJDevException;
+
+ /**
+ * this method is used to create intra-communicators, not inter-communicators.
+ */
+ public abstract Comm create(mpjdev.Group ngroup) throws MPJDevException;
+
+ public abstract Comm create(mpjdev.Comm localcomm, mpjdev.Group peergroup,
+ int localleader, int remoteleader, int tag) throws MPJDevException;
+
+ public abstract Comm clone();
+
+ public abstract Status probe(int src, int tag) throws MPJDevException;
+
+ public abstract Status iprobe(int src, int tag) throws MPJDevException;
+
+ public abstract Request irecv(mpjbuf.Buffer buf, int src, int tag,
+ mpjdev.Status status, boolean pt2pt) throws MPJDevException;
+
+ public abstract Status recv(mpjbuf.Buffer buf, int src, int tag, boolean pt2pt)
+ throws MPJDevException;
+
+ // used in finish method in javampjdev
+ public abstract void barrier() throws MPJDevException;
+
+ public abstract Request isend(mpjbuf.Buffer buf, int dest, int tag,
+ boolean pt2pt) throws MPJDevException;
+
+ public abstract void send(mpjbuf.Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJDevException;
+
+ public abstract Request issend(mpjbuf.Buffer buf, int dest, int tag,
+ boolean pt2pt) throws MPJDevException;
+
+ public abstract void ssend(mpjbuf.Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJDevException;
+
+ public int size() throws MPJDevException {
+ return this.group.size();
+ }
+
+ public int id() throws MPJDevException {
+
+ return this.group.rank();
+ }
+
+ public void free() throws MPJDevException {
+ // cleaning up resources ...
+ }
+
+ /*
+ * all processes with same color would be form one sub-group ... all processes
+ * send their color and key to all other processes ... all processes receive
+ * color and key from all other processes ... now classify how many colors
+ * you've ... assign ranks depending on keys ...lower the key, lower the new
+ * rank .. but if the keys are same ..still its not a problem ..its my
+ * responsibility to assigning new ascending ranks to each process ...
+ */
+
+ public abstract Comm split(int color, int key) throws MPJDevException;
+
+}
diff --git a/src/mpjdev/CompletionHandler.java b/src/mpjdev/CompletionHandler.java
new file mode 100644
index 0000000..6ef320c
--- /dev/null
+++ b/src/mpjdev/CompletionHandler.java
@@ -0,0 +1,46 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : CompletionHandler.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Dec 19 12:22:15 BST 2004
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ *
+ */
+
+/*
+ *@author Aamir Shafi, Bryan Carpenter
+ */
+
+package mpjdev;
+
+public interface CompletionHandler {
+ public void handleCompletion(mpjdev.Status status);
+}
diff --git a/src/mpjdev/Constants.java b/src/mpjdev/Constants.java
new file mode 100644
index 0000000..bb56223
--- /dev/null
+++ b/src/mpjdev/Constants.java
@@ -0,0 +1,66 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Constants.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev;
+
+public class Constants {
+
+ /*
+ * This class contains constants and flags
+ */
+
+ public static boolean isNative; // set if the selected device is native.
+
+ public final static int NATIVE_SEND_OVERHEAD = 8;
+ public final static int NATIVE_RECV_OVERHEAD = 8;
+
+ /*
+ * Operator constants (Macros) we may later put them in a constants class at
+ * the mpi layer
+ */
+ public final static int MAX_CODE = 1;
+ public final static int MIN_CODE = 2;
+ public final static int SUM_CODE = 3;
+ public final static int PROD_CODE = 4;
+ public final static int LAND_CODE = 5;
+ public final static int BAND_CODE = 6;
+ public final static int LOR_CODE = 7;
+ public final static int BOR_CODE = 8;
+ public final static int LXOR_CODE = 9;
+ public final static int BXOR_CODE = 10;
+ public final static int MAXLOC_CODE = 11;
+ public final static int MINLOC_CODE = 12;
+
+}
diff --git a/src/mpjdev/Group.java b/src/mpjdev/Group.java
new file mode 100755
index 0000000..5a76f51
--- /dev/null
+++ b/src/mpjdev/Group.java
@@ -0,0 +1,183 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Group.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev;
+
+import mpi.*;
+import xdev.ProcessID;
+
+public abstract class Group {
+
+ // these two are needed in javampjdev
+ // but some test cases for mpjdev use ids[] so for the moment keeping them
+ // here
+ public ProcessID[] ids = null;
+ public ProcessID myID = null;
+
+ public int rank, size;
+
+ public final static int NO_RANK = -1;
+ public static final int IDENT = 0, CONGRUENT = 3, SIMILAR = 1, UNEQUAL = 2;
+ protected static final int UNDEFINED = -1;
+
+ /*
+ * TODO: Methods below are supposed to be static, they will be defined
+ * directly in repective class but we provide wrappers here
+ *
+ *
+ * //public static int[] transRanks(Group group1, int[]ranks1, Group group2);
+ * //public static int compare(Group group1, Group group2); //public static
+ * Group union(Group group1, Group group2); //public static Group
+ * intersection(Group group1, Group group2); //public static Group
+ * difference(Group group1, Group group2);
+ */
+
+ public static int[] transRanks(mpjdev.Group group1, int[] ranks1,
+ mpjdev.Group group2) {
+ if (Constants.isNative) {
+ return mpjdev.natmpjdev.Group.transRanksNativ(
+ (mpjdev.natmpjdev.Group) group1, ranks1,
+ (mpjdev.natmpjdev.Group) group2);
+
+ } else {
+ return mpjdev.javampjdev.Group.transRanks(group1, ranks1, group2);
+ }
+
+ }
+
+ public static int compare(mpjdev.Group group1, mpjdev.Group group2) {
+
+ if (Constants.isNative) {
+ return mpjdev.natmpjdev.Group.compareNativ(
+ (mpjdev.natmpjdev.Group) group1, (mpjdev.natmpjdev.Group) group2);
+
+ } else {
+
+ return mpjdev.javampjdev.Group.compare(group1, group2);
+
+ }
+ }
+
+ public static Group union(mpjdev.Group group1, mpjdev.Group group2) {
+ if (Constants.isNative) {
+
+ return mpjdev.natmpjdev.Group.unionNativ((mpjdev.natmpjdev.Group) group1,
+ (mpjdev.natmpjdev.Group) group2);
+ } else {
+ return mpjdev.javampjdev.Group.union(group1, group2);
+ }
+
+ }
+
+ public static Group intersection(mpjdev.Group group1, mpjdev.Group group2) {
+ if (Constants.isNative) {
+
+ return mpjdev.natmpjdev.Group.intersectionNativ(
+ (mpjdev.natmpjdev.Group) group1, (mpjdev.natmpjdev.Group) group2);
+ } else {
+ return mpjdev.javampjdev.Group.intersection(group1, group2);
+ }
+ }
+
+ public static Group difference(mpjdev.Group group1, mpjdev.Group group2) {
+ if (Constants.isNative) {
+ return mpjdev.natmpjdev.Group.differenceNativ(
+ (mpjdev.natmpjdev.Group) group1, (mpjdev.natmpjdev.Group) group2);
+ } else {
+ return mpjdev.javampjdev.Group.difference(group1, group2);
+ }
+
+ }
+
+ public abstract void free();
+
+ /**
+ * This method returns the size of the group. It is a count of the number of
+ * process encapsulated by this group object.
+ *
+ * @return int The number of processes in this group
+ */
+ public abstract int size();
+
+ /**
+ * This method returns the rank of the group. It is the rank (id) of the
+ * calling thread/process in this group.
+ *
+ * @return int The rank of the callling process in this group.
+ */
+ public abstract int rank();
+
+ /**
+ * This method returns a new group object including all the ranks specified in
+ * the argument array. Each item of the argument array should be a valid rank
+ * in the calling group. The total number of items in argument array should
+ * not be more than the size of the existing group. This method is a local
+ * operation.
+ *
+ * @param ranks
+ * Integer array specifying the ranks of the processes that will be
+ * part of the new group
+ * @return Group The group object of the new process or null if the calling
+ * process is not in the new group.
+ */
+ public abstract Group incl(int[] ranks);
+
+ /**
+ * This method returns a new group object excluding all the ranks specified in
+ * the argument array. Each item of the argument array should be a valid rank
+ * in the calling group. The total number of items in argument array should
+ * not be more than the size of the existing group. This method is a local
+ * operation.
+ *
+ * @param ranks
+ * Integer array specifying the ranks of the processes that will not
+ * be part of the new group
+ * @return Group The group object of the new process or null if the calling
+ * process is in argument array.
+ */
+ public abstract Group excl(int[] ranks);
+
+ /**
+ */
+ public abstract Group rangeIncl(int[][] ranges);
+
+ /**
+ * implemented, not sure what it does and thus not tested at the moment.
+ */
+ public abstract Group rangeExcl(int[][] ranges);
+
+
+ public abstract void finalize();
+}
diff --git a/src/mpjdev/MPJDev.java b/src/mpjdev/MPJDev.java
new file mode 100644
index 0000000..40df4eb
--- /dev/null
+++ b/src/mpjdev/MPJDev.java
@@ -0,0 +1,119 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MPJDev.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+package mpjdev;
+
+/*
+ This calss does the switching between Native or javampjdev MPJDev.
+ The javampjdev then further decides which xdev device to use depending
+ on the use selection.
+ */
+import xdev.Device;
+import mpjdev.Constants;
+
+public class MPJDev {
+
+ public static String deviceName;
+ public static mpjdev.Comm WORLD = null;
+ public static Device dev = null;
+
+ public static Device init(String args[]) throws MPJDevException {
+
+ if (args.length < 3) {
+
+ throw new MPJDevException("Usage (for javampjdev): "
+ + "java MPJDev <myrank> <conf_file> <device_name>"
+ + "conf_file can be, ../conf/xdev.conf <Local>"
+ + "OR http://holly.dsg.port.ac.uk:15000/xdev.conf <Remote>"
+ + "\nUsage (for natmpjdev): " + "java MPJDev <x> <x> <device_name>"
+ + "ignore the first two arguments" + "device name = native");
+
+ }
+
+ deviceName = args[2]; // get and set the device name
+
+ if (deviceName.equals("native")) {
+ // for Native
+ Constants.isNative = true;
+
+ mpjdev.natmpjdev.MPJDev.init(args);
+ WORLD = mpjdev.natmpjdev.MPJDev.WORLD;
+
+
+ } else {
+ // for javampjdev
+ Constants.isNative = false;
+
+ dev = mpjdev.javampjdev.MPJDev.init(args);
+ WORLD = mpjdev.javampjdev.MPJDev.WORLD;
+
+ }
+
+ return dev;
+
+ }
+
+ /**
+ * Gets the overhead incurred by send methods. It should be called after
+ * calling #init(String[] args) method
+ *
+ * @return int An integer specifying the overhead incurred by send methods
+ */
+
+ public static int getSendOverhead() {
+ if (Constants.isNative) {
+ return mpjdev.natmpjdev.MPJDev.getRecvOverhead();
+ } else
+ return mpjdev.javampjdev.MPJDev.getSendOverhead();
+ }
+
+ public static int getRecvOverhead() {
+ if (Constants.isNative) {
+ return mpjdev.natmpjdev.MPJDev.getRecvOverhead();
+ } else
+ return mpjdev.javampjdev.MPJDev.getRecvOverhead();
+ }
+
+ public static void finish() throws MPJDevException {
+ if (Constants.isNative) {
+
+ mpjdev.natmpjdev.MPJDev.finish();
+ } else {
+ mpjdev.javampjdev.MPJDev.finish();
+ }
+ }
+
+}
diff --git a/src/mpjdev/MPJDevException.java b/src/mpjdev/MPJDevException.java
new file mode 100755
index 0000000..844cae2
--- /dev/null
+++ b/src/mpjdev/MPJDevException.java
@@ -0,0 +1,46 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ *
+ * File : MPJException.java
+ * Author : Bryan Carpenter
+ * Created : Fri Nov 15 23:28:05 EST 2002
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/06/14 09:23:47 $
+ */
+
+
+
+package mpjdev;
+
+import xdev.XDevException;
+
+public class MPJDevException extends XDevException {
+
+ //XDevException not to be thrown by natmpjdev
+ // at the moment we leave this as is
+ public MPJDevException() {
+ super();
+ }
+
+ public MPJDevException(Throwable cause) {
+ super(cause);
+ }
+
+ public MPJDevException(String s) {
+ super(s);
+ }
+
+}
diff --git a/src/mpjdev/MPJException.java b/src/mpjdev/MPJException.java
new file mode 100755
index 0000000..e2840cd
--- /dev/null
+++ b/src/mpjdev/MPJException.java
@@ -0,0 +1,34 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package mpjdev;
+
+/*
+ * File : MPJException.java
+ * Author : Bryan Carpenter
+ * Created : Fri Nov 15 23:28:05 EST 2002
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/06/14 09:23:47 $
+ */
+
+public class MPJException
+ extends RuntimeException {
+
+ public MPJException(String s) {
+
+ super(s);
+ }
+}
diff --git a/src/mpjdev/Request.java b/src/mpjdev/Request.java
new file mode 100644
index 0000000..44ca227
--- /dev/null
+++ b/src/mpjdev/Request.java
@@ -0,0 +1,308 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Request.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sat Oct 2 12:22:15 BST 2004
+ * Revision : $Revision: 1.10 $
+ * Updated : $Date: 2005/12/21 13:18:17 $
+ *
+ */
+
+package mpjdev;
+
+import java.util.*;
+import java.nio.ByteBuffer;
+
+public abstract class Request {
+
+ boolean isNull = false;
+
+ LinkedList list = new LinkedList();
+
+ public abstract mpjdev.Status iwait();
+
+ public abstract Status itest();
+
+ public abstract void free();
+
+ public abstract boolean isnull();
+
+ public abstract boolean cancel();
+
+ Waitany waitany;
+
+ static class Waitany {
+
+ Request completed;
+
+ int index;
+
+ Request[] reqs;
+
+ Waitany next, prev;
+
+ boolean done;
+
+ synchronized void wakeup() {
+ done = true;
+ notify();
+ }
+
+ synchronized void waitfor() {
+ while (!done) {
+ try {
+ wait();
+ }
+ catch (Exception e) {
+ }
+ }
+ }
+
+ }
+
+ static WaitanyQue waitanyQue = new WaitanyQue();
+
+ static class WaitanyQue {
+
+ Waitany front, back;
+
+ synchronized void remove(Waitany waitany) {
+ if (front == back) {
+ front = null;
+ back = null;
+ } else if (front == waitany) {
+ front.prev.next = front.next;
+ front.next.prev = front.prev;
+ front = front.prev;
+ } else if (back == waitany) {
+ back.prev.next = back.next;
+ back.next.prev = back.prev;
+ back = back.next;
+ } else {
+ waitany.prev.next = waitany.next;
+ waitany.next.prev = waitany.prev;
+ }
+ }
+
+ synchronized void add(Waitany waitany) {
+ if (listEmpty()) {
+ front = waitany;
+ back = waitany;
+ waitany.next = waitany;
+ waitany.prev = waitany;
+ } else {
+ front.next.prev = waitany;
+ waitany.next = front.next;
+ front.next = waitany;
+ waitany.prev = front;
+ back = waitany;
+ }
+
+ }
+
+ synchronized Waitany front() {
+ return front;
+ }
+
+ boolean listEmpty() {
+ return (front == null && back == null);
+ }
+
+ }
+
+ public static mpjdev.Status iwaitany(mpjdev.Request[] requests) {
+ Waitany w = initializeWaitany(requests);
+ Request r = null;
+ Waitany wr = null;
+
+ while (w.completed == null) {
+ if (w == waitanyQue.front()) {
+
+ do {
+ // TODO: This is a very dirty hack
+ // The request seriously needs to be abstracted in someway
+ // here dev is needed and the mpjdev.request is trying to
+ // access it as
+ // MPJDev.dev which doesn't exist, it exists in as
+ // javampjdev.MPJDev.dev
+ // and what about the nativ case?
+
+ if (Constants.isNative == false) { // TODO true or false ??
+ // false false
+ // I bet its false !!!
+ r = mpjdev.javampjdev.MPJDev.dev.peek();
+ } else {
+ r = null;
+ }
+
+ wr = processRequest(r);
+ // processRequest might return null ..
+ if (wr != w) {
+ w.wakeup();
+ }
+ } while (wr != w);
+
+ if (!waitanyQue.listEmpty()) {
+ waitanyQue.front.wakeup();
+ }
+
+ } else {
+ w.waitfor();
+ }
+ }
+
+ Status completedStatus = w.completed.iwait();
+ completedStatus.index = w.index;
+ // this flag was used in mpi.Request to check if completion operations
+ // have already been called--but now we need a flag at this level
+ // this ensures that if we call iwaitany with the same set of requests,
+ // we do not endup finishing the same request object ..there is nothing
+ // to stop iwait from choosiung the same reuqest ..so we need to have
+ // some control mechanism to check that this request is NULL i.e. it has
+ // already been completed ...
+ if (completedStatus == null) {
+ System.out.println("not possible 1");
+ }
+
+ if (requests[completedStatus.index] == null) {
+ System.out.println("completedStatus.index " + completedStatus.index);
+ System.out.println("not possible 2");
+ }
+ requests[completedStatus.index].isNull = true;
+ return completedStatus;
+ /*
+ * mpjdev.Request peekedRequest = null; mpjdev.Status completedStatus =
+ * null; boolean found = false ; boolean inActive = true ;
+ *
+ * // check if there is a valid request which could be peeked for(int i=0 ;
+ * i< requests.length ; i++) { if(requests[i] != null) { inActive = false; }
+ * }
+ *
+ * if(inActive) { return null; }
+ *
+ * // first test for all message .. for(int i=0 ; i< requests.length ; i++)
+ * { if(requests[i] != null) { completedStatus = requests[i].itest() ;
+ * if(completedStatus != null) { completedStatus = requests[i].iwait() ;
+ * completedStatus.index = i ; return completedStatus ; } } }
+ *
+ * do { peekedRequest = MPJDev.dev.peek() ;
+ *
+ * // calling iwait is definitely right thing to do for mxdev ... // not
+ * sure about niodev ... completedStatus = peekedRequest.iwait() ;
+ *
+ * // sort-out the index ... for(int j=0 ;j<requests.length ; j++) {
+ * if(requests[j] != null) { if(peekedRequest == requests[j]) {
+ * completedStatus.index = j ; found = true; break; } } }
+ *
+ * } while(!found) ;
+ *
+ * return completedStatus ;
+ */
+ }
+
+ static synchronized Waitany initializeWaitany(Request[] reqs) {
+ Waitany w = new Waitany();
+ boolean found = false;
+
+ for (int i = 0; i < reqs.length; i++) {
+ if (reqs[i] != null && !reqs[i].isNull) {
+ if (reqs[i].itest() != null) {
+ w.completed = reqs[i];
+ w.index = i;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ for (int i = 0; i < reqs.length; i++) {
+ if (reqs[i] != null) {
+ reqs[i].waitany = w;
+ }
+ }
+ waitanyQue.add(w);
+ }
+
+ w.reqs = reqs;
+ return w;
+ }
+
+ static synchronized Waitany processRequest(Request r) {
+
+ Waitany w = r.waitany;
+
+ if (w == null) {
+ return null;
+ }
+
+ w.completed = r;
+
+ for (int i = 0; i < w.reqs.length; i++) {
+ // System.out.println("w.reqs["+i+"]=<"+w.reqs[i]+">");
+ // System.out.println("r=<"+r+">");
+ if (w.reqs[i] == r) {
+ // System.out.println("setting the index ");
+ w.index = i;
+ }
+
+ if (w.reqs[i] != null) {
+ w.reqs[i].waitany = null;
+ }
+ }
+
+ waitanyQue.remove(w);
+
+ return w;
+
+ }
+
+ /*
+ * invoke all completion handlers in order they were defined
+ */
+ protected void complete(mpjdev.Status status) {
+ Iterator iter = list.iterator();
+ CompletionHandler handler = null;
+
+ while (iter.hasNext()) {
+
+ handler = (CompletionHandler) iter.next();
+
+ handler.handleCompletion(status);
+ }
+ }
+
+ /*
+ * add handler (logically) to the end of a list
+ */
+ public void addCompletionHandler(mpjdev.CompletionHandler handler) {
+ list.add(handler);
+ }
+}
diff --git a/src/mpjdev/Status.java b/src/mpjdev/Status.java
new file mode 100755
index 0000000..c04824e
--- /dev/null
+++ b/src/mpjdev/Status.java
@@ -0,0 +1,103 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package mpjdev;
+
+import xdev.ProcessID;
+import java.util.UUID;
+
+/*
+ * File : Status.java
+ * Author : Sang Lim, Bryan Carpenter, Aamir Shafi
+ * Created : Thu Jan 17 17:20:40 2002
+ * Revision : $Revision: 1.11 $
+ * Updated : $Date: 2014/03/11 13:26:15 PKT $
+ */
+
+/**
+ * Status object describing a completed communication.
+ */
+
+public class Status {
+
+ /**
+ * For a receive operation, the source of the message.
+ */
+ public int source;
+ /**
+ * For a receive operation, the tag in the message.
+ */
+ public int tag;
+ /**
+ * For a `waitany()' operation in class `Request'. This field defines which
+ * communication in the `reqs' array was selected.
+ */
+ public int index;
+ public int count;
+ public int countInBytes;
+ public int numEls;
+ public mpjbuf.Type type;
+ public java.util.UUID srcID = null;
+
+ // this.source = -1; is introduced here so as to provide functionality for
+ // completionHandler for nativeDevice .. see /mpjdev/nativ/Comm irecv()
+ public Status() {
+ this.source = -1;
+ }
+
+ public Status(UUID uid, int tag, int index) {
+ this.srcID = uid;
+ this.tag = tag;
+ this.index = index;
+ this.source = -1;
+ }
+
+ public Status(UUID srcID, int tag, int index, mpjbuf.Type type, int numEls) {
+ this.srcID = srcID;
+ this.tag = tag;
+ this.index = index;
+ this.type = type;
+ this.numEls = numEls;
+ this.source = -1;
+ }
+
+ public Status(int source, int tag, int index, mpjbuf.Type type, int numEls) {
+ this.source = source;
+ this.tag = tag;
+ this.index = index;
+ this.type = type;
+ this.numEls = numEls;
+ }
+
+ public Status(int source, int tag, int index) {
+ this.source = source;
+ this.tag = tag;
+ this.index = index;
+ }
+}
diff --git a/src/mpjdev/javampjdev/Comm.java b/src/mpjdev/javampjdev/Comm.java
new file mode 100644
index 0000000..7055573
--- /dev/null
+++ b/src/mpjdev/javampjdev/Comm.java
@@ -0,0 +1,1238 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Comm.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.17 $
+ * Updated : $Date: 2005/12/21 13:18:17 $
+ *
+ */
+
+package mpjdev.javampjdev;
+
+import xdev.Device;
+import mpjbuf.Buffer;
+import mpjbuf.Type ;
+import mpjbuf.NIOBuffer ;
+import mpjbuf.BufferFactory ;
+import xdev.ProcessID;
+import java.util.UUID;
+import java.util.Random;
+
+import mpi.MPI;
+import mpjdev.*;
+
+public class Comm extends mpjdev.Comm {
+
+ Device device = null;
+ /**
+ public int sendctxt = 0;
+ public int recvctxt = 0;
+ int collctxt = 0;
+ public Group group = null;
+ public Group localgroup = null;
+ */
+
+ int calContextTag = (34*1000)+20 ;
+ int mpjdevBarrierTag = (34*1000)+21 ;
+ int splitTag = (34*1000)+22 ;
+ int bCount = 1000;
+ static int staticContext = 2;
+
+ /**
+ * constructor used for MPJDev.WORLD intracomm.
+ * how will coll. operations use different contexts ?
+ */
+ Comm(xdev.Device device, mpjdev.Group group) throws MPJDevException {
+ this.device = device;
+ this.group = group;
+ int highestContext = -1;
+ int nextContext = 0;
+
+ synchronized(Comm.class) {
+ nextContext = ++staticContext ;
+ }
+
+ try {
+ highestContext = calculateContext(10, false, nextContext);
+ }
+ catch (Exception e) {
+ throw new MPJDevException ( e );
+ }
+
+ sendctxt = highestContext;
+ recvctxt = highestContext;
+ collctxt = highestContext + (2 * highestContext);
+ //collctxt = highestContext + (2 * highestContext);
+ }
+
+ /**
+ * This method creates intercommunicator. Actually, the code may
+ * suggest that this is a very complex function, but the truth is,
+ * i don't have broadcast, reduce like functions at mpjdev level, which
+ * makes this method look difficult ..the implementation. Anyway,
+ *
+ * There is a local leader, and a remote leader. There's a concept of
+ * peer comm for creating intercommunicator. The peer comm is actually
+ * the communicator, that allows the two leaders to communicate
+ * their groups information with each other. The local leader,
+ * sends the ranks of all of its members (these ranks are w.r.t peer comm)
+ * to remote leader. The local leader then receives the ranks of all
+ * processes from remote-leader. These ranks are used by local leader
+ * to find out ProcessID, and thus create a remotegroup object that would
+ * represent the remote group. This remote group is required because in
+ * all communications using intercomm, the user will use the ranks
+ * of processes in remote groups. So once localleader, and remote leader
+ * have exchanged information, and created group objects representing
+ * remote groups, they need to broadcast this 'set of ranks' to all
+ * processes within their intracommunicator. Once this info. is broadcasted
+ * , then all processes create group objects. Once this group creation
+ * stufff is done, now its time to agree on contexts ...
+ *
+ * Both the intracommunictors (of which localleader, and remoteleader are
+ * members) broadcast in order to calculate context, and once each group
+ * has agreed on the contexts, localleaders and remoteleaders share
+ * this information. If this context is not same, then intercomm is created,
+ * if they are same, then i do some plus/minuses to agree on something
+ * that is unique ..you may see this in the code ....i don't know how
+ * to explain it in words.
+ */
+
+ //if (peergroup.ids[localleader].uuid().equals(
+ // peergroup.myID.uuid())) {
+ Comm(xdev.Device device, mpjdev.Group localgroup, mpjdev.Group peergroup,
+ int localleader, int remoteleader, int tag,
+ int peercontext, int context) throws MPJDevException {
+
+ mpjdev.Request req = null; // added by me
+ int value = 5 ;
+ int me = peergroup.rank();
+ //System.out.println("--- intercomm constructor ---"+me );
+ //System.out.println(" peercontext (comm_world) "+peercontext);
+ //System.out.println(" context (local_comm)"+context);
+ this.device = device;
+ this.localgroup = localgroup;
+ int sendOverhead = MPJDev.getSendOverhead() ;
+ int recvOverhead = MPJDev.getRecvOverhead() ;
+ int capacity = sendOverhead + 23;
+
+ Buffer sbuf = new Buffer(BufferFactory.create(capacity),
+ sendOverhead ,capacity );
+ Buffer rbuf = new Buffer(BufferFactory.create(capacity),
+
+ recvOverhead , 16+recvOverhead );
+ int[] intdata = new int[1];
+
+ if (localgroup.ids[localleader].uuid().equals(
+ localgroup.myID.uuid())) {
+
+ //System.out.println("local leader ..."+me);
+ intdata[0] = localgroup.size();
+ //System.out.println(me +"sending size of localgrp to remoteleader "
+ // +intdata[0]);
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ // System.out.println("sending ..") ;
+ req = device.isend(sbuf, peergroup.ids[remoteleader],
+ tag, peercontext); // added by me
+ } catch(Exception e ) {
+ throw new MPJDevException ( e );
+ }
+
+ mpjdev.Request []localgroupreq = new mpjdev.Request[localgroup.size()] ;
+ mpjbuf.Buffer wBuffer [] = new mpjbuf.Buffer[localgroup.size()] ;
+
+
+ for (int i = 0; i < localgroup.size(); i++) {
+
+ int prank = 0;
+
+ for (int j = 0; j < peergroup.size(); j++) {
+
+ if (localgroup.ids[i].uuid().equals(
+ peergroup.ids[j].uuid())) {
+ prank = j; //peergroup.ids[j].rank();
+ }
+ }
+
+ //System.out.println("sending the rank(WORLD) of process"+me
+ // +" to remote leader"+prank);
+ intdata[0] = prank;
+
+ try {
+ wBuffer[i] = new mpjbuf.Buffer(
+ BufferFactory.create(capacity), sendOverhead, capacity);
+
+ wBuffer[i].putSectionHeader(Type.INT);
+ wBuffer[i].write(intdata, 0, 1);
+ wBuffer[i].commit();
+ // System.out.println("sending ..") ;
+ localgroupreq[i]= device.isend(wBuffer[i],
+ peergroup.ids[remoteleader],
+ tag, peercontext); // added by me
+ }
+ catch(Exception e ){
+ throw new MPJDevException( e );
+ }
+ }
+
+
+ //System.out.println("now the local leader is receiving ..."+me );
+ device.recv(rbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+
+ //System.out.println(me + "now the local leader has received ..."
+ // +peercontext );
+
+ try {
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1); // commented by me
+ rbuf.clear();
+ }
+ catch(Exception e ) {
+ System.out.println(me +"has failed ..") ;
+ throw new MPJDevException( e );
+ }
+
+ req.iwait(); //Kamran: Completing isend of localleader to remote
+ //leader
+
+
+ try {
+ sbuf.clear() ;
+ } catch(Exception e ) {
+ throw new MPJDevException( e );
+ }
+
+ int rgroupsize = intdata[0];
+ ProcessID[] rids = new ProcessID[rgroupsize];
+ int[] rranks = new int[rgroupsize];
+ //System.out.println("local leader size "+rgroupsize);
+
+ for (int i = 0; i < rgroupsize; i++) {
+ try {
+ device.recv(rbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ rranks[i] = intdata[0];
+ rids[i] = new ProcessID(peergroup.ids[rranks[i]].uuid()); //, -1);
+
+ }
+
+ for (int i = 0; i < localgroup.size(); i++) {
+ localgroupreq[i].iwait() ;
+ try {
+ wBuffer[i].clear() ;
+ } catch(Exception e ) {
+ throw new MPJDevException( e );
+ }
+ BufferFactory.destroy(wBuffer[i].getStaticBuffer()) ;
+ }
+
+ // done by Aamir //
+
+ this.group = peergroup.incl(rranks); //check ?
+
+ for (int i = 0; i < localgroup.size(); i++) {
+
+ /* dont send recv to myself */
+ if (localgroup.ids[localleader].uuid().equals(
+ localgroup.ids[i].uuid())) {
+ continue;
+ }
+
+ intdata[0] = rgroupsize;
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ //System.out.println(me +"localleader sending group size to process"+i);
+ device.send(sbuf, localgroup.ids[i],
+ tag, context);
+ sbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ for (int j = 0; j < rgroupsize; j++) {
+
+ intdata[0] = rranks[j];
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ device.send(sbuf, localgroup.ids[i],
+ tag, context);
+ sbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ }
+ }
+ }
+
+ else {
+
+ //System.out.println("not localleader"+ me);
+ try {
+ device.recv(rbuf, localgroup.ids[localleader],
+ tag, context);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException ( e );
+ }
+ int rgroupsize = intdata[0];
+ //System.out.println(me +"received group size from local leader "
+ // +rgroupsize);
+ ProcessID[] rids = new ProcessID[rgroupsize];
+ int[] rranks = new int[rgroupsize];
+
+ for (int i = 0; i < rgroupsize; i++) {
+
+ //device.recv(rbuf, peergroup.ids[localleader],
+ try {
+ device.recv(rbuf, localgroup.ids[localleader],
+ tag, context);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ rranks[i] = intdata[0];
+ //System.out.println("received world rank of process"+i
+ // +"which is,"+rranks[i]);
+ rids[i] = new ProcessID(peergroup.ids[rranks[i]].uuid()); //, -1);
+
+ }
+
+ this.group = peergroup.incl(rranks); //check?
+ //System.out.println("built non-local leader which is, "+group);
+ }
+
+ //System.out.println(" calling calculateContext"+me);
+ int nextContext = 0 ;
+ synchronized(Comm.class) {
+ nextContext = (staticContext+2) ;
+ }
+ int hcontext = calculateContext(context, true, nextContext);
+ //System.out.println(" called calculateContext"+me);
+
+ //if (peergroup.ids[localleader].uuid().equals(
+ // peergroup.myID.uuid()))
+ if (localgroup.ids[localleader].uuid().equals(
+ localgroup.myID.uuid())) {
+
+ intdata[0] = hcontext;
+
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ req = device.isend(sbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+
+
+ device.recv(rbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+
+ req.iwait() ;
+ sbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ int rhcontext = intdata[0];
+
+ if (hcontext == rhcontext) {
+ // if both group's highest context is same, then we need some sort
+ // of conflict resolution approahc. The way current i am doing it is
+ // by passing remoteleaders rank to each other. These are ranks in
+ // some communicator like WORLD ..and cannot be equal ...
+ int peersRemoteLeader = 0 ;
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ intdata[0] = remoteleader ;
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ req = device.isend(sbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+
+
+ device.recv(rbuf, peergroup.ids[remoteleader],
+ tag, peercontext);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+
+ req.iwait() ;
+ sbuf.clear();
+ peersRemoteLeader = intdata[0] ;
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ /* get on with it ...doesnt matter */
+ //sendctxt = hcontext;
+ //recvctxt = rhcontext;
+
+ if (peersRemoteLeader > remoteleader) {
+ //System.out.println(" localleader > remoteleader ");
+ sendctxt = hcontext ; //+1; // localleader;
+ recvctxt = hcontext -1; // localleader;
+ }
+ else {
+ //System.out.println(" remoteleader > localleader ");
+ sendctxt = hcontext-1 ; //-1 ;//localleader; //remoteleader;
+ recvctxt = hcontext ; //1 localleader; //remoteleader;
+ }
+
+ }
+ else {
+ sendctxt = hcontext;
+ recvctxt = rhcontext;
+ }
+
+ //System.out.println("context selected (leader)"+sendctxt);
+ //System.out.println("context selected (leader)"+recvctxt);
+
+ for (int i = 0; i < localgroup.size(); i++) {
+ /* dont send recv to myself */
+ //if (peergroup.ids[localleader].uuid().equals(
+ // localgroup.ids[i].uuid()))
+ if (localgroup.ids[localleader].uuid().equals(
+ localgroup.ids[i].uuid())) {
+ continue;
+ }
+ intdata[0] = sendctxt;
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ //System.out.println("localleader sending contexts to process "+i);
+ device.send(sbuf, localgroup.ids[i],
+ tag, context);
+ sbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ intdata[0] = recvctxt;
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(intdata, 0, 1);
+ sbuf.commit();
+ //System.out.println("localleader sending contexts to process "+i);
+ device.send(sbuf, localgroup.ids[i],
+ tag, context);
+ sbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException ( e) ;
+ }
+
+ }
+
+ }
+ else {
+
+ //device.recv(rbuf, peergroup.ids[localleader],
+ try {
+ device.recv(rbuf, localgroup.ids[localleader],
+ tag, context);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+
+ rbuf.clear();
+ sendctxt = intdata[0];
+
+ //device.recv(rbuf, peergroup.ids[localleader],
+ device.recv(rbuf, localgroup.ids[localleader],
+ tag, context);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(intdata, 0, 1);
+ rbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException ( e );
+ }
+
+ recvctxt = intdata[0];
+
+ //System.out.println("context selected (non-leader)"+sendctxt);
+ //System.out.println("context selected (non-leader)"+recvctxt);
+ }
+
+ collctxt = -1; // intercomms dont need one.
+ //System.out.println(" finished "+me);
+ //System.out.println(" sendctxt "+sendctxt);
+ //System.out.println(" recvctxt "+recvctxt);
+ BufferFactory.destroy(rbuf.getStaticBuffer()) ;
+ BufferFactory.destroy(sbuf.getStaticBuffer()) ;
+
+ //for(i =0 ; i<localgroup.size() ;i++) {
+ // BufferFactory.destroy(wBuffer[i].getStaticBuffer());
+ //}
+
+ }
+
+ /**
+ * constructor used for making intracomm, other than MPJDev.WORLD
+ */
+ Comm(xdev.Device device, mpjdev.Group group, int context) {
+ this.device = device;
+ this.group = group;
+ int highestContext = -1;
+ int nextContext = 0 ;
+
+ synchronized(Comm.class) {
+ nextContext = ++staticContext ;
+ }
+
+ try {
+ highestContext = calculateContext(context, false, nextContext);
+ }
+ catch (Exception e) {
+ throw new MPJDevException (e);
+ }
+
+ sendctxt = highestContext;
+ collctxt = highestContext + (2 * highestContext);
+ //collctxt = highestContext + (2 * highestContext);
+ recvctxt = highestContext;
+ }
+
+ /**
+ * constructor used for making intercomm
+ * group is the remote group ...this will be used for determining ranks
+ * for the send and recv processes (becayuse this is intercomm)
+ * localgroup is localgroup ..and this is used for nothing (it seems)
+ * the contexts are named as sendcontext, and recvcontext ...and are
+ * used as such ....
+ * Do i still need this method?
+ */
+ Comm(xdev.Device device, mpjdev.Group group, mpjdev.Group localgroup, int context) {
+ this.device = device;
+ this.group = group;
+ //this.localgroup = localgroup;
+ //calculate context ...
+ }
+
+
+ /*
+ * This private method calculates the context of communications for this
+ * intracommunicator. This method will calculate context for intracomm
+ * and calculating intercomm can be tricky. and i don't know at the
+ * moment how that will be done.
+ */
+ private int calculateContext(int context, boolean isIComm,
+ int nextContext)
+ throws MPJDevException {
+
+ int myRank = -1, mySize = -1;
+ ProcessID[] ids = null;
+
+ if (isIComm) {
+ myRank = this.localgroup.rank();
+ mySize = this.localgroup.size();
+ ids = this.localgroup.ids;
+ }
+ else {
+ myRank = this.group.rank();
+ mySize = this.group.size();
+ ids = this.group.ids;
+ }
+
+ //System.out.println("rank<"+myRank+"> starting to send");
+ int[] contextArray = new int[1];
+ contextArray[0] = nextContext ; //(new Random()).nextInt(1024);
+ int i;
+ mpjdev.Request[] req = new mpjdev.Request[mySize];
+ int sendOverhead = MPJDev.getSendOverhead () ;
+ int recvOverhead = MPJDev.getRecvOverhead () ;
+ int cap = sendOverhead+23; //FIXME: What's this magic number?
+
+ mpjbuf.Buffer wBuffer [] = new mpjbuf.Buffer[mySize] ;
+
+ for (i = 0; i < mySize; i++) {
+ if (i == myRank) {
+ continue;
+ }
+ //System.out.println("process <"+group.rank()+"> sending to <"+i );
+ try {
+ wBuffer[i] = new mpjbuf.Buffer(
+ BufferFactory.create(cap), sendOverhead, cap);
+ wBuffer[i].putSectionHeader(mpjbuf.Type.INT);
+ wBuffer[i].write(contextArray, 0, 1);
+ wBuffer[i].commit();
+ req[i] = device.isend(wBuffer[i], ids[i], (calContextTag+i), context);
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ //System.out.println("process <"+group.rank()+"> sent to "+i );
+ }
+
+ mpjbuf.Buffer rBuffer = new mpjbuf.Buffer(
+ BufferFactory.create(recvOverhead+16),
+ recvOverhead , recvOverhead+16);
+ //FIXME: What's this magic number?
+ int highestContext = contextArray[0];
+
+ for (i = 0; i < mySize; i++) {
+ if (i == myRank) {
+ continue;
+ }
+
+ try {
+ //System.out.println("rank<"+myRank+"> recving from"+i);
+ device.recv(rBuffer, ids[i], (calContextTag+myRank), context);
+ //System.out.println("rank<"+myRank+"> recved from"+i);
+ rBuffer.commit();
+ Type type = rBuffer.getSectionHeader();
+ rBuffer.getSectionSize() ;
+ rBuffer.read(contextArray, 0, 1);
+ rBuffer.clear();
+ }
+ catch (Exception e) {
+ throw new MPJDevException ( e );
+ }
+
+ if (contextArray[0] > highestContext) {
+ highestContext = contextArray[0];
+ }
+
+ }
+
+ //System.out.println("rank<"+myRank+"> recv completed ");
+ //System.out.println("rank<"+myRank+"> is last loop");
+
+ for (i = 0; i < mySize; i++) {
+ if (i == myRank) {
+ continue;
+ }
+ req[i].iwait();
+ try {
+ wBuffer[i].clear();
+ } catch(Exception e) {
+ e.printStackTrace() ;
+ }
+ }
+
+ for(i =0 ; i<mySize ;i++) {
+ if (i == myRank)
+ continue;
+ BufferFactory.destroy(wBuffer[i].getStaticBuffer());
+ }
+
+ BufferFactory.destroy(rBuffer.getStaticBuffer());
+ return highestContext;
+ }
+
+ /**
+ * this method will create intracommunicators. One way is to
+ * use create(grp), or get ids from grp at MPJ level and
+ * give the argument. contexts will be managed in this device and
+ * intercomms will be created by create(grp1,grp2) or whatever
+ * it may require.
+ */
+ public mpjdev.javampjdev.Comm create(int[] ids) throws MPJDevException {
+ mpjdev.Group tmpgrp = this.group.incl(ids);
+ // will be replaced by MPI.GROUP_EMPTY
+ return ( (tmpgrp != null) ? (create(tmpgrp)) : (null));
+ }
+
+ /**
+ * this method is used to create intra-communicators,
+ * not inter-communicators.
+ */
+ public mpjdev.javampjdev.Comm create(mpjdev.Group ngroup) throws MPJDevException {
+
+ if (ngroup.rank() == -1)
+ return null; //this is basically COMM_GROUP_EMPTY ...
+
+ //System.out.println("ngroup.size() "+ngroup.size);
+ //System.out.println("ngroup.rank() "+ngroup.rank);
+ //System.out.println(" collctxt "+collctxt);
+ return new mpjdev.javampjdev.Comm(this.device, ngroup, collctxt);
+ }
+
+ public mpjdev.javampjdev.Comm create(mpjdev.Comm localcomm, mpjdev.Group peergroup,
+ int localleader, int remoteleader,
+ int tag) throws MPJDevException {
+ return new mpjdev.javampjdev.Comm(this.device, localcomm.group, peergroup, localleader,
+ remoteleader, tag, sendctxt, localcomm.collctxt);
+ }
+
+ public Comm clone() {
+ return null;
+ }
+
+ public mpjdev.Status probe(int src, int tag) throws MPJDevException {
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.iprobe(), requested negative message destination: "
+ + src);
+ }
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.iprobe(), requested source " + src +
+ " does not exist in communicator of size " +
+ this.size());
+ }
+
+ ProcessID srcID = null;
+
+ if (src == MPI.ANY_SOURCE) {
+ srcID = xdev.Device.ANY_SRC;
+ }
+ else {
+ srcID = group.ids[src];
+ }
+
+ mpjdev.Status status = device.probe(srcID, tag, recvctxt);
+ /* This loop is trying to find the matching receive */
+ for (int j = 0; j < group.ids.length; j++) {
+ if (group.ids[j].uuid().equals(status.srcID)) {
+ status.source = j;
+ break;
+ }
+ }
+ return status;
+ }
+
+ public mpjdev.Status iprobe(int src, int tag) throws MPJDevException {
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.iprobe(), requested negative message destination: "
+ + src);
+ }
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.iprobe(), requested source " + src +
+ " does not exist in communicator of size " +
+ this.size());
+ }
+
+ ProcessID srcID = null;
+
+ if (src == MPI.ANY_SOURCE) {
+ srcID = xdev.Device.ANY_SRC;
+ }
+ else {
+ srcID = group.ids[src];
+ }
+ mpjdev.Status status = device.iprobe(srcID, tag, recvctxt);
+
+ if(status != null) {
+ /* This loop is trying to find the matching receive */
+ for (int j = 0; j < group.ids.length; j++) {
+ if (group.ids[j].uuid().equals(status.srcID)) {
+ status.source = j;
+ break;
+ }
+ }
+ }
+ return status;
+ }
+
+ public mpjdev.Request irecv(mpjbuf.Buffer buf, int src, int tag,
+ mpjdev.Status status, boolean pt2pt)
+ throws MPJDevException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.irecv(), buffer is null.");
+ }
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.irecv(), requested negative message destination: "
+ + src);
+ }
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.irecv(), requested source " + src +
+ " does not exist in communicator of size " +
+ this.size());
+ }
+
+ int context = 0;
+
+ if (pt2pt) {
+ context = recvctxt;
+ }
+ else {
+ context = collctxt;
+ }
+
+ ProcessID srcID = null;
+
+ if (src == MPI.ANY_SOURCE) {
+ srcID = xdev.Device.ANY_SRC;
+ }
+ else {
+ srcID = group.ids[src];
+ }
+ mpjdev.Request request = device.irecv(buf, srcID, tag, context, status);
+
+ request.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ /* This loop is trying to find the matching receive */
+ for (int j = 0; j < group.ids.length; j++) {
+ if (group.ids[j].uuid().equals(status.srcID)) {
+ status.source = j;
+ break;
+ }
+ }
+ }
+ });
+
+ return request;
+ }
+
+ public mpjdev.Status recv(mpjbuf.Buffer buf, int src, int tag, boolean pt2pt)
+ throws MPJDevException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.irecv(), buffer is null.");
+ }
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.irecv(), requested negative message destination: "
+ + src);
+ }
+
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.irecv(), requested source " + src +
+ " does not exist in communicator of size " +
+ this.size());
+ }
+
+ int context = 0;
+ mpjdev.Status status = null;
+
+ if (pt2pt) {
+ context = recvctxt;
+ }
+ else {
+ context = collctxt;
+ }
+
+ ProcessID srcID = null;
+
+ if (src == MPI.ANY_SOURCE) {
+ srcID = xdev.Device.ANY_SRC;
+ }
+ else {
+ srcID = group.ids[src];
+ }
+
+ status = device.recv(buf, srcID, tag, context);
+
+ /* This loop is trying to find the matching receive */
+ for (int j = 0; j < group.ids.length; j++) {
+ if (group.ids[j].uuid().equals(status.srcID)) {
+ status.source = j;
+ break;
+ }
+ }
+
+ return status;
+ }
+
+ public void barrier() throws MPJDevException {
+
+ if (this.localgroup != null) {
+ System.out.println("mpjdev_barrier cannot be called for intercomm");
+ return;
+ }
+
+ bCount++;
+ int size = this.group.size();
+ int rank = this.group.rank();
+ int stuff[] = new int[1];
+ int x = 1;
+ int y = (int) Math.pow(2d, Math.floor(Math.log(size) / Math.log(2)));
+ int sendOverhead = MPJDev.getSendOverhead() ;
+ int cap = sendOverhead + 23;
+ mpjbuf.Buffer wBuffer = new mpjbuf.Buffer(BufferFactory.create(cap),
+ sendOverhead, cap);
+ mpjbuf.Buffer rBuffer = new mpjbuf.Buffer(BufferFactory.create(16),
+ 0, 16);
+ try {
+ wBuffer.putSectionHeader(mpjbuf.Type.INT);
+ wBuffer.write(stuff, 0, 1);
+ wBuffer.commit();
+ }catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ if (rank >= y) {
+ //send(rank-y,(-176+rank-y+bCount));
+ try {
+ send(wBuffer, rank-y, ( ( mpjdevBarrierTag+rank-y) * bCount),
+ false);
+ recv(rBuffer, rank-y, ( ( mpjdevBarrierTag+rank) * bCount), false);
+ rBuffer.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException ( e );
+ }
+ }
+ else {
+ if ( (size - y) > rank) {
+ try {
+ recv(rBuffer, rank + y, ((mpjdevBarrierTag+rank) * bCount), false);
+ rBuffer.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ }
+
+ int round = -1;
+ int peer = 0;
+
+ do {
+ round = round + 1;
+ peer = rank ^ (int) Math.pow(2d, round);
+ try {
+ send(wBuffer, peer, ( (mpjdevBarrierTag+peer) * bCount), false);
+ recv(rBuffer, peer, ( (mpjdevBarrierTag+rank) * bCount), false);
+ rBuffer.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ }
+ while (round != ( (int) (Math.log(y) / Math.log(2)) - 1));
+
+ if ( (size - y) > rank) {
+ //Send(stuff,0,1,MPI.INT,rank+y,(-176+rank+y+bCount));
+ try {
+ send(wBuffer, rank + y,
+ ((mpjdevBarrierTag+rank+y) * bCount), false);
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+ }
+ }
+
+ if (bCount == Integer.MAX_VALUE - 1) {
+ bCount = 1000;
+ }
+
+ BufferFactory.destroy(wBuffer.getStaticBuffer()) ;
+ BufferFactory.destroy(rBuffer.getStaticBuffer()) ;
+
+ }
+
+ public mpjdev.Request isend(mpjbuf.Buffer buf, int dest, int tag,
+ boolean pt2pt) throws MPJDevException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ }
+ else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest +
+ " does not exist in communicator of size " + size());
+ }
+
+ int context = 0;
+
+ if (pt2pt) {
+ context = sendctxt;
+ }
+ else {
+ context = collctxt;
+ }
+ //is status important here? .. .. ..
+ return device.isend(buf, group.ids[dest], tag, context);
+
+ }
+
+ public void send(mpjbuf.Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJDevException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ }
+ else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest +
+ " does not exist in communicator of size " + size());
+ }
+
+ int context = 0;
+ //System.out.println(" sendctxt (send) mpjdev "+sendctxt);
+ //System.out.println(" recvctxt (send) mpjdev "+recvctxt);
+
+ if (pt2pt) {
+ context = sendctxt;
+ }
+ else {
+ context = collctxt;
+ }
+
+ device.send(buf, group.ids[dest], tag, context);
+ }
+
+ public mpjdev.Request issend(mpjbuf.Buffer buf, int dest, int tag,
+ boolean pt2pt) throws MPJDevException {
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ }
+ else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest +
+ " does not exist in communicator of size " + size());
+ }
+
+ int context = 0;
+
+ if (pt2pt) {
+ context = sendctxt;
+ }
+ else {
+ context = collctxt;
+ }
+ // again is status important here ..we can define a completion
+ // handler here if it is ..
+ return device.issend(buf, group.ids[dest], tag, context);
+ }
+
+ public void ssend(mpjbuf.Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJDevException {
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ }
+ else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest +
+ " does not exist in communicator of size " + size());
+ }
+
+ int context = 0;
+
+ if (pt2pt) {
+ context = sendctxt;
+ }
+ else {
+ context = collctxt;
+ }
+
+ device.ssend(buf, group.ids[dest], tag, context);
+ }
+
+ public int size() {
+ return this.group.size();
+ }
+
+ public int id() {
+ //System.out.println(" this.group.rank() <"+this.group.rank()+">");
+ return this.group.rank();
+ }
+
+ public void free() throws MPJDevException {
+ //cleaning up resources ...
+ }
+
+
+ /*
+ all processes with same color would be form one sub-group ...
+ all processes send their color and key to all other processes ...
+ all processes receive color and key from all other processes ...
+ now classify how many colors you've ...
+ assign ranks depending on keys ...lower the key, lower the new rank ..
+ but if the keys are same ..still its not a problem ..its my
+ responsibility to assigning new ascending ranks to each process ...
+ */
+ public Comm split(int color, int key) throws MPJDevException {
+
+ int[][] b = new int[group.size()][3];
+ int len = 0;
+ int a[] = new int[2];
+ a[0] = color;
+ a[1] = key;
+ b[len][0] = color;
+ b[len][1] = key;
+ b[len][2] = group.rank();
+ len++;
+
+ int size = group.size();
+ int rank = group.rank();
+ int tag = splitTag ;
+ int sOverhead = MPJDev.getSendOverhead() ;
+ int cap = sOverhead + 23;
+
+ Buffer buf = new Buffer(BufferFactory.create(cap), sOverhead, cap);
+
+ try {
+ buf.putSectionHeader(Type.INT);
+ buf.write(a, 0, 2);
+ buf.commit();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ mpjdev.Request[] reqs = new mpjdev.Request[size];
+
+ /* send to all processes */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)continue;
+ reqs[i] = isend(buf, i, rank + tag + i, false);
+ }
+
+ try {
+ buf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ Buffer rbuf = new Buffer(BufferFactory.create(16), 0, 16);
+ /* now receive from all other processes */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)continue;
+ //System.out.print("p<"+rank+"> receving from <"+i+">");
+ try {
+ recv(rbuf, i, tag + i + rank, false);
+ rbuf.commit();
+ rbuf.getSectionHeader();
+ rbuf.getSectionSize() ;
+ rbuf.read(a, 0, 2);
+ rbuf.clear();
+ }
+ catch(Exception e) {
+ throw new MPJDevException( e );
+ }
+
+ if (a[0] == color) {
+ b[len][0] = a[0];
+ b[len][1] = a[1];
+ b[len][2] = i;
+ len++;
+ }
+ }
+
+ /* complete send operation */
+ for (int i = 0; i < size; i++) {
+ if (i == rank)continue;
+ reqs[i].iwait();
+ }
+
+ int keys[] = new int[len];
+ for (int i = 0; i < len; i++) {
+ keys[i] = b[i][1];
+ }
+
+ java.util.Arrays.sort(keys);
+ int nids[] = new int[len];
+
+ for (int i = 0; i < len; i++) {
+ for (int j = 0; j < len; j++) {
+ if (keys[i] == b[j][1])
+ nids[i] = b[j][2];
+ }
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("rank " + rank);
+ for (int i = 0; i < nids.length; i++) {
+ buffer.append("nids[" + i + "]=" + nids[i]);
+ }
+
+ //if(rank == 0)
+ //System.out.println("\n "+buffer.toString());
+ // System.exit(0);
+ BufferFactory.destroy(buf.getStaticBuffer()) ;
+ BufferFactory.destroy(rbuf.getStaticBuffer()) ;
+ return create(nids);
+ }
+
+}
diff --git a/src/mpjdev/javampjdev/Group.java b/src/mpjdev/javampjdev/Group.java
new file mode 100755
index 0000000..199564e
--- /dev/null
+++ b/src/mpjdev/javampjdev/Group.java
@@ -0,0 +1,732 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : Group.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Oct 15 12:22:15 BST 2004
+ * Revision : $Revision: 1.13 $
+ * Updated : $Date: 2005/11/27 19:40:12 $
+ *
+ */
+
+package mpjdev.javampjdev;
+
+import java.util.UUID;
+import xdev.ProcessID;
+import mpjdev.*;
+
+public class Group extends mpjdev.Group {
+
+ //public ProcessID[] ids = null;
+
+ //ProcessID myID = null;
+ //int rank, size;
+
+ //indexes of this array are ranks, remember this
+
+ public Group(ProcessID[] ids, ProcessID myID, int rank) {
+ this.ids = ids;
+ this.size = ids.length;
+
+ if (myID != null) {
+ this.rank = rank; // myID.rank();
+ //this rank is index of myID on ids array ...
+ this.myID = myID;
+ if(!(ids[rank].uuid().equals(myID.uuid()))) {
+ System.out.println("The group should contain itself "+
+ "Error in mpjdev.Group constructor ");
+ }
+ }
+ else
+ this.rank = NO_RANK;
+ }
+
+ /**
+ * This method frees this group object. Though automatic garbage collector
+ * will take care of it, but we mark this object for gc, by declaring it
+ * null ...
+ * implement at the end.
+ */
+ public void free() {
+ //this.group = null;
+ //this = null;
+ }
+
+ /**
+ * This method returns the size of the group. It is a count of the number
+ * of process encapsulated by this group object.
+ * @return int The number of processes in this group
+ */
+ public int size() {
+ return this.size;
+ }
+
+ /**
+ * This method returns the rank of the group. It is the rank (id) of the calling thread/process in this group.
+ * @return int The rank of the callling process in this group.
+ */
+ public int rank() {
+ return this.rank;
+ }
+
+ /**
+ * ranks1 should be a valid argument in Translate_ranks
+ * ranks2.length = ranks1.length
+ */
+
+ public static int[] transRanks(mpjdev.Group group1, int[] ranks1,
+ mpjdev.Group group2) {
+ int[] ranks2 = new int[ranks1.length];
+ int i, j, k;
+
+ for (k = 0; k < ranks2.length; k++) {
+ ranks2[k] = UNDEFINED ;
+ }
+
+ ProcessID[] ids1 = group1.ids;
+ int size1 = group1.size;
+
+ ProcessID[] ids2 = group2.ids;
+ int size2 = group2.size;
+ UUID temp1 = null, temp2 = null;
+
+ for (i = 0; i < ranks1.length; i++) {
+ temp1 = ids1[i].uuid();
+
+ for (j = 0; j < size2; j++) {
+ temp2 = ids2[j].uuid();
+
+ if (temp1.equals(temp2)) {
+ ranks2[i] = j;
+ //ranks2[i] = ids2[j].rank();
+ break;
+ }
+ }
+
+ }
+ return ranks2;
+ }
+
+ /**
+ */
+ public static int compare(mpjdev.Group group1, mpjdev.Group group2) {
+ /* Null will be replaced by GROUP_EMPTY */
+ if (group1 == null && group2 == null) {
+ System.out.println("compare why are you comparing two null groups :( ?");
+ return -1;
+ }
+ else if (group1 == null && group2 != null) {
+ System.out.println("compare group1 is null" + group1);
+ return -1;
+ }
+ else if (group1 != null && group2 == null) {
+ System.out.println("compare group2 is null" + group2);
+ return -1;
+ }
+ else {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ int size1 = group1.size;
+ int rank1 = group1.rank;
+
+ ProcessID[] ids2 = group2.ids;
+ ProcessID myID2 = group2.myID;
+ int size2 = group2.size;
+ int rank2 = group2.rank;
+
+ /* debugging loop ...
+ System.out.println("size1 "+size1);
+ System.out.println("size2 "+size2);
+ for(int g=0 ; g<size1; g++) {
+ System.out.print("ids1["+g+"]="+ids1[g]);
+ System.out.print("ids2["+g+"]="+ids2[g]);
+
+ }*/
+
+ ProcessID[] tempids = new ProcessID[size1], ids = null;
+ ProcessID myID = null;
+ int rank = 0;
+ int size = 0;
+ int i, j;
+ UUID temp1 = null, temp2 = null;
+
+ if (size1 != size2) {
+ return UNEQUAL;
+ }
+
+ boolean ident = true;
+
+ for (i = 0; i < size1; i++) {
+ temp1 = ids1[i].uuid();
+ temp2 = ids2[i].uuid();
+
+ if (temp1.equals(temp2)) {
+ }
+ else {
+ ident = false;
+ break;
+ }
+ }
+
+ if (ident) {
+ return IDENT;
+ }
+
+ boolean sim = true;
+
+ for (i = 0; i < size1; i++) {
+ temp1 = ids1[i].uuid();
+ for (j = 0; j < size2; j++) {
+ temp2 = ids2[j].uuid();
+ if (temp1.equals(temp2)) {
+ break;
+ }
+ if (j == size2) {
+ sim = false;
+ }
+ }
+ }
+
+ if (sim) {
+ return SIMILAR;
+ }
+ else {
+ return UNEQUAL;
+ }
+
+ }
+ }
+
+ //TODO: why not return mpjdev.Group
+ public static Group union(mpjdev.Group group1, mpjdev.Group group2) throws MPJDevException {
+
+ /* Null will be replaced by GROUP_EMPTY */
+ if (group1 == null && group2 == null) {
+ return null;
+ }
+ else if (group1 == null && group2 != null) {
+ ProcessID[] ids2 = group2.ids;
+ ProcessID myID2 = group2.myID;
+ int size2 = group2.size;
+ int rank2 = group2.rank;
+ ProcessID[] ids = new ProcessID[size2];
+ ProcessID myID = null;
+ int rank = NO_RANK, size = 0;
+ int i;
+
+ for (i = 0; i < size2; i++) {
+ ids[i] = ids2[i] ; //new ProcessID(ids2[i].uuid(), ids2[i].rank());
+ if (myID2 != null && ids[i].uuid().equals(myID2.uuid())) {
+ rank = rank2;
+ myID = ids[i]; //new ProcessID(ids[i].uuid(), rank);
+ //myID.rank(rank);
+ }
+ }
+
+ size = size2;
+ return new Group(ids, myID, rank);
+ }
+ else if (group1 != null && group2 == null) {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ int size1 = group1.size;
+ int rank1 = group1.rank;
+ ProcessID[] ids = new ProcessID[size1];
+ ProcessID myID = null;
+ int rank = NO_RANK, size = 0;
+ int i;
+
+ for (i = 0; i < size1; i++) {
+ ids[i] = ids1[i]; //new ProcessID(ids1[i].uuid(), ids1[i].rank());
+ rank = i;
+ if (myID1 != null && ids[i].uuid().equals(myID1.uuid())) {
+ myID = ids[i]; //new ProcessID(ids[i].uuid(), rank);
+ //myID.rank(rank);
+ }
+ }
+
+ size = size1;
+ return new Group(ids, myID,rank);
+ }
+ else {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ int size1 = group1.size;
+ int rank1 = group1.rank;
+
+ ProcessID[] ids2 = group2.ids;
+ ProcessID myID2 = group2.myID;
+ int size2 = group2.size;
+ int rank2 = group2.rank;
+
+ ProcessID[] tempids = new ProcessID[size1 + size2], ids = null;
+ ProcessID myID = null;
+ int rank = NO_RANK;
+ int size = 0;
+ int i, j;
+
+ for (i = 0; i < size1; i++) {
+ tempids[i] = ids1[i];
+ //new ProcessID(ids1[i].uuid(), ids1[i].rank());
+
+ if (myID1 != null && tempids[i].uuid().equals(myID1.uuid())) {
+ myID = tempids[i]; //new ProcessID(tempids[i].uuid(), i);
+ //myID.rank(i);
+ rank = i;
+ }
+ }
+
+ size = size1;
+ i = 0;
+ UUID uuid2 = null;
+
+ for (j = 0; j < size2; j++) {
+ uuid2 = ids2[j].uuid();
+ //check if it is already contained
+ boolean present = false;
+ //System.out.println("\n uuid2 ==>"+uuid2);
+ for (i = 0; i < size; i++) {
+ //System.out.println("tempids["+i+"]="+tempids[i]);
+ //System.out.println("uids1["+i+"].uuid() "+tempids[i].uuid());
+
+ if (tempids[i].uuid().equals(uuid2)) {
+ present = true;
+ break;
+ }
+
+ }
+ //its not in there, so add it
+ if (!present) {
+ tempids[size] = ids2[j];
+ //new ProcessID(ids2[j].uuid(), size);
+ //tempids[size].rank(size);
+
+ if (myID2 != null && tempids[size].uuid().equals(myID2.uuid())) {
+ myID = tempids[size]; //new ProcessID(tempids[size].uuid(), size);
+ //myID.rank(size);
+ rank = size ;
+ }
+ size++;
+ }
+ present = false;
+ }
+ ids = new ProcessID[size];
+ for (j = 0; j < size; j++)
+ ids[j] = tempids[j];
+
+ return new Group(ids, myID, rank);
+ }
+ }
+
+ /**
+ *
+ */
+
+ public static mpjdev.Group intersection(mpjdev.Group group1, mpjdev.Group group2) {
+
+ /* Null will be replaced by GROUP_EMPTY */
+ if (group1 == null || group2 == null) {
+ return null;
+ }
+ else {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ int size1 = group1.size;
+ int rank1 = group1.rank;
+
+ ProcessID[] ids2 = group2.ids;
+ ProcessID myID2 = group2.myID;
+ int size2 = group2.size;
+ int rank2 = group2.rank;
+
+ ProcessID[] tempids = new ProcessID[size1 + size2], ids = null;
+ ProcessID myID = null;
+ int rank = NO_RANK;
+ int size = 0;
+ int i, j;
+ UUID temp1, temp2;
+
+ for (i = 0; i < size1; i++) {
+ temp1 = ids1[i].uuid();
+ for (j = 0; j < size2; j++) {
+ temp2 = ids2[j].uuid();
+
+ if (temp1.equals(temp2)) {
+ //rank = size;
+ tempids[size] = ids1[i]; //new ProcessID(temp1, rank);
+ //tempids[size].rank(rank);
+
+ if ( (myID2 != null && tempids[size].uuid().equals(myID2.uuid())) ||
+ (myID1 != null && tempids[size].uuid().equals(myID1.uuid()))) {
+ rank = size;
+ myID = tempids[size];//new ProcessID(tempids[size].uuid(), rank);
+ //myID.rank(rank);
+ }
+
+ size++;
+ break;
+ }
+ }
+ }
+ ids = new ProcessID[size];
+
+ for (j = 0; j < size; j++)
+ ids[j] = tempids[j];
+
+ return new Group(ids, myID, rank);
+ }
+ }
+
+ /**
+ * Processes in group1, which are not in group2 make another grp.
+ */
+ public static Group difference(mpjdev.Group group1, mpjdev.Group group2) throws
+ MPJDevException {
+
+ /* Null will be replaced by GROUP_EMPTY */
+ if (group1 == null && group2 == null) {
+ return null;
+ }
+ else if (group1 == null && group2 != null) {
+ return null;
+ }
+ else if (group1 != null && group2 == null) {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ return new Group(ids1, myID1,group1.rank);
+ }
+ else {
+ ProcessID[] ids1 = group1.ids;
+ ProcessID myID1 = group1.myID;
+ int size1 = group1.size;
+ int rank1 = group1.rank;
+
+ ProcessID[] ids2 = group2.ids;
+ ProcessID myID2 = group2.myID;
+ int size2 = group2.size;
+ int rank2 = group2.rank;
+
+ ProcessID[] tempids = new ProcessID[size1], ids = null;
+ ProcessID myID = null;
+ int rank = NO_RANK;
+ int size = 0;
+ int i, j;
+ UUID temp1 = null, temp2 = null;
+
+ for (i = 0; i < size1; i++) {
+ temp1 = ids1[i].uuid();
+ boolean present = false, sid = false;
+
+ for (j = 0; j < size2; j++) {
+ temp2 = ids2[j].uuid();
+ if (temp1.equals(temp2)) {
+ present = true;
+ break;
+ }
+ }
+
+ if (!present) {
+ tempids[size] = ids1[i]; //new ProcessID(temp1, size);
+ //ids1[i].rank(rank);
+
+ if ( (rank1 != NO_RANK && temp1.equals(myID1.uuid()))) { //||
+ //( rank2 != NO_RANK && temp2.equals(myID2.uuid()) ) ) {
+ //System.out.println("\nfixing my id to " + size + "where, rank1=" +
+ // rank1 + ",rank2" + rank2 + "\n");
+ myID = tempids[size]; //new ProcessID(tempids[size].uuid(), size);
+ //myID.rank(size);
+ rank = size;
+ }
+
+ size++;
+ }
+ present = false;
+ }
+
+ ids = new ProcessID[size];
+
+ for (j = 0; j < size; j++)
+ ids[j] = tempids[j];
+
+ return new Group(ids, myID, rank);
+ }
+ }
+
+ /**
+ * This method returns a new group object including all the ranks specified in the argument array.
+ * Each item of the argument array should be a valid rank in the calling group. The total number of
+ * items in argument array should not be more than the size of the existing group. This method is a local
+ * operation.
+ * @param ranks Integer array specifying the ranks of the processes that will be part of the new group
+ * @return Group The group object of the new process or null if the calling process is not in the new group.
+ */
+ public Group incl(int[] ranks) throws MPJDevException {
+ StringBuffer buffer = new StringBuffer();
+ /*
+ buffer.append("rank "+rank);
+ for(int g=0 ; g<ranks.length ; g++) {
+ buffer.append("ranks["+g+"]="+ranks[g]);
+ buffer.append("ids["+ranks[g]+"]="+ids[ranks[g]].uuid());
+ }
+ if(rank == 0)
+ System.out.println("\n\n mpjdev incl.(before) "+buffer.toString());
+ */
+ int i, j;
+ int rank = NO_RANK;
+ if (ranks.length > this.size) {
+ throw new MPJDevException("Error in Group Incl method: length of "+
+ "array "+ranks.length+" is greater than size <"+
+ this.size + ">" );
+ }
+
+ for (i = 0; i < ranks.length; i++) {
+ if (ranks[i] > (this.size - 1) || ranks[i] < 0) {
+ throw new MPJDevException("Error in Group Incl method: arg["+i+"] "+
+ "of array is bounded by [0-"+(this.size-1)+"]" );
+ }
+ }
+
+ ProcessID[] newIds = new ProcessID[ranks.length];
+ ProcessID myID = null;
+
+ for (j = 0; j < ranks.length; j++) {
+ newIds[j] = ids[ranks[j]]; //new ProcessID(ids[ranks[j]].uuid(), j);
+ //newIds[j].rank(j);
+ if (ranks[j] == this.rank) {
+ myID = newIds[j]; //new ProcessID(newIds[j].uuid(), j);
+ rank = j;
+ //myID.rank(j);
+ }
+ }
+ /*
+ StringBuffer nbuffer = new StringBuffer();
+ nbuffer.append("rank "+rank);
+ for(int g=0 ; g<newIds.length ; g++) {
+ nbuffer.append("newIds["+g+"]="+newIds[g].uuid() );
+ nbuffer.append("newIds["+g+"]="+newIds[g].rank() );
+ }
+ if(rank == 0)
+ System.out.println("\n\n mpjdev incl. (after)"+nbuffer.toString());
+ */
+ return new Group(newIds, myID, rank);
+ }
+
+ /**
+ * This method returns a new group object excluding all the ranks specified in the argument array.
+ * Each item of the argument array should be a valid rank in the calling group. The total number of
+ * items in argument array should not be more than the size of the existing group. This method is a local
+ * operation.
+ * @param ranks Integer array specifying the ranks of the processes that will not be part of the new group
+ * @return Group The group object of the new process or null if the calling process is in argument array.
+ */
+ public Group excl(int[] ranks) throws MPJDevException {
+ int i, j;
+ if (ranks.length > this.size) {
+ throw new MPJDevException("Error in Group Excl method: length of "+
+ "array "+ranks.length+" is greater than size <"+
+ this.size + ">" );
+ }
+
+ for (i = 0; i < ranks.length; i++) {
+ if (ranks[i] > (this.size - 1) || ranks[i] < 0) {
+ throw new MPJDevException("Error in Group Excl method: arg["+i+"] "+
+ "of array is bounded by [0-"+(this.size-1)+"]" );
+ }
+ }
+
+ ProcessID[] newIds = new ProcessID[this.size - ranks.length];
+ ProcessID myID = null;
+ int rank = NO_RANK;
+ int nrank = 0;
+ boolean present = false;
+
+ for (j = 0; j < this.size; j++) {
+ for (i = 0; i < ranks.length; i++) {
+ //if (ids[j].rank() == ranks[i])
+ if (j == ranks[i]) {
+ present = true;
+ }
+ }
+
+ if (!present) {
+ newIds[nrank] = ids[j]; //new ProcessID(ids[j].uuid(), nrank);
+ //newIds[nrank].rank(nrank);
+ //if (ids[j].rank() == this.rank) {
+ if (j == this.rank) {
+ myID = newIds[nrank]; //new ProcessID(newIds[nrank].uuid(), nrank);
+ rank = nrank;
+ //myID.rank(nrank);
+ }
+ nrank++;
+ }
+
+ present = false;
+ }
+
+ return new Group(newIds, myID, rank);
+ }
+
+ /**
+ */
+ public Group rangeIncl(int[][] ranges) throws MPJDevException {
+ int len = ranges.length, fRank, lRank, str, i, j, k, np = 0, ranks;
+
+ for (i = 0; i < len; i++) {
+ fRank = ranges[i][0];
+ lRank = ranges[i][1];
+ str = ranges[i][2];
+
+ if (str != 0) {
+ if ( str > 0 && fRank > lRank) {
+ throw new MPJDevException( "Error in rangeIncl: stride <"+str+">"+
+ "is greater than zero and firstRank <"+fRank+
+ "> is greater than lastRank <"+lRank+ ">" );
+ }
+
+ if (str < 0 && fRank < lRank) {
+ throw new MPJDevException( "Error in rangeIncl: stride <"+str+">"+
+ "is less than zero and firstRank <"+fRank+
+ "> is less than lastRank <"+lRank+ ">" );
+ }
+
+ if ( (ranks = ( ( (lRank - fRank) / str) + 1)) > 0) {
+ np += ranks;
+ }
+ }
+ else {
+ throw new MPJDevException( "Error in rangeIncl: stride <"+str+">"+
+ "is zero");
+ }
+ }
+
+ if (np == 0) {
+ throw new MPJDevException( "Error in rangeIncl: number of processes <"
+ +np+"> to be included in new group is zero");
+ }
+
+ int[] npp = new int[np];
+
+ //for(int l=0 ; l<npp.length ; l++) npp[l] =-1;
+
+ k = 0;
+
+ for (i = 0; i < len; i++) {
+ fRank = ranges[i][0];
+ lRank = ranges[i][1];
+ str = ranges[i][2];
+
+ if (str != 0) {
+ //Does this start with fRank ?
+ for (j = fRank; j * str <= lRank * str; j += str) {
+ if (j < this.size() && j >= 0) {
+ npp[k] = j;
+ k++;
+ }
+ }
+ }
+ else {
+ throw new MPJDevException( "Error in rangeIncl: stride <"+str+">"+
+ "is zero");
+ }
+ }
+
+ return incl(npp);
+ }
+
+ /**
+ * implemented, not sure what it does and thus not tested at the moment.
+ */
+ public Group rangeExcl(int[][] ranges) throws MPJDevException {
+ int len = ranges.length, fRank, lRank, str, i, j, k, np = 0, ranks;
+
+ for (i = 0; i < len; i++) {
+ fRank = ranges[i][0];
+ lRank = ranges[i][1];
+ str = ranges[i][2];
+
+ if (str != 0) {
+
+ if ( str > 0 && fRank > lRank) {
+ throw new MPJDevException( "Error in rangeExcl: stride <"+str+">"+
+ "is greater than zero and firstRank <"+fRank+
+ "> is greater than lastRank <"+lRank+ ">" );
+ }
+
+ if (str < 0 && fRank < lRank) {
+ throw new MPJDevException( "Error in rangeExcl: stride <"+str+">"+
+ "is less than zero and firstRank <"+fRank+
+ "> is less than lastRank <"+lRank+ ">" );
+ }
+
+ if ( (ranks = ( ( (lRank - fRank) / str) + 1)) > 0) {
+ np += ranks;
+ }
+ }
+ else {
+ throw new MPJDevException( "Error in rangeExcl: stride <"+str+">"+
+ "is zero");
+ }
+ }
+
+ if (np == 0) {
+ throw new MPJDevException( "Error in rangeExcl: number of processes <"
+ +np+"> to be included in new group is zero");
+ }
+
+ k = 0;
+ int[] npp = new int[np];
+
+ for (i = 0; i < len; i++) {
+ fRank = ranges[i][0];
+ lRank = ranges[i][1];
+ str = ranges[i][2];
+
+ if (str != 0) {
+ //does this start with fRank ?
+ for (j = fRank; j * str <= lRank * str; j += str) {
+ if (j < this.size() && j >= 0) {
+ npp[k] = j;
+ k++;
+ }
+ }
+ }
+ else {
+ throw new MPJDevException( "Error in rangeExcl: stride <"+str+">"+
+ "is zero");
+ }
+ }
+
+ return excl(npp);
+ }
+
+ //implement at the end.
+ public void finalize() throws MPJDevException {
+ }
+}
+
diff --git a/src/mpjdev/javampjdev/MPJDev.java b/src/mpjdev/javampjdev/MPJDev.java
new file mode 100644
index 0000000..8e3b09b
--- /dev/null
+++ b/src/mpjdev/javampjdev/MPJDev.java
@@ -0,0 +1,143 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2010)
+ 3. Bryan Carpenter (2005 - 2010)
+ 4. Mark Baker (2005 - 2010)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJDev.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Mon Nov 1 12:22:15 BST 2004
+ * Revision : $Revision: 1.12 $
+ * Updated : $Date: 2005/12/05 11:58:20 $
+ *
+ */
+
+package mpjdev.javampjdev;
+
+import xdev.Device;
+import xdev.ProcessID;
+import org.apache.log4j.Logger ;
+import mpjdev.*;
+
+public class MPJDev {
+
+ public static Comm WORLD = null;
+
+ //TODO: I had to make it public because its being used from outside the package
+ // in mpjdev.Request
+ public static Device dev = null;
+
+ static Logger logger = Logger.getLogger( "mpj" );
+
+ public static Device init(String args[]) throws MPJDevException {
+
+ if (args.length < 3) {
+
+ throw new MPJDevException("Usage: " +
+ "java MPJDev <myrank> <conf_file> <device_name>"
+ +"conf_file can be, ../conf/xdev.conf <Local>"
+ +"OR http://holly.dsg.port.ac.uk:15000/xdev.conf <Remote>");
+
+ }
+
+ /* we want multiple threads to see the same object */
+ synchronized (MPJDev.class) {
+ if (dev == null) {
+ //dev = Device.newInstance(args[2]);
+ String device = args[2];
+
+ if (device.equals("niodev")) {
+ dev = new xdev.niodev.NIODevice();
+ } else if (device.equals("mxdev")) {
+ dev = new xdev.mxdev.MXDevice();
+ } else if (device.equals("smpdev")) {
+ dev = new xdev.smpdev.SMPDevice();
+ } else if (device.equals("hybdev")) {
+ dev = new xdev.hybdev.HYBDevice();
+ }else {
+ throw new MPJDevException("No matching device found for <"
+ + dev + ">");
+ }
+
+ }
+ }
+ if (dev == null) {
+ System.out.println("Specified device: " + args[2]);
+ System.out.println("Available devices, niodev, smpdev, mxdev, hybdev");
+ System.out.println("Error, cant execute, correct the device first");
+ return dev ;
+ }
+
+ ProcessID[] ids = dev.init(args);
+ ProcessID myID = dev.id();
+ int myRank = -1;
+ for(int i=0 ; i<ids.length ; i++) {
+ if(myID.uuid().equals(ids[i].uuid())) {
+ myRank = i ;
+ break;
+ }
+ }
+ WORLD = new Comm(dev, new Group(ids, myID, myRank ));
+ return dev ;
+ }
+
+ /**
+ * Gets the overhead incurred by send methods. It should be called
+ * after calling #init(String[] args) method
+ * @return int An integer specifying the overhead incurred by send methods
+ */
+ public static int getSendOverhead() {
+ if(dev == null) {
+ throw new MPJDevException("MPJDev should call init before getting "+
+ "getSendOverhead()" ) ;
+ }
+ return dev.getSendOverhead() ;
+ }
+
+ /**
+ * Gets the overhead incurred by recv methods. It should be called
+ * after calling #init(String[] args) method
+ * @return int Number of bytes overhead incurred by recv methods
+ */
+ public static int getRecvOverhead() {
+ if(dev == null) {
+ throw new MPJDevException("MPJDev should call init before getting "+
+ "getRecvOverhead()" ) ;
+ }
+ return dev.getRecvOverhead() ;
+ }
+
+ public static void finish() throws MPJDevException {
+ try {
+ dev.finish();
+ }catch( xdev.XDevException xde) {
+ throw new MPJDevException ( xde);
+ }
+
+ dev = null;
+ }
+
+}
diff --git a/src/mpjdev/natmpjdev/Comm.java b/src/mpjdev/natmpjdev/Comm.java
new file mode 100644
index 0000000..f061850
--- /dev/null
+++ b/src/mpjdev/natmpjdev/Comm.java
@@ -0,0 +1,502 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : natmpjdev.Comm.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjbuf.*;
+import mpjdev.*;// for MPJException
+
+public class Comm extends mpjdev.Comm {
+
+ private static int mpiTagUB;
+ int ghostTag = 0;
+ public long handle = -1;
+
+ public long ghostHandle = -1;
+ private int size;
+ static boolean initialized = false;
+
+ // these values as per mpiJava
+ public static int world = 2; // used for GetComm
+ public static int self = 1;
+
+ /*
+ * Static Block for loading the libnativempjdev.so
+ */
+ static {
+ System.loadLibrary("nativempjdev");
+
+ if(!loadGlobalLibraries()) {
+ System.out.println("MPJ Express failed to load required libraries");
+ System.exit(1);
+ }
+ }
+ /**
+ * The initial communicator. Equivalent of MPI_COMM_WORLD.
+ */
+ public static Comm WORLD;
+
+ /**
+ * Number of Processes Spawned by this communicator.
+ */
+ public int size() {
+ return size;
+ }
+
+ public int id() {
+ // we can also have a int id set and here just return its value rather
+ // than calling the group.rank() method
+ // TODO: OPTIMIZE later
+ return this.group.rank();
+ }
+
+ public Comm(long handle) throws MPJException {
+ setHandle(handle);
+
+ }
+
+ public Comm(long handle, mpjdev.Group localgroup_) throws MPJException {
+ setHandle(handle);
+ this.localgroup = localgroup_;
+
+ }
+
+ public Comm() {
+ GetComm(world); // sets this Comm to MPI_COMM_WORLD: This sets
+ // handle natively
+
+ long groupHandle = group(); // this returns the underlying group of this
+ // Comm
+ this.group = new Group(groupHandle);
+
+ ghostHandle = dup(handle); // dup is native
+ size = size(handle); // size is native..
+ }
+
+ private void setHandle(long handle) throws MPJException {
+ this.handle = handle;
+ ghostHandle = dup(handle); // dup is native
+ // get group handle then set this.group = new Group(returnedGroupHandle)
+ long groupHandle = group(); // this returns the underlying group of this
+ // Comm
+ this.group = new Group(groupHandle);
+ // this.localgroup = this.group;
+
+ size = size(handle); // size is native..
+ }
+
+ public long getHandle() {
+ return this.handle;
+ }
+
+ public Comm create(int[] ids) throws MPJException {
+
+ long newComm = create(handle, ids); // this create is native
+ if (newComm == 0)
+ // It means this process will be outside the group..
+ return null;
+ else
+ return new Comm(newComm);
+ }
+
+ public void free() throws MPJException {
+ if (handle != -1)
+ free(handle); // free is native
+ if (ghostHandle != -1)
+ free(ghostHandle);
+ }
+
+ /*
+ * The init() method.. This initializes the MPI.
+ */
+ public static void init(String[] args) throws MPJException {
+
+ if (initialized) {
+ return;
+ }
+ nativeInit(args);
+ WORLD = new Comm();
+ mpiTagUB = getTagUB(); // returns mpiTagUB (its basically implementation
+ // dependant value for max Tag value, read the MPI Specs)
+ initialized = true;
+ }
+
+ /*
+ * The finish()() method.. This would finialize the MPI. Previously this
+ * method was defined in MPJDev.java but now it has been moved in here for the
+ * native case
+ */
+ public static void finish() throws MPJException {
+ nativeFinish();
+ }
+
+ public int getMPI_TAG_UB(){
+ return mpiTagUB;
+ }
+
+ public Comm split(int color, int key) {
+ long newCommHandle = nativeSplit(this.handle, color, key);
+ return new Comm(newCommHandle);
+ }
+
+ public void send(Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ } else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest + " does not exist in communicator of size " + size());
+ }
+
+ int staticBufferLength = buf.getSize();
+ int dynamicBufferLength;
+
+ if (buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length;
+ } else
+ dynamicBufferLength = 0;
+
+ nativeSend(handle, buf, dest, tag,
+ staticBufferLength + MPJDev.getSendOverhead(), dynamicBufferLength);
+
+ } // ends send()
+
+ public mpjdev.Status recv(Buffer buf, int src, int tag, boolean pt2pt)
+ throws MPJException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.irecv(), buffer is null.");
+ }
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.irecv(), requested negative message destination: " + src);
+ }
+
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.irecv(), requested source " + src
+ + " does not exist in communicator of size " + this.size());
+ }
+
+ mpjdev.Status status = new mpjdev.Status();
+
+ int staticBufferLength = buf.getCapacity();
+ nativeRecv(handle, buf, staticBufferLength, src, tag, status);
+
+ int sectionSize = -1; // MPI.UNDEFINED
+ Type sectionHeader = null;
+ try {
+ buf.commit();
+ sectionHeader = buf.getSectionHeader();
+ sectionSize = buf.getSectionSize();
+ }
+ catch (Exception e) {
+ }
+
+ status.type = sectionHeader;
+ status.numEls = sectionSize;
+
+ return status;
+ }
+
+ public NativeRequest isend(Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ } else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest + " does not exist in communicator of size " + size());
+ }
+
+ NativeSendRequest req = new NativeSendRequest();
+
+ int staticBufferLength = buf.getSize();
+ int dynamicBufferLength;
+
+ if (buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length;
+ } else
+ dynamicBufferLength = 0;
+
+ nativeIsend(handle, buf, dest, tag,
+ staticBufferLength + MPJDev.getSendOverhead(), dynamicBufferLength, req);
+
+ return req;
+
+ } // ends isend()
+
+ public NativeRequest irecv(Buffer buffer, int src, int tag,
+ mpjdev.Status status, boolean pt2pt) throws MPJException {
+
+ if (buffer == null) {
+ throw new MPJDevException("In Comm.irecv(), buffer is null.");
+ }
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.irecv(), requested negative message destination: " + src);
+ }
+
+ else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.irecv(), requested source " + src
+ + " does not exist in communicator of size " + this.size());
+ }
+
+ NativeRecvRequest req = new NativeRecvRequest(handle);
+
+ nativeIrecv(handle, buffer, src, tag, status, req);
+
+ req.addCompletionHandler(new mpjdev.CompletionHandler() {
+ public void handleCompletion(mpjdev.Status status) {
+ /* Check for the matching receive */
+ if (status.source != -1) {
+
+ }
+ // actually the source is already populated by
+ // then native iwait() so just let go
+
+ }
+ });
+
+ return req;
+
+ } // ends irecv()
+
+ public void ssend(Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJException {
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ } else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest + " does not exist in communicator of size " + size());
+ }
+
+ int staticBufferLength = buf.getSize();
+ int dynamicBufferLength;
+
+ if (buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length;
+ } else
+ dynamicBufferLength = 0;
+
+ nativeSsend(handle, buf, dest, tag,
+ staticBufferLength + MPJDev.getSendOverhead(), dynamicBufferLength);
+
+ }
+
+ public mpjdev.Request issend(Buffer buf, int dest, int tag, boolean pt2pt)
+ throws MPJException {
+
+ if (buf == null) {
+ throw new MPJDevException("In Comm.isend(), buffer is null.");
+ }
+
+ if (dest < 0) {
+ throw new MPJDevException(
+ "In Comm.isend(), requested negative message destination: " + dest);
+ } else if (dest >= size()) {
+ throw new MPJDevException("In Comm.isend(), requested destination "
+ + dest + " does not exist in communicator of size " + size());
+ }
+
+ NativeSendRequest req = new NativeSendRequest();
+
+ int staticBufferLength = buf.getSize();
+ int dynamicBufferLength;
+
+ if (buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length;
+ } else
+ dynamicBufferLength = 0;
+
+ nativeIssend(handle, buf, dest, tag,
+ staticBufferLength + MPJDev.getSendOverhead(), dynamicBufferLength, req);
+
+ return req;
+ }
+
+ /*
+ * To create Intercomm
+ */
+ public Comm create(mpjdev.Comm localcomm, mpjdev.Group peergroup,
+ int localleader, int remoteleader, int tag) throws MPJException {
+
+ long newIntercomm = nativeCreateIntercomm(handle,
+ ((mpjdev.natmpjdev.Comm) localcomm).getHandle(), localleader,
+ remoteleader, tag);
+
+ return new Comm(newIntercomm, localcomm.group);
+
+ }
+
+ public Comm create(mpjdev.Group ngroup) throws MPJException {
+
+ long ngroupHandle = ((mpjdev.natmpjdev.Group) ngroup).getHandle();
+ long newCommHandle = nativeCreate(ngroupHandle);
+
+ if (newCommHandle == 0)
+ return null;
+ else
+ return new Comm(newCommHandle);
+
+ }
+
+ public void barrier() {
+ // No need here in natmpjdev
+ }
+
+ // This is also null in javampjdev
+ public Comm clone() throws MPJException {
+ return null;
+ }
+
+ public mpjdev.Status iprobe(int src, int tag) throws MPJException {
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.iprobe(), requested negative message destination: " + src);
+ } else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.iprobe(), requested source " + src
+ + " does not exist in communicator of size " + this.size());
+ }
+
+ return probe(src, tag);
+ }
+
+ public mpjdev.Status probe(int src, int tag) throws MPJException {
+
+ if (src < 0 && src != -2) {
+ throw new MPJDevException(
+ "In Comm.iprobe(), requested negative message destination: " + src);
+ } else if (src >= this.size() && src != -2) {
+ throw new MPJDevException("In Comm.iprobe(), requested source " + src
+ + " does not exist in communicator of size " + this.size());
+ }
+
+ mpjdev.Status status = new mpjdev.Status(src, tag, -1);
+ nativeProbe(handle, src, tag, status);
+
+ // this status has numEls field which is not set - since its not
+ // significant here, the countInBytes field is set
+ return status;
+ }
+
+ /*
+ * Native Methods
+ */
+
+ // used to load with dlopen() -- Mainly because Open MPI depends on it
+ private static native boolean loadGlobalLibraries();
+
+ // why static. Because its called from static contenxt in MPJDev
+ private static native int getTagUB();
+
+ // this gets the handle as COMM_WORLD
+ // perhaps rename it from getWorld() to getCOMM_WORLD()
+ private static native long getWorld(); // TODO rename it to getCOMM_WORLD()
+
+ private native long dup(long comm) throws MPJException;
+
+ private native int rank(long handle) throws MPJException;
+
+ private native int size(long comm) throws MPJException;
+
+ private native long create(long comm, int[] ids) throws MPJException;
+
+ private native long nativeSplit(long handle, int color, int key)
+ throws MPJException;
+
+ private native long nativeCreate(long ngroup) throws MPJException;
+
+ private native long nativeCreateIntercomm(long peerCommHandle,
+ long localCommHandle, int localleader, int remoteleader, int tag)
+ throws MPJException;
+
+ private native void free(long comm) throws MPJException;
+
+ private static native void nativeInit(String[] args);
+
+ public static native void nativeFinish();
+
+ private native long group() throws MPJException; // gets the group handle of
+ // this Comm
+
+ private native void GetComm(int Type) throws MPJException;
+
+ private native void nativeSend(long handle, mpjbuf.Buffer buf, int dest,
+ int tag, int slen, int dlen) throws MPJException;
+
+ private native void nativeRecv(long handle, mpjbuf.Buffer buffer, int size,
+ int src, int tag, mpjdev.Status status) throws MPJException;
+
+ private native void nativeSsend(long handle, mpjbuf.Buffer buf, int dest,
+ int tag, int slen, int dlen) throws MPJException;
+
+ private native void nativeIssend(long handle, Buffer buffer, int dest,
+ int tag, int staticBufferLength, int dynamicBufferLength,
+ NativeSendRequest req) throws MPJException;
+
+ private native void nativeIsend(long handle, Buffer buffer, int dest,
+ int tag, int staticBufferLength, int dynamicBufferLength,
+ NativeSendRequest req) throws MPJException;
+
+ private native void nativeIrecv(long handle, Buffer buffer, int src, int tag,
+ mpjdev.Status status, NativeRecvRequest req) throws MPJException;
+
+ // I know the status already has the src and tag initialized but for the
+ // simplicity
+ // of implementing at the native level lets just pass the src and tag in the
+ // arguments
+ private native void nativeProbe(long handle, int src, int tag,
+ mpjdev.Status status) throws MPJException;
+} // ends Comm class
+
diff --git a/src/mpjdev/natmpjdev/Group.java b/src/mpjdev/natmpjdev/Group.java
new file mode 100644
index 0000000..0c58533
--- /dev/null
+++ b/src/mpjdev/natmpjdev/Group.java
@@ -0,0 +1,234 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : natmpjdev.Group.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjdev.*;
+
+public class Group extends mpjdev.Group {
+
+ /*
+ * TODO also have to implement there abstract methods
+ *
+ * public abstract Group rangeIncl(int[][] ranges); public abstract Group
+ * rangeExcl(int[][] ranges);
+ */
+
+ static {
+ init();
+ }
+
+ protected long handleOfGroup; // native MPI handle of this group
+
+ public long getHandle() {
+
+ return handleOfGroup;
+ }
+
+ private static native void init(); // This is called in the static block
+
+ public Group(int Type) {
+ GetGroup(Type); // Type is 3 or 2 // GetGroup() is a native method
+ // type 2 = COMM_WORLD this is mostly the case
+ }
+
+ /*
+ * This function set the group to the group pointed by the _handle
+ */
+ public Group(long _handle) {
+ handleOfGroup = _handle;
+
+ }
+
+ /*
+ * This function sets the group to either the default group i.e. the group of
+ * universal COMM_WORLD (typeOfWorld == 2) or it sets to MPI_GROUP_EMPTY
+ * (typeOfWorld == 3)
+ */
+ private native void GetGroup(int Type);
+
+ public void free() {
+
+ nativeFree();
+ }
+
+ public int size() {
+
+ return nativeSize();
+ }
+
+ public int rank() {
+
+ return nativeRank();
+ }
+
+ public Group incl(int[] ranks) {
+ return new Group(nativeIncl(ranks));
+
+ }
+
+ public Group excl(int[] ranks) {
+ return new Group(nativeExcl(ranks));
+
+ }
+
+ public Group rangeIncl(int[][] ranges) {
+
+ if (ranges == null)
+ return null;
+
+ // convert the 2D ranges into 1D and pass it to the nativeRangeIncl
+
+ // as we know that the dimension is 3 so ranges[len][3]
+ // here find len with ranges.length
+ int len = ranges.length;
+ int oneDimRanges[] = new int[len * 3];
+
+ for (int i = 0; i < len; i++) {
+ oneDimRanges[(i * 3) + 0] = ranges[i][0];
+ oneDimRanges[(i * 3) + 1] = ranges[i][1];
+ oneDimRanges[(i * 3) + 2] = ranges[i][2];
+ }
+
+ return new Group(nativeRangeIncl(len, oneDimRanges));
+
+ }
+
+ public Group rangeExcl(int[][] ranges) {
+
+ if (ranges == null)
+ return null;
+
+ // convert the 2D ranges into 1D and pass it to the nativeRangeIncl
+
+ // as we know that the dimension is 3 so ranges[len][3]
+ // here find len with ranges.length
+ int len = ranges.length;
+ int oneDimRanges[] = new int[len * 3];
+
+ for (int i = 0; i < len; i++) {
+ oneDimRanges[(i * 3) + 0] = ranges[i][0];
+ oneDimRanges[(i * 3) + 1] = ranges[i][1];
+ oneDimRanges[(i * 3) + 2] = ranges[i][2];
+ }
+
+ return new Group(nativeRangeExcl(len, oneDimRanges));
+ }
+
+ public void finalize() throws MPJDevException {
+ // MPI_GROUP_FREE functionality .. as per mpiJava 1.2 specs
+ }
+
+ public static int[] transRanksNativ(mpjdev.natmpjdev.Group group1,
+ int[] ranks1, mpjdev.natmpjdev.Group group2) {
+
+ return nativetransRanks(group1.getHandle(), group2.getHandle(), ranks1);
+ }
+
+ /*
+ * Methods below are static in mpjdev.Group where they act as wrappers to
+ * functions in javampjdev.Group and natmpjdev.Group. So have to provide
+ * implementation
+ */
+ // Static functions
+ public static int compareNativ(mpjdev.natmpjdev.Group group1,
+ mpjdev.natmpjdev.Group group2) {
+
+ int result = nativeCompare(group1.getHandle(), group2.getHandle());
+
+ // No need to explicitly compare the result with
+ // IDENT, SIMILAR or UNEQUAL as the native code takes care of it
+ // But make sure to keep these macros the same in
+ // mpjdev.Group and /mpjdev/nativ/lib/mpjdev_nativ_Group.c
+ // in case there values change in the future
+
+ return result;
+ }
+
+ public static Group unionNativ(mpjdev.natmpjdev.Group group1,
+ mpjdev.natmpjdev.Group group2) {
+
+ long unionGroupHandle = nativeUnion(group1.getHandle(), group2.getHandle());
+
+ return new Group(unionGroupHandle);
+ }
+
+ public static Group intersectionNativ(mpjdev.natmpjdev.Group group1,
+ mpjdev.natmpjdev.Group group2) {
+
+ long intersectionGroupHandle = nativeIntersection(group1.getHandle(),
+ group2.getHandle());
+
+ return new Group(intersectionGroupHandle);
+
+ }
+
+ public static Group differenceNativ(mpjdev.natmpjdev.Group group1,
+ mpjdev.natmpjdev.Group group2) {
+
+ long differenceGroupHandle = nativeDifference(group1.getHandle(),
+ group2.getHandle());
+
+ return new Group(differenceGroupHandle);
+ }
+
+ // TODO: native rangeIncl() rangeExcl() to be implemented
+ private native void nativeFree();
+
+ private native int nativeSize();
+
+ private native int nativeRank();
+
+ private native long nativeIncl(int[] ranks);
+
+ private native long nativeExcl(int[] ranks);
+
+ private native long nativeRangeIncl(int n, int[] ranges);
+
+ private native long nativeRangeExcl(int n, int[] ranges);
+
+ private static native int[] nativetransRanks(long handleGroup1,
+ long handleGroup2, int[] ranks1);
+
+ private static native int nativeCompare(long handleGroup1, long handleGroup2);
+
+ private static native long nativeUnion(long handleGroup1, long handleGroup2);
+
+ private static native long nativeIntersection(long handleGroup1,
+ long handleGroup2);
+
+ private static native long nativeDifference(long handleGroup1,
+ long handleGroup2);
+}
diff --git a/src/mpjdev/natmpjdev/Intercomm.java b/src/mpjdev/natmpjdev/Intercomm.java
new file mode 100644
index 0000000..3be16d5
--- /dev/null
+++ b/src/mpjdev/natmpjdev/Intercomm.java
@@ -0,0 +1,60 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : natmpjdev.Intercomm.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjdev.*;
+
+public class Intercomm {
+
+ mpjdev.natmpjdev.Comm mpjdevNativeComm = null;
+
+ public Intercomm(mpjdev.natmpjdev.Comm _mpjdevComm) {
+ this.mpjdevNativeComm = _mpjdevComm;
+ }
+
+ /*
+ *
+ * returns the group of the new intracomm
+ */
+ public mpjdev.Group Merge(boolean high) throws MPJDevException {
+
+ long newIntracommHandle = nativeMerge(mpjdevNativeComm.getHandle(), high);
+ mpjdev.natmpjdev.Comm newComm = new Comm(newIntracommHandle);
+ return newComm.group;
+ }
+
+ private native long nativeMerge(long commHandle, boolean high);
+} // ends class mpjdev.natmpjdev.Intracomm.java
diff --git a/src/mpjdev/natmpjdev/Intracomm.java b/src/mpjdev/natmpjdev/Intracomm.java
new file mode 100644
index 0000000..7796301
--- /dev/null
+++ b/src/mpjdev/natmpjdev/Intracomm.java
@@ -0,0 +1,925 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : natmpjdev.Intracomm.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjbuf.*;
+import mpi.*;
+import java.nio.*;
+
+public class Intracomm {
+
+ private static native void init();
+
+ static {
+ init();
+ }
+ mpjdev.natmpjdev.Comm mpjdevNativeComm = null;
+
+ public Intracomm(mpjdev.natmpjdev.Comm _mpjdevComm) {
+ this.mpjdevNativeComm = _mpjdevComm;
+ }
+
+ /**
+ * Compare two communicators.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> comm1 </tt></td>
+ * <td>first communicator
+ * </tr>
+ * <tr>
+ * <td><tt> comm2 </tt></td>
+ * <td>second communicator
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>result
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_COMM_COMPARE</tt>.
+ * <p>
+ * <tt>MPI.IDENT</tt>(0) results if the <tt>comm1</tt> and <tt>comm2</tt> are
+ * references to the same object (ie, if <tt>comm1 == comm2</tt>).
+ * <tt>MPI.CONGRUENT</tt>(3) results if the underlying groups are identical
+ * but the communicators differ by context. <tt>MPI.SIMILAR</tt>(1) results if
+ * the underlying groups are similar but the communicators differ by context.
+ * <tt>MPI.UNEQUAL</tt>(2) results otherwise.
+ */
+
+ public static int Compare(mpjdev.Comm comm1, mpjdev.Comm comm2)
+ throws MPIException { //it throws mpi.MPIException?
+
+ return nativeCompare(((mpjdev.natmpjdev.Comm) comm1).getHandle(),
+ ((mpjdev.natmpjdev.Comm) comm2).getHandle());
+ }
+
+ private static native int nativeCompare(long handleComm1, long handleComm2);
+
+ /**
+ * Clone the communicator This method will be called only by intracommunicator
+ * .... changed the return value to Intracomm ...(instead of Object) ...
+ */
+ public Object clone() {
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: clone yet to be implemented");
+ return null;
+ }
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * /** A call to <tt>Barrier</tt> blocks the caller until all process in the
+ * group have called it.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BARRIER</tt>.
+ */
+ public void Barrier() {
+ nativeBarrier(mpjdevNativeComm.handle);
+ }
+
+ /*
+ * int MPI_Barrier( MPI_Comm comm )
+ */
+ private native void nativeBarrier(long commHandle);
+
+ /**
+ * Broadcast a message from the process with rank <tt>root</tt> to all
+ * processes of the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> buf </tt></td>
+ * <td>buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> offset </tt></td>
+ * <td>initial offset in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>datatype of each item in buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of broadcast root
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_BCST</tt>.
+ */
+
+ public void Bcast(Object buf, int size, int root) {
+
+ nativeBcast(mpjdevNativeComm.handle, (ByteBuffer) buf, size, root);
+
+ }
+
+ /*
+ * int MPI_Bcast( void *buffer, int count, MPI_Datatype datatype, int root,
+ * MPI_Comm comm )
+ */
+ private native void nativeBcast(long commHandle, ByteBuffer buffer,
+ int count, int root);
+
+ /**
+ * Each process sends the contents of its send buffer to the root process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHER</tt>.
+ */
+ public void Gather(Object sendbuf, int sendSize, Object recvbuf,
+ int recvSize, int root, boolean isRoot) {
+
+ // System.out.println("mpjdev.natmpjdev.Intracomm: Gather yet to be implemented");
+ nativeGather(mpjdevNativeComm.handle, (ByteBuffer) sendbuf, sendSize,
+ (ByteBuffer) recvbuf, recvSize, root, isRoot);
+ }
+
+ /*
+ * int MPI_Gather(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void
+ * *recvbuf, int recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm)
+ */
+ private native void nativeGather(long commHandle, ByteBuffer sendbuf,
+ int sendcount, ByteBuffer recvbuf, int recvcount, int root, boolean isRoot);
+
+ /**
+ * Extends functionality of <tt>Gather</tt> by allowing varying counts of data
+ * from each process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of receiving process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GATHERV</tt>.
+ * <p>
+ * The sizes of arrays <tt>recvcounts</tt> and <tt>displs</tt> should be the
+ * size of the group. Entry <em>i</em> of <tt>displs</tt> specifies the
+ * displacement relative to element <tt>recvoffset</tt> of <tt>recvbuf</tt> at
+ * which to place incoming data.
+ */
+ public void Gatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype, int root) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Gatherv yet to be implemented but don't know how -_-");
+
+ }
+
+ /*
+ *
+ * int MPI_Gatherv(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void
+ * *recvbuf, int *recvcnts, int *displs, MPI_Datatype recvtype, int root,
+ * MPI_Comm comm)
+ */
+ private native void nativeGatherv(long commHandle, mpjbuf.Buffer sendbuf,
+ int sendcount, mpjbuf.Buffer recvbuf, int[] recvcount, int[] displs,
+ int root);
+
+ /**
+ * Inverse of the operation <tt>Gather</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTER</tt>.
+ */
+
+ public void Scatter(Object sendbuf, int sendSize, Object recvbuf,
+ int recvSize, int root) {
+
+ nativeScatter(mpjdevNativeComm.handle, (ByteBuffer) sendbuf, sendSize,
+ (ByteBuffer) recvbuf, recvSize, root);
+ }
+
+ /*
+ * MPI_Scatter(void* send_data, int send_count, MPI_Datatype send_datatype,
+ * void* recv_data, int recv_count, MPI_Datatype recv_datatype, int root,
+ * MPI_Comm communicator)
+ */
+ private native void nativeScatter(long commHandle, ByteBuffer sendbuf,
+ int sendcount, ByteBuffer recvbuf, int recvcount, int root);
+
+ /**
+ * Inverse of the operation <tt>Gatherv</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of sending process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_SCATTERV</tt>.
+ */
+ public void Scatterv(Object sendbuf, int sendoffset, int[] sendcount,
+ int[] displs, Datatype sendtype, Object recvbuf, int recvoffset,
+ int recvcount, Datatype recvtype, int root) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Scatterv yet to be implemented but don't know how -_-");
+
+ }
+
+ /*
+ * int MPI_Scatterv( void *sendbuf, int *sendcnts, int *displs, MPI_Datatype
+ * sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root,
+ * MPI_Comm comm)
+ */
+ private native void nativeScatterv(long commHandle, ByteBuffer sendbuf,
+ int[] sendcount, int[] displs, ByteBuffer recvbuf, int recvcount, int root);
+
+ /**
+ * Similar to <tt>Gather</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items to receive
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHER</tt>.
+ */
+
+ public void Allgather(Object sendbuf, int sendSize, Object recvbuf,
+ int recvSize) {
+
+ nativeAllgather(mpjdevNativeComm.handle, (ByteBuffer) sendbuf, sendSize,
+ (ByteBuffer) recvbuf, recvSize);
+ }
+
+ /*
+ *
+ * int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void
+ * *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+ */
+ private native void nativeAllgather(long commHandle, ByteBuffer sendbuf,
+ int sendcount, ByteBuffer recvbuf, int recvcount);
+
+ /**
+ * Similar to <tt>Gatherv</tt>, but all processes receive the result.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items to send
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * </tr>
+ * <tr>
+ * <td><tt> displs </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLGATHERV</tt>.
+ */
+ public void Allgatherv(Object sendbuf, int sendoffset, int sendcount,
+ Datatype sendtype, Object recvbuf, int recvoffset, int[] recvcount,
+ int[] displs, Datatype recvtype) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Allgatherv yet to be implemented but don't know how -_-");
+ }
+
+ /*
+ * int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+ * void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype,
+ * MPI_Comm comm)
+ */
+
+ private native void nativeAllgatherv(long commHandle, ByteBuffer sendbuf,
+ int sendcount, ByteBuffer recvbuf, int[] recvcount, int[] displs);
+
+ /**
+ * Extension of <tt>Allgather</tt> to the case where each process sends
+ * distinct data to each of the receivers.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcount </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcount </tt></td>
+ * <td>number of items received from any process
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of receive buffer items
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALL</tt>.
+ */
+
+ public void Alltoall(Object sendbuf, int sendSize, Object recvbuf,
+ int recvSize) {
+
+ nativeAlltoall(mpjdevNativeComm.handle, (ByteBuffer) sendbuf, sendSize,
+ (ByteBuffer) recvbuf, recvSize);
+
+ }
+
+ /*
+ * int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, void
+ * *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+ */
+ private native void nativeAlltoall(long commHandle, ByteBuffer sendbuf,
+ int sendcount, ByteBuffer recvbuf, int recvcount);
+
+ /**
+ * Adds flexibility to <tt>Alltoall</tt>: location of data for send is
+ * specified by <tt>sdispls</tt> and location to place data on receive side is
+ * specified by <tt>rdispls</tt>.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> sendcounts </tt></td>
+ * <td>number of items sent to each process
+ * </tr>
+ * <tr>
+ * <td><tt> sdispls </tt></td>
+ * <td>displacements from which to take outgoing data
+ * </tr>
+ * <tr>
+ * <td><tt> sendtype </tt></td>
+ * <td>datatype send buffer items
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>number of elements received from each process
+ * <tr>
+ * <td><tt> rdispls </tt></td>
+ * <td>displacements at which to place incoming data
+ * </tr>
+ * <tr>
+ * <td><tt> recvtype </tt></td>
+ * <td>datatype of each item in receive buffer
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLTOALLV</tt>.
+ */
+ public void Alltoallv(Object sendbuf, int[] sendcount, int[] sdispls,
+ Object recvbuf, int[] recvcount, int[] rdispls) {
+
+ nativeAlltoallv(mpjdevNativeComm.handle, (ByteBuffer) sendbuf, sendcount,
+ sdispls, (ByteBuffer) recvbuf, recvcount, rdispls);
+ }
+
+ /*
+ * int MPI_Alltoallv(void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype
+ * sendtype, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype
+ * recvtype, MPI_Comm comm)
+ */
+ private native void nativeAlltoallv(long commHandle, ByteBuffer sendbuf,
+ int[] sendcount, int[] sdispls, ByteBuffer recvbuf, int[] recvcount,
+ int[] rdispls);
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and return the combined value in the output buffer of the root
+ * process.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * <tr>
+ * <td><tt> root </tt></td>
+ * <td>rank of root process
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE</tt>.
+ * <p>
+ * The predefined operations are available in Java as <tt>MPI.MAX</tt>,
+ * <tt>MPI.MIN</tt>, <tt>MPI.SUM</tt>, <tt>MPI.PROD</tt>, <tt>MPI.LAND</tt>,
+ * <tt>MPI.BAND</tt>, <tt>MPI.LOR</tt>, <tt>MPI.BOR</tt>, <tt>MPI.LXOR</tt>,
+ * <tt>MPI.BXOR</tt>, <tt>MPI.MINLOC</tt> and <tt>MPI.MAXLOC</tt>.
+ */
+
+ public void Reduce(Object sendbuf, Object recvbuf, int count, Datatype type,
+ Op op, int root) {
+
+ nativeReduce(mpjdevNativeComm.handle, sendbuf, (ByteBuffer) recvbuf, count,
+ type.baseType, op.opCode, root);
+
+ }
+
+ /*
+ * int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype
+ * datatype, MPI_Op op, int root, MPI_Comm comm)
+ */
+
+ private native void nativeReduce(long commHandle, Object sendbuf,
+ ByteBuffer recvbuf, int count, int datatype, int op, int root);
+
+ /**
+ * Same as <tt>reduce</tt> except that the result appears in receive buffer of
+ * all process in the group.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> count </tt></td>
+ * <td>number of items in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_ALLREDUCE</tt>.
+ */
+
+ public void Allreduce(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int count, Datatype datatype, Op op) {
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Allreduce yet to be implemented but don't know how -_-");
+ }
+
+ /*
+ * int MPI_Allreduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype
+ * datatype, MPI_Op op, MPI_Comm comm)
+ */
+ private native void nativeAllreduce(long commHandle, ByteBuffer sendbuf,
+ ByteBuffer recvbuf,
+ /* int recvoffset, */
+ int count,
+ /* Datatype datatype, */
+ Op op);
+
+ /**
+ * Combine elements in input buffer of each process using the reduce
+ * operation, and scatter the combined values over the output buffers of the
+ * processes.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> sendbuf </tt></td>
+ * <td>send buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> sendoffset </tt></td>
+ * <td>initial offset in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvbuf </tt></td>
+ * <td>receive buffer array
+ * </tr>
+ * <tr>
+ * <td><tt> recvoffset </tt></td>
+ * <td>initial offset in receive buffer
+ * </tr>
+ * <tr>
+ * <td><tt> recvcounts </tt></td>
+ * <td>numbers of result elements distributed to each process
+ * </tr>
+ * <tr>
+ * <td><tt> datatype </tt></td>
+ * <td>data type of each item in send buffer
+ * </tr>
+ * <tr>
+ * <td><tt> op </tt></td>
+ * <td>reduce operation
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_REDUCE_SCATTER</tt>.
+ */
+ public void Reduce_scatter(Object sendbuf, int sendoffset, Object recvbuf,
+ int recvoffset, int[] recvcounts, Datatype datatype, Op op) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Reduce_scatter yet to be implemented but don't know how -_-");
+ }
+
+ /*
+ * int MPI_Reduce_scatter(void* sendbuf, void* recvbuf, int *recvcounts,
+ * MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+ */
+ private native void nativeReduce_scatter(long commHandle, ByteBuffer sendbuf,
+ ByteBuffer recvbuf,
+ /* int recvoffset, */
+ int[] recvcounts,
+ /* Datatype datatype, */
+ Op op);
+
+ // TODO: As we are using the MPJ Express top layer for Topologies we at the
+ // moment do not need Cartcomm and Graphcomm creation here.
+ /**
+ * Create a Cartesian topology communicator whose group is a subset of the
+ * group of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> dims </tt></td>
+ * <td>the number of processes in each dimension
+ * </tr>
+ * <tr>
+ * <td><tt> periods </tt></td>
+ * <td> <tt>true</tt> if grid is periodic, <tt>false</tt> if not, in each
+ * dimension
+ * </tr>
+ * <tr>
+ * <td><tt> reorder </tt></td>
+ * <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new Cartesian topology communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_CART_CREATE</tt>.
+ * <p>
+ * The number of dimensions of the Cartesian grid is taken to be the size of
+ * the <tt>dims</tt> argument. The array <tt>periods</tt> must be the same
+ * size.
+ */
+ public Cartcomm Create_cart(int[] dims, boolean[] periods, boolean reorder) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Create_cart yet to be implemented but don't know how -_-");
+ return null;
+ }
+
+ /**
+ * Create a graph topology communicator whose group is a subset of the group
+ * of this communicator.
+ * <p>
+ * <table>
+ * <tr>
+ * <td><tt> index </tt></td>
+ * <td>node degrees
+ * </tr>
+ * <tr>
+ * <td><tt> edges </tt></td>
+ * <td>graph edges
+ * </tr>
+ * <tr>
+ * <td><tt> reorder </tt></td>
+ * <td> <tt>true</tt> if ranking may be reordered, <tt>false</tt> if not
+ * </tr>
+ * <tr>
+ * <td><em> returns: </em></td>
+ * <td>new graph topology communicator
+ * </tr>
+ * </table>
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_GRAPH_CREATE</tt>.
+ * <p>
+ * The number of nodes in the graph, <em>nnodes</em>, is taken to be size of
+ * the <tt>index</tt> argument. The size of array <tt>edges</tt> must be
+ * <tt>index [nnodes} - 1]</tt>.
+ */
+ public Graphcomm Create_graph(int[] index, int[] edges, boolean reorder) {
+
+ System.out
+ .println("mpjdev.natmpjdev.Intracomm: Create_graph yet to be implemented but don't know how -_-");
+ return null;
+ }
+
+} // ends class mpjdev.natmpjdev.Intracomm.java
diff --git a/src/mpjdev/natmpjdev/MPJDev.java b/src/mpjdev/natmpjdev/MPJDev.java
new file mode 100644
index 0000000..ed47100
--- /dev/null
+++ b/src/mpjdev/natmpjdev/MPJDev.java
@@ -0,0 +1,97 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : natmpjdev.MPJDev.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+package mpjdev.natmpjdev;
+
+import mpjdev.*;
+import org.apache.log4j.Logger;
+
+public class MPJDev {
+
+ public static Comm WORLD = null;
+
+ static Logger logger = Logger.getLogger("mpj");
+
+ public static void init(String args[]) throws MPJDevException {
+
+ if (args.length < 3) {
+
+ throw new MPJDevException("Usage: " + "java MPJDev <x> <x> <device_name>"
+ + "ignore the first two arguments x x device_name = native");
+
+ }
+ if (Comm.initialized) {
+ return;
+ }
+
+ Comm.init(args);
+ WORLD = mpjdev.natmpjdev.Comm.WORLD;
+
+ }
+
+ /**
+ * Gets the overhead incurred by send methods. It should be called after
+ * calling #init(String[] args) method
+ *
+ * @return int An integer specifying the overhead incurred by send methods
+ */
+ public static int getSendOverhead() {
+
+ return mpjdev.Constants.NATIVE_SEND_OVERHEAD;
+ }
+
+ /**
+ * Gets the overhead incurred by recv methods. It should be called after
+ * calling #init(String[] args) method
+ *
+ * @return int Number of bytes overhead incurred by recv methods
+ */
+ public static int getRecvOverhead() {
+
+ return mpjdev.Constants.NATIVE_RECV_OVERHEAD;
+ }
+
+ public static void finish() throws MPJDevException {
+ try {
+ Comm.finish();
+ }
+ catch (MPJDevException mdeve) {
+ throw new MPJDevException(mdeve);
+ }
+
+ }
+
+}
diff --git a/src/mpjdev/natmpjdev/NativeRecvRequest.java b/src/mpjdev/natmpjdev/NativeRecvRequest.java
new file mode 100644
index 0000000..c688d00
--- /dev/null
+++ b/src/mpjdev/natmpjdev/NativeRecvRequest.java
@@ -0,0 +1,125 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : NativeRecvRequest.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjdev.Status;
+
+public class NativeRecvRequest extends NativeRequest {
+
+ private static native void initNativeRecvRequest();
+
+ static {
+ initNativeRecvRequest();
+ }
+
+ protected NativeRecvRequest() {
+
+ }
+
+ public NativeRecvRequest(long commHandle_) {
+ this.commHandle = commHandle_;
+
+ }
+
+ public Status iwait() {
+
+ if (completed) {
+ return this.status;
+ }
+
+ Status status_ = new Status();
+ Wait(status_);
+ try {
+ bufferHandle.commit();
+ // Whats happening?
+ // Actually in the native method Wait() the bufferHandle field is being
+ // set so here we need to commit it and read other info like type and size
+ // as below
+
+ bufferHandle.setSize(status_.numEls);
+
+ status_.type = bufferHandle.getSectionHeader();
+ status_.numEls = bufferHandle.getSectionSize();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ complete(status_);
+ this.completed = true;
+ this.status = status_;
+ return status_;
+ }
+
+ private native Status Wait(Status stat);
+
+ public Status itest() {
+
+ if (this.completed) {
+ return null;
+ }
+
+ Status result = new Status();
+ // res1 and result are the same ..
+ Status res1 = Test(result);
+ if (res1 == null) {
+ return null;
+ } else {
+ try {
+ bufferHandle.commit();
+ // Whats happening?
+ // Actually in the native method Wait() the bufferHandle field is being
+ // set so here we need to commit it and read other info like type and
+ // size as below
+
+ bufferHandle.setSize(res1.numEls);
+
+ res1.type = bufferHandle.getSectionHeader();
+ res1.numEls = bufferHandle.getSectionSize();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ complete(res1);
+ this.completed = true;
+ this.status = res1;
+ return res1;
+ }
+
+ }
+
+ private native Status Test(Status stat);
+
+}
diff --git a/src/mpjdev/natmpjdev/NativeRequest.java b/src/mpjdev/natmpjdev/NativeRequest.java
new file mode 100644
index 0000000..c0e6bcb
--- /dev/null
+++ b/src/mpjdev/natmpjdev/NativeRequest.java
@@ -0,0 +1,74 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : NativeRequest.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+package mpjdev.natmpjdev;
+
+import mpjdev.Status;
+
+public abstract class NativeRequest extends mpjdev.Request {
+
+ protected long commHandle; // used in iwait in NativeRecvRequest
+ // for recving dynamic buffer
+
+ public long handle;
+ protected mpjbuf.Buffer bufferHandle;
+
+
+ volatile boolean completed = false;
+
+ mpjdev.Status status = null;
+
+ // These two function are implemented by NativeRecvRequest and NativeSendRequest
+ public abstract Status iwait();
+
+ public abstract Status itest();
+
+ /**
+ * The methods below are not implemented yet. They are here in order to
+ * compile code :)
+ **/
+
+ public boolean cancel() {
+ return false;
+ }
+
+ public boolean isnull() {
+ return false;
+ }
+
+ public void free() {
+ }
+
+} // ends class Request.java
diff --git a/src/mpjdev/natmpjdev/NativeSendRequest.java b/src/mpjdev/natmpjdev/NativeSendRequest.java
new file mode 100644
index 0000000..f6d4dd3
--- /dev/null
+++ b/src/mpjdev/natmpjdev/NativeSendRequest.java
@@ -0,0 +1,90 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : NativeSendRequest.java
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+package mpjdev.natmpjdev;
+
+import mpjdev.Status;
+
+public class NativeSendRequest extends NativeRequest {
+
+ long dbufHandle; // dynamicBuffer handle
+ int dbuflen; // dynamicBuffer length
+
+ private static native void initNativeSendRequest();
+
+ static {
+ initNativeSendRequest();
+ }
+
+ // constructor
+ protected NativeSendRequest() {
+ // nothing here
+ }
+
+ public Status iwait() {
+
+ if (completed) {
+ return this.status;
+ }
+
+ Status result = new Status();
+ Wait(result); // native Wait()
+ complete(result);
+ this.completed = true;
+ return result;
+
+ }
+
+ private native Status Wait(Status stat);
+
+ public Status itest() {
+ if (this.completed) {
+ return null;
+ }
+ Status result = new Status();
+ if (Test(result) == null)
+ return null;
+ else {
+ complete(result);
+ this.completed = true;
+ this.status = result;
+ }
+ return result;
+ }
+
+ private native Status Test(Status stat);
+
+}
diff --git a/src/mpjdev/natmpjdev/lib/CMakeLists.txt b/src/mpjdev/natmpjdev/lib/CMakeLists.txt
new file mode 100644
index 0000000..8eb2104
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 2.6)
+
+project(nativempjdev C)
+
+SET( SOURCE_FILES
+ mpjdev_natmpjdev_Comm.c
+ mpjdev_natmpjdev_Group.c
+ mpjdev_natmpjdev_NativeRecvRequest.c
+ mpjdev_natmpjdev_NativeSendRequest.c
+ mpjdev_natmpjdev_Intracomm.c
+ mpjdev_natmpjdev_Intercomm.c
+)
+#SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY $ENV{MPJ_HOME}/lib)
+ADD_LIBRARY(nativempjdev SHARED ${SOURCE_FILES})
+
+find_package(MPI)
+if(MPI_FOUND)
+set(CMAKE_COMPILE_FLAGS ${CMAKE_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS})
+set(CMAKE_LINK_FLAGS ${CMAKE_LINK_FLAGS} ${MPI_LINK_FLAGS})
+
+include_directories(${MPI_INCLUDE_PATH} $ENV{JAVA_HOME}/include $ENV{JAVA_HOME}/include/linux)
+endif(MPI_FOUND)
+target_link_libraries(nativempjdev ${MPI_LIBRARIES})
+install(TARGETS nativempjdev DESTINATION $ENV{MPJ_HOME}/lib)
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.c
new file mode 100644
index 0000000..d298ef4
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.c
@@ -0,0 +1,976 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : mpjdev_natmpjdev_Comm.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+#include "mpjdev_natmpjdev_Comm.h"
+#include "mpi.h"
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include "mpjdev_natmpjdev_shared.h"
+//for ltdl
+#ifdef __unix__
+#include <dlfcn.h>
+#elif __linux__
+#include <dlfcn.h>
+#endif
+
+jfieldID mpjdev_natmpjdev_Comm_CommhandleID;
+
+static JavaVM *jvm;
+static int mpiTagUB;
+static void *mpilibhandle=NULL;
+
+jclass CL_mpjbuf_NIOBuffer;
+jclass CL_mpjbuf_Buffer;
+jclass CL_mpjdev_Status;
+// used in send/recv
+jfieldID FID_mpjbuf_Buffer_staticBuffer;
+jfieldID FID_mpjbuf_Buffer_dynamicBuffer;
+jfieldID FID_mpjbuf_Buffer_capacity;
+jfieldID FID_mpjbuf_Buffer_size;
+jfieldID FID_mpjbuf_NIOBuffer_buffer;
+
+jfieldID mpjdev_Status_sourceID;
+jfieldID mpjdev_Status_tagID;
+//jfieldID mpjdev_Status_stathandleID;
+jfieldID mpjdev_Status_indexID;
+jfieldID mpjdev_Status_numEls;
+jfieldID mpjdev_Status_countInBytes;
+
+/* JNI caching
+ * JNI_OnLoad()
+ *
+ */
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+
+ JNIEnv *env;
+ jvm = vm; //the static
+
+ if (JNI_OK != (*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6)) {
+ exit(1);
+ }
+
+ //caching classes and flieds
+
+ CL_mpjbuf_Buffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env, "mpjbuf/Buffer"));
+ CL_mpjbuf_NIOBuffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env, "mpjbuf/NIOBuffer"));
+
+ FID_mpjbuf_Buffer_size = (*env)->GetFieldID(env, CL_mpjbuf_Buffer, "size",
+ "I");
+
+ CL_mpjdev_Status = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env, "mpjdev/Status"));
+
+ mpjdev_Status_sourceID = (*env)->GetFieldID(env, CL_mpjdev_Status, "source",
+ "I");
+
+ mpjdev_Status_tagID = (*env)->GetFieldID(env, CL_mpjdev_Status, "tag", "I");
+
+ mpjdev_Status_indexID = (*env)->GetFieldID(env, CL_mpjdev_Status, "index",
+ "I");
+
+ mpjdev_Status_numEls = (*env)->GetFieldID(env, CL_mpjdev_Status, "numEls",
+ "I");
+
+ mpjdev_Status_countInBytes = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "countInBytes", "I");
+
+ // x = (*env)->GetFieldID(env,CL_mpjdev_Status,"numEls","I");
+
+ FID_mpjbuf_Buffer_capacity = (*env)->GetFieldID(env, CL_mpjbuf_Buffer,
+ "capacity", "I");
+
+ FID_mpjbuf_Buffer_staticBuffer = (*env)->GetFieldID(env, CL_mpjbuf_Buffer,
+ "staticBuffer", "Lmpjbuf/RawBuffer;");
+
+ FID_mpjbuf_Buffer_dynamicBuffer = (*env)->GetFieldID(env, CL_mpjbuf_Buffer,
+ "dynamicBuffer", "[B");
+
+ FID_mpjbuf_NIOBuffer_buffer = (*env)->GetFieldID(env, CL_mpjbuf_NIOBuffer,
+ "buffer", "Ljava/nio/ByteBuffer;");
+
+ if (FID_mpjbuf_Buffer_staticBuffer && FID_mpjbuf_Buffer_size
+ && FID_mpjbuf_NIOBuffer_buffer && FID_mpjbuf_Buffer_capacity) {
+
+ return JNI_VERSION_1_6;
+
+ } else {
+ fprintf(stderr, "\n Fatal error getting FIDs");
+ exit(3);
+ }
+
+}
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: loadGlobalLibraries
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_mpjdev_natmpjdev_Comm_loadGlobalLibraries
+ (JNIEnv *env, jclass thisObject) {
+ //This will make sure the library is loaded
+ // specially in the case of Open MPI
+ #ifdef OMPI_MPI_H
+ if (NULL == (mpilibhandle = dlopen("libmpi.so",
+ RTLD_NOW | RTLD_GLOBAL))) {
+ return JNI_FALSE;
+ }
+ #endif
+ return JNI_TRUE;
+}
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: getTagUB
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_getTagUB(JNIEnv *env,
+ jclass thisClass) {
+
+ MPI_Aint * maxTag;
+ //void * maxTag;
+ int error, flag;
+
+ error = MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &maxTag, &flag);
+
+ if(error != MPI_SUCCESS || !flag ){
+ printf( " ERROR IN native mpitagub\n");
+ }
+
+ return *maxTag;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: getWorld
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_getWorld(JNIEnv *env,
+ jclass thisClass) {
+ return (jlong) MPI_COMM_WORLD;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: dup
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_dup(JNIEnv *env,
+ jobject thisObject, jlong comm) {
+
+ MPI_Comm newComm;
+ int errCode = MPI_Comm_dup((MPI_Comm) (intptr_t) comm, &newComm);
+
+ return (long) newComm;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: rank
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_rank(JNIEnv *env,
+ jobject thisObject, jlong comm) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+ int rank;
+ int eerCode = MPI_Comm_rank(mpi_comm, &rank);
+
+ return rank;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: size
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_size(JNIEnv *env,
+ jobject thisObject, jlong comm) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+ int size;
+ int eerCode = MPI_Comm_size(mpi_comm, &size);
+
+ return size;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: create
+ * Signature: (J[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_create(JNIEnv *env,
+ jobject thisObject, jlong comm, jintArray ids) {
+
+ MPI_Comm newComm;
+ MPI_Group existingGroup, newGroup;
+
+ int size;
+ jint *pids;
+ int errCode;
+
+ MPI_Comm existingComm = (MPI_Comm) (intptr_t) comm;
+ MPI_Comm_group(existingComm, &existingGroup);
+
+ size = (*env)->GetArrayLength(env, ids);
+ pids = (*env)->GetIntArrayElements(env, ids, 0); // 0 or JNI_COPY?
+ errCode = MPI_Group_incl(existingGroup, size, (int*) pids, &newGroup);
+
+ (*env)->ReleaseIntArrayElements(env, ids, pids, JNI_ABORT);
+
+ errCode = MPI_Comm_create(existingComm, newGroup, &newComm);
+
+ if (newComm == MPI_COMM_NULL) {
+ // printf("Nativ: Comm - is NULL\n");
+ return 0;
+ } else
+ return (jlong) newComm;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSplit
+ * Signature: (JII)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeSplit(JNIEnv *env,
+ jobject thisObject, jlong comm, jint color, jint key) {
+
+ int errCode;
+ MPI_Comm newComm;
+ MPI_Comm existingComm = (MPI_Comm) (intptr_t) comm;
+
+ errCode = MPI_Comm_split(comm, color, key, &newComm);
+
+ if (newComm == MPI_COMM_NULL) {
+ printf("Nativ: Comm Split- newComm is returning NULL\n");
+ return 0;
+ } else
+ return (jlong) newComm;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeCreate
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeCreate(JNIEnv *env,
+ jobject thisObject, jlong group) {
+
+ int errCode;
+ MPI_Comm newComm;
+
+ MPI_Group existingGroup = (MPI_Group) (intptr_t) group;
+ MPI_Comm existingComm = (MPI_Comm)(*env)->GetLongField(env, thisObject,
+ mpjdev_natmpjdev_Comm_CommhandleID);
+
+ errCode = MPI_Comm_create(existingComm, existingGroup, &newComm);
+
+ if (newComm == MPI_COMM_NULL) {
+ // printf("Nativ: Comm - nativeCreate is returning NULL\n");
+ return 0;
+ } else
+ return (jlong) newComm;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeCreateIntercomm
+ * Signature: (JJIII)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeCreateIntercomm(
+ JNIEnv *env, jobject thisObject, jlong peerComm_, jlong localComm_,
+ jint localleader, jint remoteleader, jint tag) {
+
+ int errCode;
+ MPI_Comm peerComm = (MPI_Comm) (intptr_t) peerComm_;
+ MPI_Comm localComm = (MPI_Comm) (intptr_t) localComm_;
+ MPI_Comm newIntercomm;
+
+ errCode = MPI_Intercomm_create(localComm, localleader, peerComm, remoteleader,
+ tag, &newIntercomm);
+
+ if (errCode == MPI_SUCCESS) {
+ //printf("Nativ: Comm - nativeIntercommCreate MPI_SUCCESS \n");
+ } else {
+ printf("Nativ: Comm - nativeIntercommCreate returned not MPI_SUCCESS\n");
+ }
+
+ return (jlong) newIntercomm;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_free
+(JNIEnv *env, jobject thisObject, jlong comm) {
+
+ MPI_Comm existingComm = (MPI_Comm) (intptr_t) comm;
+ int errCode = MPI_Comm_free(&existingComm);
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeInit
+ * Signature: ([Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeInit
+(JNIEnv *env, jclass thisClass, jobjectArray args) {
+ //the logic of this function is almost same as of mpi-Java
+
+ jclass string = (*env)->FindClass(env, "java/lang/String");
+ int len = (*env)->GetArrayLength(env, args);
+ char ** sargs = (char**) calloc(len+1, sizeof(char*));
+ int errCode;
+ int rank, len_of_proc_name;
+ char name[MPI_MAX_PROCESSOR_NAME];
+ jobject newArgs;
+
+ int i;
+ int flag;
+
+ //parse the args array element wise and populate the sargs
+ for (i=0; i<len; i++) {
+ int slen;
+
+ jstring jc = (jstring)(*env)->GetObjectArrayElement(env, args, i);
+ slen = strlen((*env)->GetStringUTFChars(env, jc, 0)) + 1; //why plus one?
+ sargs[i] = (char*) calloc(slen, sizeof(char));
+
+ #ifdef WIN32
+ strcpy_s(sargs[i], slen, (*env)->GetStringUTFChars(env, jc, 0));
+ #elif _WIN64
+ strcpy_s(sargs[i], slen, (*env)->GetStringUTFChars(env, jc, 0));
+ #elif _WIN32
+ strcpy_s(sargs[i], slen, (*env)->GetStringUTFChars(env, jc, 0));
+ #elif __unix__
+ strcpy(sargs[i], (*env)->GetStringUTFChars(env, jc, 0));
+ #elif __linux__
+ strcpy(sargs[i], (*env)->GetStringUTFChars(env, jc, 0));
+ #endif
+ }
+
+ errCode = MPI_Init(&len, &sargs);
+
+ //cache the handle
+ mpjdev_natmpjdev_Comm_CommhandleID = (*env)->GetFieldID(env, thisClass,
+ "handle", "J");
+
+ MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &mpiTagUB, &flag);
+
+ /*
+ * Print the name of the computer node where this rank is executed
+ * */
+ MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+ MPI_Get_processor_name(name, &len_of_proc_name);
+ printf("Starting process <%d> on on <%s>\n", rank, name);
+ fflush(stdout);
+
+ /* we are not returning the new arguments (the modified ones from MPI_Init()??
+ * but mpi-Java is returning. I am just providing that logic of returning the
+ * new arguments in this comment section, perhaps for future use....
+
+ jobject newArgs = (*env)->NewObjectArray(env, len, string, NULL);
+
+ for(i=0, i<len, i++){
+ jstring jc = (*env)->NewStringUTF(env, sargs[i]);
+ (*env)->SetObjectArrayElement(env, newArgs, i, jc);
+ }
+
+ return newArgs;
+ */
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeFinish
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeFinish
+(JNIEnv *env, jclass thisClass) {
+
+ int errCode = MPI_Finalize();
+
+ if (errCode != MPI_SUCCESS) {
+ printf("Error in MPI_Finalize()\n");
+ fflush(stdout);
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: group
+ * Signature: ()J
+ *
+ * This function returns the default group of the CommhandleID
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_group(JNIEnv *env,
+ jobject thisObject) {
+
+ MPI_Group group;
+
+ MPI_Comm existingComm = (MPI_Comm)(*env)->GetLongField(env, thisObject,
+ mpjdev_natmpjdev_Comm_CommhandleID);
+ MPI_Comm_group(existingComm, &group);
+
+ return (jlong) group;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: GetComm
+ * Signature: (I)V
+ *
+ * This function sets the Comm.
+ * 0 = COMM_NULL
+ * 1 = COMM_SELF
+ * 2 = COMM_WORLD is mostly the case
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_GetComm
+(JNIEnv *env, jobject thisObject, jint type) {
+
+ switch (type) {
+ case 0:
+ (*env)->SetLongField(env, thisObject, mpjdev_natmpjdev_Comm_CommhandleID,
+ (jlong)MPI_COMM_NULL);
+ break;
+ case 1:
+ (*env)->SetLongField(env, thisObject, mpjdev_natmpjdev_Comm_CommhandleID,
+ (jlong)MPI_COMM_SELF);
+ break;
+ case 2:
+ (*env)->SetLongField(env, thisObject, mpjdev_natmpjdev_Comm_CommhandleID,
+ (jlong)MPI_COMM_WORLD);
+ break;
+ default:
+ break;
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSend
+ * Signature: (JLmpjbuf/Buffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeSend
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint dest, jint tag,
+ jint sbufLen, jint dbufLen) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+
+ /*Declarations for staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char * buffer_address = NULL;
+
+ /* Declarations for dynamicBuffer */
+
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray dynamicBuffer;
+ jbyte * dBuffer;
+
+ /* Get the static Buffer Related things.. */
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env,staticBuffer,FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)directBuffer);
+ jlong capacity = (*env)->GetDirectBufferCapacity(env,(jobject) directBuffer);
+
+ //.. write the first eight bytes ..
+ // _________________________
+ // | E | X | X | X | DSIZE |
+ // -------------------------
+ if(dbufLen > 0) {
+
+ char encoding = 1;
+ buffer_address[0] = encoding;
+ buffer_address[4] = (((unsigned int) dbufLen) >> 24) & 0xFF;
+ buffer_address[5] = (((unsigned int) dbufLen) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbufLen) >> 8) & 0xFF;
+ buffer_address[7] = ((unsigned int) dbufLen) & 0xFF;
+
+ } else {
+ char encoding = 0;
+ buffer_address[0] = encoding;
+ }
+ //TODO: in case of dynamic buffer Optimize this by doing isend here and imediately a send
+ // and later a wait() on this isend for staticbuffer
+ MPI_Send(buffer_address,sbufLen,MPI_BYTE,dest,tag,mpi_comm);
+
+ if(dbufLen > 0) {
+ dynamicBuffer = (jbyteArray)(*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_dynamicBuffer);
+
+ dBuffer = (*env)->GetByteArrayElements(env,dynamicBuffer,&isCopy);
+ //TODO: do something about this magic number
+ MPI_Send(dBuffer,dbufLen,MPI_BYTE,dest,tag+10001,mpi_comm);
+ (*env)->ReleaseByteArrayElements(env,dynamicBuffer,dBuffer,0);
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeRecv
+ * Signature: (JLmpjbuf/Buffer;IIILmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeRecv
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint size, jint src,
+ jint tag, jobject status) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+
+ jboolean isCopy = JNI_TRUE;
+
+ /* Declarations of staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ MPI_Status mpi_status, mpi_status_dyn;
+ int elements;
+ char * buffer_address = NULL;
+
+ /* Declarations of Dynamic Buffer */
+
+ jbyteArray darr;
+ jbyte * dBuffer;
+ int dbuf_len = 0;
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (jbyteArray)(*env)->GetObjectField(env,staticBuffer,FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directBuffer);
+
+ int src_ = src;
+ int tag_ = tag;
+
+ if(src == -2)
+ src_ = MPI_ANY_SOURCE;
+ if(tag == -2)
+ tag_ = MPI_ANY_TAG;
+
+ // size = sizeInBytes of StaticBuffer
+ MPI_Recv(buffer_address,size,MPI_BYTE,src_,tag_,comm,&mpi_status);
+
+ char encoding = 0;
+ int x;
+
+ encoding = buffer_address[0];
+ if(encoding == 1) {
+ x = (((int)(unsigned char) buffer_address[4]) << 24) |
+ (((int)(unsigned char) buffer_address[5]) << 16) |
+ (((int)(unsigned char) buffer_address[6]) << 8) |
+ (((int)(unsigned char) buffer_address[7]) );
+
+ dbuf_len = x;
+ }
+ // Following 2 lines are important!
+
+ MPI_Get_count(&mpi_status, MPI_BYTE, &elements);
+
+ // setting this from nativ/Comm.c in recv() from sectionsize
+ (*env)->SetIntField(env,buf,FID_mpjbuf_Buffer_size,elements);
+
+ // I am also setting this because we need it in mpi/Status Get_count
+ // method: TODO remove magic numbers
+ (*env)->SetIntField(env, status, mpjdev_Status_countInBytes,
+ (jint) (elements - 8-8));// 8 is the size of section header
+ // and 8 recv overhead
+
+ (*env)->SetIntField(env, status, mpjdev_Status_sourceID,
+ mpi_status.MPI_SOURCE);
+
+ (*env)->SetIntField(env, status, mpjdev_Status_tagID,
+ mpi_status.MPI_TAG);
+
+ //recv dynamic buf
+ if(dbuf_len > 0) {
+
+ darr = (*env)->NewByteArray (env, dbuf_len);
+ // perhaps no need for this - use malloc instead
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+
+ MPI_Recv(dBuffer,dbuf_len,MPI_BYTE,src_,tag_+10001,comm,&mpi_status_dyn);
+
+ (*env)->SetByteArrayRegion(env,darr,0,dbuf_len,dBuffer);
+
+ jmethodID setdbuf = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, buf, setdbuf, darr);
+
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSsend
+ * Signature: (JLmpjbuf/Buffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeSsend
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint dest, jint tag,
+ jint sbufLen, jint dbufLen) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+
+ /*Declarations for staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char * buffer_address = NULL;
+
+ /* Declarations for dynamicBuffer */
+
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray dynamicBuffer;
+ jbyte * dBuffer;
+
+ /* Get the static Buffer Related things.. */
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env,staticBuffer,FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)directBuffer);
+ jlong capacity = (*env)->GetDirectBufferCapacity(env,(jobject) directBuffer);
+
+ if(dbufLen > 0) {
+
+ char encoding = 1;
+ buffer_address[0] = encoding;
+ buffer_address[4] = (((unsigned int) dbufLen) >> 24) & 0xFF;
+ buffer_address[5] = (((unsigned int) dbufLen) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbufLen) >> 8) & 0xFF;
+ buffer_address[7] = ((unsigned int) dbufLen) & 0xFF;
+
+ } else {
+ char encoding = 0;
+ buffer_address[0] = encoding;
+ }
+ MPI_Ssend(buffer_address,sbufLen,MPI_BYTE,dest,tag,mpi_comm);
+
+ if(dbufLen > 0) {
+ dynamicBuffer = (jbyteArray)(*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_dynamicBuffer);
+
+ dBuffer = (*env)->GetByteArrayElements(env,dynamicBuffer,&isCopy);
+ //TODO: do something about this magic number
+ MPI_Ssend(dBuffer,dbufLen,MPI_BYTE,dest,tag+10001,mpi_comm);
+ (*env)->ReleaseByteArrayElements(env,dynamicBuffer,dBuffer,0);
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIssend
+ * Signature: (JLmpjbuf/Buffer;IIIILmpjdev/natmpjdev/NativeSendRequest;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIssend
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint dest,
+ jint tag, jint sbufLen, jint dbufLen, jobject request) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+ MPI_Request mpi_request;
+
+ /*
+ * Acquiring the handles on request (the java NativeSendRequest)
+ * These can go in the JNI_OnLoad()
+ */
+
+ jclass native_send_req_class = (*env)->GetObjectClass(env, request);
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, native_send_req_class, "bufferHandle",
+ "Lmpjbuf/Buffer;");
+ jfieldID dbufreqhandleID =
+ (*env)->GetFieldID(env, native_send_req_class, "dbufHandle", "J");
+
+ jfieldID dbuflenID =
+ (*env)->GetFieldID(env, native_send_req_class, "dbuflen", "I");
+
+ jfieldID reqhandleID = (*env)->GetFieldID(env,native_send_req_class, "handle","J");
+
+ /*Declarations for staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char * buffer_address = NULL;
+
+ /* Declarations for dynamicBuffer */
+
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray dynamicBuffer;
+ jbyte * dBuffer;
+
+ /* Get the static Buffer Related things.. */
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env,staticBuffer,FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)directBuffer);
+
+ if(dbufLen > 0) {
+
+ char encoding = 1;
+ buffer_address[0] = encoding;
+ buffer_address[4] = (((unsigned int) dbufLen) >> 24) & 0xFF;
+ buffer_address[5] = (((unsigned int) dbufLen) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbufLen) >> 8) & 0xFF;
+ buffer_address[7] = ((unsigned int) dbufLen) & 0xFF;
+
+ } else {
+ char encoding = 0;
+ buffer_address[0] = encoding;
+ }
+
+ MPI_Issend(buffer_address,sbufLen,MPI_BYTE,dest,tag,mpi_comm, &mpi_request);
+
+ /*
+ * Set the handles of mpi_request to the request (the java one)
+ */
+ (*env)->SetLongField(env, request, reqhandleID, (jlong)mpi_request);
+
+ (*env)->SetObjectField(env, request, bufferhandleID, buf);
+
+ if(dbufLen > 0) {
+
+ dynamicBuffer = (jbyteArray)(*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_dynamicBuffer);
+
+ MPI_Request mpi_request_dyn;
+ dBuffer = (*env)->GetByteArrayElements(env,dynamicBuffer,&isCopy);
+ MPI_Issend(dBuffer,dbufLen,MPI_BYTE,dest,tag+10001,mpi_comm,&mpi_request_dyn);
+
+ /*
+ * Set the handles of mpi_request_dyn to the request (the java one)
+ */
+ (*env)->SetIntField(env, request, dbuflenID, dbufLen);
+
+ (*env)->SetLongField(env, request, dbufreqhandleID,
+ (jlong) mpi_request_dyn);
+
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIsend
+ * Signature: (JLmpjbuf/Buffer;IIIILmpjdev/natmpjdev/NativeSendRequest;I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIsend
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint dest, jint tag,
+ jint sbufLen, jint dbufLen, jobject request) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+ MPI_Request mpi_request;
+
+ /*
+ * Acquiring the handles on request (the java NativeSendRequest)
+ * these can go in the JNI_OnLoad()
+ */
+
+ jclass native_send_req_class = (*env)->GetObjectClass(env, request);
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, native_send_req_class, "bufferHandle",
+ "Lmpjbuf/Buffer;");
+ jfieldID dbufreqhandleID =
+ (*env)->GetFieldID(env, native_send_req_class, "dbufHandle", "J");
+
+ jfieldID dbuflenID =
+ (*env)->GetFieldID(env, native_send_req_class, "dbuflen", "I");
+
+ jfieldID reqhandleID = (*env)->GetFieldID(env,native_send_req_class, "handle","J");
+
+ /*Declarations for staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char * buffer_address = NULL;
+
+ /* Declarations for dynamicBuffer */
+
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray dynamicBuffer;
+ jbyte * dBuffer;
+
+ /* Get the static Buffer Related things.. */
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env,staticBuffer,FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)directBuffer);
+
+ if(dbufLen > 0) {
+
+ char encoding = 1;
+ buffer_address[0] = encoding;
+ buffer_address[4] = (((unsigned int) dbufLen) >> 24) & 0xFF;
+ buffer_address[5] = (((unsigned int) dbufLen) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbufLen) >> 8) & 0xFF;
+ buffer_address[7] = ((unsigned int) dbufLen) & 0xFF;
+
+ } else {
+ char encoding = 0;
+ buffer_address[0] = encoding;
+ }
+
+ MPI_Isend(buffer_address,sbufLen,MPI_BYTE,dest,tag,mpi_comm, &mpi_request);
+
+ /*
+ * Set the handles of mpi_request to the request (the java one)
+ */
+ (*env)->SetLongField(env, request, reqhandleID, (jlong)mpi_request);
+
+ (*env)->SetObjectField(env, request, bufferhandleID, buf);
+
+ if(dbufLen > 0) {
+
+ dynamicBuffer = (jbyteArray)(*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_dynamicBuffer);
+
+ MPI_Request mpi_request_dyn;
+ dBuffer = (*env)->GetByteArrayElements(env,dynamicBuffer,&isCopy);
+ MPI_Isend(dBuffer,dbufLen,MPI_BYTE,dest,tag+10001,mpi_comm,&mpi_request_dyn);
+
+ /*
+ * Set the handles of mpi_request_dyn to the request (the java one)
+ */
+ (*env)->SetIntField(env, request, dbuflenID, dbufLen);
+
+ (*env)->SetLongField(env, request, dbufreqhandleID,
+ (jlong) mpi_request_dyn);
+
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIrecv
+ * Signature: (JLmpjbuf/Buffer;IILmpjdev/Status;Lmpjdev/natmpjdev/NativeRecvRequest;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIrecv
+(JNIEnv *env, jobject thisObject, jlong comm, jobject buf, jint src, jint tag,
+ jobject status, jobject request) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t)comm;
+ MPI_Request mpi_request;
+
+ /* Trying to get the Request's bufferHandleID */
+ jclass native_recv_req_class = (*env)->GetObjectClass(env, request);
+
+ jfieldID reqhandleID = (*env)->GetFieldID(env,native_recv_req_class,"handle","J");
+
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, native_recv_req_class,
+ "bufferHandle", "Lmpjbuf/Buffer;");
+
+ jboolean isCopy = JNI_TRUE;
+
+ /* Declarations of staticBuffer */
+
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+
+ int elements;
+ char * buffer_address = NULL;
+
+ /* Declarations of Dynamic Buffer */
+
+ jbyteArray darr;
+ jbyte * dBuffer;
+
+ staticBuffer = (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (jbyteArray)(*env)->GetObjectField(env,staticBuffer,
+ FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directBuffer);
+
+ jlong capacity = (*env)->GetDirectBufferCapacity(
+ env,(jobject) directBuffer);
+
+ int src_ = src;
+ int tag_ = tag;
+
+ if(src == -2)
+ src_ = MPI_ANY_SOURCE;
+ if(tag == -2)
+ tag_ = MPI_ANY_TAG;
+
+ MPI_Irecv(buffer_address,capacity,MPI_BYTE,src_,tag_,mpi_comm,&mpi_request);
+
+ (*env)->SetLongField(env,request,reqhandleID,(jlong)mpi_request);
+
+ (*env)->SetObjectField(env,request,bufferhandleID,buf);
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeProbe
+ * Signature: (JIILmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeProbe
+(JNIEnv *env, jobject thisObject, jlong comm, jint src, jint tag, jobject status) {
+
+ MPI_Comm mpi_comm = (MPI_Comm)(intptr_t) comm;
+ MPI_Status mpi_status;
+ int elements;
+
+ // Probe for an incoming message from process
+ MPI_Probe(src, tag, mpi_comm, &mpi_status);
+
+ // probe returns, the status object with the size and other
+ // attributes of the incoming message. Get the size of the message
+ MPI_Get_count(&mpi_status, MPI_BYTE, &elements);
+
+ // setting this because we need it in mpi/Status Get_count
+ // method: TODO remove these magic numbers
+ (*env)->SetIntField(env, status, mpjdev_Status_countInBytes,
+ (jint) (elements - 8 - 8));// 8 is the size of section header
+ // 8 recv overhead
+
+ (*env)->SetIntField(env, status, mpjdev_Status_sourceID,
+ mpi_status.MPI_SOURCE);
+
+ (*env)->SetIntField(env, status, mpjdev_Status_tagID,
+ mpi_status.MPI_TAG);
+
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.h
new file mode 100644
index 0000000..782c7ed
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Comm.h
@@ -0,0 +1,189 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_Comm */
+
+#ifndef _Included_mpjdev_natmpjdev_Comm
+#define _Included_mpjdev_natmpjdev_Comm
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: loadGlobalLibraries
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_mpjdev_natmpjdev_Comm_loadGlobalLibraries
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: getTagUB
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_getTagUB
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: getWorld
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_getWorld
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: dup
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_dup
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: rank
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_rank
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: size
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Comm_size
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: create
+ * Signature: (J[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_create
+ (JNIEnv *, jobject, jlong, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSplit
+ * Signature: (JII)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeSplit
+ (JNIEnv *, jobject, jlong, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeCreate
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeCreate
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeCreateIntercomm
+ * Signature: (JJIII)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_nativeCreateIntercomm
+ (JNIEnv *, jobject, jlong, jlong, jint, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_free
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeInit
+ * Signature: ([Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeInit
+ (JNIEnv *, jclass, jobjectArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeFinish
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeFinish
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: group
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Comm_group
+ (JNIEnv *, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: GetComm
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_GetComm
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSend
+ * Signature: (JLmpjbuf/Buffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeSend
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeRecv
+ * Signature: (JLmpjbuf/Buffer;IIILmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeRecv
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jint, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeSsend
+ * Signature: (JLmpjbuf/Buffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeSsend
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIssend
+ * Signature: (JLmpjbuf/Buffer;IIIILmpjdev/natmpjdev/NativeSendRequest;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIssend
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jint, jint, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIsend
+ * Signature: (JLmpjbuf/Buffer;IIIILmpjdev/natmpjdev/NativeSendRequest;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIsend
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jint, jint, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeIrecv
+ * Signature: (JLmpjbuf/Buffer;IILmpjdev/Status;Lmpjdev/natmpjdev/NativeRecvRequest;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeIrecv
+ (JNIEnv *, jobject, jlong, jobject, jint, jint, jobject, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Comm
+ * Method: nativeProbe
+ * Signature: (JIILmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Comm_nativeProbe
+ (JNIEnv *, jobject, jlong, jint, jint, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.c
new file mode 100644
index 0000000..89dc517
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.c
@@ -0,0 +1,437 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ /*
+ * File : mpjdev_natmpjdev_Group.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+#include "mpjdev_natmpjdev_Group.h"
+#include "mpi.h"
+#include "mpjdev_natmpjdev_shared.h"
+#include <inttypes.h>
+#include <stdlib.h> // for malloc
+jfieldID GrouphandleID;
+
+/* class mpjdev_natmpjdev_Group */
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: init
+ * Signature: ()V
+ *
+ * This function is called once in the static region of mpjdev.Group class
+ * it only gets the field ID for handle in the global jfieldID GrouphandleID
+ * so that we don't have to
+ * do a lookup each time its used.
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_init
+(JNIEnv *env, jclass thisClass) {
+
+ GrouphandleID = (*env)->GetFieldID(env, thisClass, "handleOfGroup", "J");
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: GetGroup
+ * Signature: (I)V
+ *
+ * This function set the group to either the default group i.e. the group of
+ * universal COMM_WORLD (typeOfWorld == 2) or it sets to MPI_GROUP_EMPTY
+ * (typeOfWorld == 3)
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_GetGroup
+(JNIEnv *env, jobject thisObject, jint typeOfWorld) {
+
+ MPI_Group group;
+ switch (typeOfWorld) {
+ case 2:
+ MPI_Comm_group(MPI_COMM_WORLD, &group);
+ (*env)->SetLongField(env, thisObject, GrouphandleID, (jlong)group);
+ break;
+ case 3:
+ (*env)->SetLongField(env, thisObject, GrouphandleID, (jlong)MPI_GROUP_EMPTY);
+ break;
+ default:
+ break;
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeFree
+ * Signature: ()V
+ *
+ * Free the group and set the handle to MPI_GROUP_NULL
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_nativeFree
+(JNIEnv *env, jobject thisObject) {
+
+ MPI_Group group = (MPI_Group)((*env)->GetLongField(env, thisObject,
+ GrouphandleID));
+ MPI_Group_free(&group);
+
+ (*env)->SetLongField(env, thisObject, GrouphandleID, (jlong)MPI_GROUP_NULL);
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeSize
+ * Signature: ()I
+ *
+ * Size of the group
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeSize(JNIEnv *env,
+ jobject thisObject) {
+ int size;
+
+ MPI_Group group = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+ int errCode = MPI_Group_size(group, &size);
+
+ if (errCode != MPI_SUCCESS)
+ return -1;
+ else
+ return size;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRank
+ * Signature: ()I
+ *
+ * Rank of this process with in the group
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeRank(JNIEnv *env,
+ jobject thisObject) {
+
+ int rank;
+
+ MPI_Group group = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+ int errCode = MPI_Group_rank(group, &rank);
+
+ if (errCode == MPI_ERR_GROUP || errCode == MPI_ERR_ARG) {
+ printf("native Group Rank returned with error !\n");
+ fflush (stdout);
+ rank = -1;
+
+ }
+
+ if (rank < 0)
+ return -1;
+
+ return rank;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeIncl
+ * Signature: ([I)J
+ *
+ * Incl for group
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeIncl(JNIEnv *env,
+ jobject thisObject, jintArray ranks) {
+
+ int n;
+ jint *rks;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Group newGroup;
+
+ n = (*env)->GetArrayLength(env, ranks);
+ rks = (*env)->GetIntArrayElements(env, ranks, &isCopy);
+
+ MPI_Group existingGroup = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+
+ MPI_Group_incl(existingGroup, n, (int*) rks, &newGroup);
+
+ (*env)->ReleaseIntArrayElements(env, ranks, rks, 0);
+
+ return (jlong) newGroup;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeExcl
+ * Signature: ([I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeExcl(JNIEnv *env,
+ jobject thisObject, jintArray ranks) {
+
+ int n;
+ jint *rks;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Group newGroup;
+
+ n = (*env)->GetArrayLength(env, ranks);
+ rks = (*env)->GetIntArrayElements(env, ranks, &isCopy);
+
+ MPI_Group existingGroup = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+
+ int errCode = MPI_Group_excl(existingGroup, n, (int*) rks, &newGroup);
+
+ (*env)->ReleaseIntArrayElements(env, ranks, rks, 0);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("Nativ: Group - nativeExcl Failed errCode = %d\n", errCode);
+ return 0;
+ } else
+ return (jlong) newGroup;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRangeIncl
+ * Signature: (I[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeRangeIncl(JNIEnv *env,
+ jobject thisObject, jint n, jintArray oneDimRanges) {
+
+ int oneDimRangesLen;
+ jint *nativeOneDimRanges;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Group newGroup;
+
+ oneDimRangesLen = (*env)->GetArrayLength(env, oneDimRanges);
+ nativeOneDimRanges = (*env)->GetIntArrayElements(env, oneDimRanges, &isCopy);
+
+ MPI_Group existingGroup = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+
+ int errCode = MPI_Group_range_incl(existingGroup, n,
+ (int (*)[3]) nativeOneDimRanges, &newGroup);
+
+ (*env)->ReleaseIntArrayElements(env, oneDimRanges, nativeOneDimRanges, 0);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("Nativ: Group - nativeRangeIncl Failed errCode = %d\n", errCode);
+ return 0;
+ } else
+ return (jlong) newGroup;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRangeExcl
+ * Signature: (I[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeRangeExcl(JNIEnv *env,
+ jobject thisObject, jint n, jintArray oneDimRanges) {
+
+ int oneDimRangesLen;
+ jint *nativeOneDimRanges;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Group newGroup;
+
+ oneDimRangesLen = (*env)->GetArrayLength(env, oneDimRanges);
+ nativeOneDimRanges = (*env)->GetIntArrayElements(env, oneDimRanges, &isCopy);
+
+ MPI_Group existingGroup = (MPI_Group)(
+ (*env)->GetLongField(env, thisObject, GrouphandleID));
+
+ int errCode = MPI_Group_range_excl(existingGroup, n,
+ (int (*)[3]) nativeOneDimRanges, &newGroup);
+
+ (*env)->ReleaseIntArrayElements(env, oneDimRanges, nativeOneDimRanges, 0);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("Nativ: Group - nativeRangeExcl Failed errCode = %d\n", errCode);
+ return 0;
+ } else
+ return (jlong) newGroup;
+
+}
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativetransRanks
+ * Signature: (JJ[I)[I
+ */
+JNIEXPORT jintArray JNICALL Java_mpjdev_natmpjdev_Group_nativetransRanks(
+ JNIEnv *env, jclass thisClass, jlong group1_, jlong group2_,
+ jintArray ranks) {
+
+ int errCode;
+ int n;
+ jintArray result;
+ jint *rks, *rks2;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Group group1 = (MPI_Group) (intptr_t) group1_;
+ MPI_Group group2 = (MPI_Group) (intptr_t) group2_;
+
+ n = (*env)->GetArrayLength(env, ranks);
+ rks = (*env)->GetIntArrayElements(env, ranks, &isCopy);
+ rks2 = malloc(sizeof(int) * n);
+ result = (*env)->NewIntArray(env, n);
+
+ if (result == NULL) {
+ return NULL; /* out of memory error thrown */
+ }
+
+ errCode = MPI_Group_translate_ranks(group1, n, (int*) rks, group2,
+ (int*) rks2);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("Nativ: Group - nativetransRanks Failed errCode = %d\n", errCode);
+ free(rks2);
+ (*env)->ReleaseIntArrayElements(env, ranks, rks, 0);
+ return NULL;
+ }
+
+ (*env)->ReleaseIntArrayElements(env, ranks, rks, 0);
+
+ // move from rks2 to the java jintArray result
+ (*env)->SetIntArrayRegion(env, result, 0, n, rks2);
+
+ free(rks2);
+
+ return (jintArray) result;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeCompare
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeCompare(JNIEnv *env,
+ jobject thisObject, jlong _group1, jlong _group2) {
+
+ int result;
+ int errCode;
+
+ MPI_Group group1 = (MPI_Group) (intptr_t) _group1;
+ MPI_Group group2 = (MPI_Group) (intptr_t) _group2;
+
+ errCode = MPI_Group_compare(group1, group2, &result);
+
+ // here return the result as MPJ Express macros
+ // as per MPJ Express 0.38
+ // NO_RANK = -1, IDENT = 0, CONGRUENT = 3, SIMILAR = 1, UNEQUAL = 2;
+ // UNDEFINED = -1;
+
+ if (errCode == MPI_SUCCESS) {
+
+ if (result == MPI_IDENT) {
+ return IDENT;
+ } else if (result == MPI_SIMILAR) {
+ return SIMILAR;
+ } else if (result == MPI_UNEQUAL) {
+ return UNEQUAL;
+ }
+ } else if (errCode == MPI_ERR_GROUP || errCode == MPI_ERR_ARG) {
+ //error !
+ printf("nativeCompare error = %d \n", errCode);
+ return -1; // UNDEFINED
+ }
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeUnion
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeUnion(JNIEnv *env,
+ jobject thisObject, jlong group1_, jlong group2_) {
+
+ int result;
+ int errCode;
+
+ MPI_Group group1 = (MPI_Group) (intptr_t) group1_;
+ MPI_Group group2 = (MPI_Group) (intptr_t) group2_;
+ MPI_Group newGroup;
+ errCode = MPI_Group_union(group1, group2, &newGroup);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("nativeUnion not MPI_SUCCESS\n");
+ return -1;
+ }
+
+ return (jlong) newGroup;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeIntersection
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeIntersection(
+ JNIEnv *env, jobject thisObject, jlong group1_, jlong group2_) {
+
+ int result;
+ int errCode;
+
+ MPI_Group group1 = (MPI_Group) (intptr_t) group1_;
+ MPI_Group group2 = (MPI_Group) (intptr_t) group2_;
+ MPI_Group newGroup;
+ errCode = MPI_Group_intersection(group1, group2, &newGroup);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("nativeIntersection not MPI_SUCCESS\n");
+ return -1;
+ }
+
+ return (jlong) newGroup;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeDifference
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeDifference(
+ JNIEnv *env, jobject thisObject, jlong group1_, jlong group2_) {
+
+ int result;
+ int errCode;
+
+ MPI_Group group1 = (MPI_Group) (intptr_t) group1_;
+ MPI_Group group2 = (MPI_Group) (intptr_t) group2_;
+ MPI_Group newGroup;
+ errCode = MPI_Group_difference(group1, group2, &newGroup);
+
+ if (errCode != MPI_SUCCESS) {
+ printf("nativeDifference not MPI_SUCCESS\n");
+ return -1;
+ }
+
+ return (jlong) newGroup;
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.h
new file mode 100644
index 0000000..fef0168
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Group.h
@@ -0,0 +1,137 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_Group */
+
+#ifndef _Included_mpjdev_natmpjdev_Group
+#define _Included_mpjdev_natmpjdev_Group
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef mpjdev_natmpjdev_Group_NO_RANK
+#define mpjdev_natmpjdev_Group_NO_RANK -1L
+#undef mpjdev_natmpjdev_Group_IDENT
+#define mpjdev_natmpjdev_Group_IDENT 0L
+#undef mpjdev_natmpjdev_Group_CONGRUENT
+#define mpjdev_natmpjdev_Group_CONGRUENT 3L
+#undef mpjdev_natmpjdev_Group_SIMILAR
+#define mpjdev_natmpjdev_Group_SIMILAR 1L
+#undef mpjdev_natmpjdev_Group_UNEQUAL
+#define mpjdev_natmpjdev_Group_UNEQUAL 2L
+#undef mpjdev_natmpjdev_Group_UNDEFINED
+#define mpjdev_natmpjdev_Group_UNDEFINED -1L
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_init
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: GetGroup
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_GetGroup
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeFree
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Group_nativeFree
+ (JNIEnv *, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeSize
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeSize
+ (JNIEnv *, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRank
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeRank
+ (JNIEnv *, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeIncl
+ * Signature: ([I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeIncl
+ (JNIEnv *, jobject, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeExcl
+ * Signature: ([I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeExcl
+ (JNIEnv *, jobject, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRangeIncl
+ * Signature: (I[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeRangeIncl
+ (JNIEnv *, jobject, jint, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeRangeExcl
+ * Signature: (I[I)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeRangeExcl
+ (JNIEnv *, jobject, jint, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativetransRanks
+ * Signature: (JJ[I)[I
+ */
+JNIEXPORT jintArray JNICALL Java_mpjdev_natmpjdev_Group_nativetransRanks
+ (JNIEnv *, jclass, jlong, jlong, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeCompare
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Group_nativeCompare
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeUnion
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeUnion
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeIntersection
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeIntersection
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Group
+ * Method: nativeDifference
+ * Signature: (JJ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Group_nativeDifference
+ (JNIEnv *, jclass, jlong, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.c
new file mode 100644
index 0000000..8a58db5
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.c
@@ -0,0 +1,68 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ /*
+ * File : mpjdev_natmpjdev_Intercomm.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+#include "mpjdev_natmpjdev_Intercomm.h"
+#include "mpi.h"
+#include <inttypes.h>
+/* Implementation for class mpjdev_natmpjdev_Intercomm */
+
+/*
+ * Class: mpjdev_natmpjdev_Intercomm
+ * Method: nativeMerge
+ * Signature: (JZ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Intercomm_nativeMerge(JNIEnv *env,
+ jobject thisObject, jlong intercomm, jboolean _high) {
+
+ MPI_Comm mpi_Intercomm = (MPI_Comm) (intptr_t) intercomm;
+ MPI_Comm newintracomm;
+ int errCode = -1;
+ errCode = MPI_Intercomm_merge(mpi_Intercomm, _high, &newintracomm);
+
+ if (errCode == MPI_SUCCESS) {
+ //printf("Nativ: Intercomm Merge MPI_SUCCESS \n");
+ } else {
+ printf("Nativ: Intercomm Merge returned is not MPI_SUCCESS\n");
+ }
+
+ if (newintracomm == MPI_COMM_NULL) {
+ printf("Nativ: Intercomm Merge- newintracomm returned is NULL\n");
+ return 0;
+ } else
+ return (jlong) newintracomm;
+
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.h
new file mode 100644
index 0000000..f448c36
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intercomm.h
@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_Intercomm */
+
+#ifndef _Included_mpjdev_natmpjdev_Intercomm
+#define _Included_mpjdev_natmpjdev_Intercomm
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: mpjdev_natmpjdev_Intercomm
+ * Method: nativeMerge
+ * Signature: (JZ)J
+ */
+JNIEXPORT jlong JNICALL Java_mpjdev_natmpjdev_Intercomm_nativeMerge
+ (JNIEnv *, jobject, jlong, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.c
new file mode 100644
index 0000000..47de417
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.c
@@ -0,0 +1,650 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ /*
+ * File : mpjdev_natmpjdev_Intracomm.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+#include "mpjdev_natmpjdev_Intracomm.h"
+#include <inttypes.h>
+#include "mpjdev_natmpjdev_shared.h"
+#include "mpi.h"
+#include <stdlib.h>
+#include <string.h>
+
+jfieldID FID_mpjbuf_Buffer_staticBuffer;
+jfieldID FID_mpjbuf_Buffer_dynamicBuffer;
+jfieldID FID_mpjbuf_NIOBuffer_buffer;
+
+jclass CL_mpjbuf_NIOBuffer;
+jclass CL_mpjbuf_Type;
+jclass CL_mpjbuf_Buffer;
+jfieldID FID_mpjbuf_Buffer_capacity;
+jfieldID FID_mpjbuf_Buffer_size;
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_init
+(JNIEnv * env, jclass thisClass)
+{
+//-----------------------
+
+ CL_mpjbuf_Buffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env,"mpjbuf/Buffer"));
+
+ CL_mpjbuf_NIOBuffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env,"mpjbuf/NIOBuffer"));
+ CL_mpjbuf_Type = (*env)->FindClass(env,"mpjbuf/Type");
+ FID_mpjbuf_Buffer_capacity =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"capacity","I");
+
+ FID_mpjbuf_Buffer_size =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"size","I");
+ FID_mpjbuf_Buffer_staticBuffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"staticBuffer","Lmpjbuf/RawBuffer;");
+//TODO: no need ! of dynamicBuffer
+ FID_mpjbuf_Buffer_dynamicBuffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"dynamicBuffer","[B");
+
+ FID_mpjbuf_NIOBuffer_buffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_NIOBuffer,"buffer","Ljava/nio/ByteBuffer;");
+
+//-----------------------
+
+}
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeCompare
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeCompare(
+ JNIEnv *env, jclass thisClass, jlong _comm1, jlong _comm2) {
+
+ int result;
+ int errCode;
+
+ MPI_Comm comm1 = (MPI_Comm) (intptr_t) _comm1;
+ MPI_Comm comm2 = (MPI_Comm) (intptr_t) _comm2;
+
+ errCode = MPI_Comm_compare(comm1, comm2, &result);
+ // here return the result as MPJ Express macros
+ // as per MPJ Express 0.38
+ // NO_RANK = -1, IDENT = 0, CONGRUENT = 3, SIMILAR = 1, UNEQUAL = 2;
+ // UNDEFINED = -1;
+
+ if (errCode == MPI_SUCCESS) {
+ // printf("nativeCompare result = %d \n",result);
+ if (result == MPI_IDENT) {
+ return IDENT;
+ } else if (result == MPI_CONGRUENT) {
+ return CONGRUENT;
+ } else if (result == MPI_SIMILAR) {
+ return SIMILAR;
+ } else if (result == MPI_UNEQUAL) {
+ return UNEQUAL;
+ }
+ } else if (errCode == MPI_ERR_GROUP || errCode == MPI_ERR_ARG) {
+ //error !
+ return -1; // UNDEFINED
+ }
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeBarrier
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeBarrier
+(JNIEnv *env, jobject thisClass, jlong comm) {
+
+ MPI_Barrier((MPI_Comm) (intptr_t) comm);
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeBcast
+ * Signature: (JLmpjbuf/Buffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeBcast
+(JNIEnv *env, jobject thisClass, jlong comm, jobject buf, jint count, jint root) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)buf);
+
+ MPI_Bcast(buffer_address,count,MPI_BYTE,root,mpi_comm);
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeGather
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;IIZ)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeGather
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jint send_counter, jobject recv_buf, jint recv_count, jint root, jboolean isRoot) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+
+ //- For SendBuffer -
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)send_buf);
+
+ // - For Recv Buffer -
+ /*Declarations for ByteBuffer */
+
+ char *r_buffer_address=NULL;
+
+ /* Get the ByteBuffer Related things.. */
+
+ if(isRoot) {
+ r_buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)recv_buf);
+
+ }
+
+ MPI_Gather(buffer_address,send_counter,MPI_BYTE,r_buffer_address,
+ recv_count,MPI_BYTE,root,mpi_comm);
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeGatherv
+ * Signature: (JLmpjbuf/Buffer;ILmpjbuf/Buffer;[I[II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeGatherv
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf, jint send_count,
+ jobject recv_buf, jintArray recv_counts, jintArray displs, jint root) {
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeScatter
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeScatter
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jint send_count, jobject recv_buf, jint recv_count, jint root) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+ int rank = -1;
+ MPI_Comm_rank(mpi_comm, &rank);
+ //- For SendBuffer -
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+ if(rank == root)
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)send_buf);
+
+ // - For Recv Buffer -
+ /*Declarations for ByteBuffer */
+
+ char *r_buffer_address=NULL;
+
+ /* Get the ByteBuffer Related things.. */
+
+ r_buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)recv_buf);
+
+ MPI_Scatter(buffer_address,send_count,MPI_BYTE,r_buffer_address,
+ recv_count,MPI_BYTE,root,mpi_comm);
+ /*
+ * MPI_Scatter(void* send_data, int send_count, MPI_Datatype send_datatype,
+ * void* recv_data, int recv_count, MPI_Datatype recv_datatype, int root,
+ * MPI_Comm communicator)
+ */
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeScatterv
+ * Signature: (JLmpjbuf/Buffer;[I[ILmpjbuf/Buffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeScatterv
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jintArray send_counts, jintArray displs, jobject recv_buf,
+ jint recv_count, jint root) {
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllgather
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllgather
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jint send_count, jobject recv_buf, jint recv_count) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+
+ //- For SendBuffer -
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+ //if(rank == root)
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)send_buf);
+
+ // - For Recv Buffer -
+ /*Declarations for ByteBuffer */
+
+ char *r_buffer_address=NULL;
+
+ /* Get the ByteBuffer Related things.. */
+
+ r_buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)recv_buf);
+
+ MPI_Allgather(buffer_address,send_count,MPI_BYTE,r_buffer_address,
+ recv_count,MPI_BYTE,mpi_comm);
+ /*
+ * MPI_Allgather(void* send_data, int send_count, MPI_Datatype send_datatype,
+ * void* recv_data, int recv_count, MPI_Datatype recv_datatype,
+ * MPI_Comm communicator)
+ */
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllgatherv
+ * Signature: (JLmpjbuf/Buffer;ILmpjbuf/Buffer;[I[I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllgatherv
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jint send_count, jobject recv_buf, jintArray recv_counts, jintArray displs) {
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: Alltoall
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAlltoall
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jint send_count, jobject recv_buf, jint recv_count) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+
+ //- For SendBuffer -
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)send_buf);
+
+ // - For Recv Buffer -
+ /*Declarations for ByteBuffer */
+
+ char *r_buffer_address=NULL;
+
+ /* Get the ByteBuffer Related things.. */
+
+ r_buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)recv_buf);
+
+ MPI_Alltoall(buffer_address,send_count,MPI_BYTE,r_buffer_address,
+ recv_count,MPI_BYTE,mpi_comm);
+ /*
+ * int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+ void *recvbuf, int recvcount, MPI_Datatype recvtype,
+ MPI_Comm comm)
+ */
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: Alltoallv
+ * Signature: (JLjava/nio/ByteBuffer;[I[ILjava/nio/ByteBuffer;[I[I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAlltoallv
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jintArray send_counts, jintArray send_displ, jobject recv_buf,
+ jintArray recv_counts, jintArray recv_displ) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+ jboolean isCopy = JNI_TRUE;
+
+ //- For SendBuffer -
+ /*Declarations for staticBuffer */
+
+ char * buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)send_buf);
+
+ // - For Recv Buffer -
+ /*Declarations for ByteBuffer */
+
+ char *r_buffer_address=NULL;
+
+ /* Get the ByteBuffer Related things.. */
+
+ r_buffer_address = (char *)(*env)->GetDirectBufferAddress(env,(jobject)recv_buf);
+
+ //get send count
+ jint *native_send_count = (*env)->GetIntArrayElements(env, send_counts, &isCopy);
+ //get send_displ
+ jint *native_send_displ = (*env)->GetIntArrayElements(env, send_displ, &isCopy);
+ //get recv_count
+ jint *native_recv_count = (*env)->GetIntArrayElements(env, recv_counts, &isCopy);
+ //get recv_displ
+ jint*native_recv_displ = (*env)->GetIntArrayElements(env, recv_displ, &isCopy);
+
+ MPI_Alltoallv(buffer_address,(int*)native_send_count, (int*)native_send_displ,
+ MPI_BYTE, r_buffer_address, (int*)native_recv_count,
+ (int*)native_recv_displ, MPI_BYTE, mpi_comm);
+
+ //release
+ (*env)->ReleaseIntArrayElements(env,send_counts,native_send_count,JNI_ABORT);
+ (*env)->ReleaseIntArrayElements(env,send_displ,native_send_displ,JNI_ABORT);
+ (*env)->ReleaseIntArrayElements(env,recv_counts,native_recv_count,JNI_ABORT);
+ (*env)->ReleaseIntArrayElements(env,recv_displ,native_recv_displ,JNI_ABORT);
+
+ /*
+ * int MPI_Alltoallv(const void *sendbuf, const int *sendcounts,
+ const int *sdispls, MPI_Datatype sendtype, void *recvbuf,
+ const int *recvcounts, const int *rdispls, MPI_Datatype recvtype,
+ MPI_Comm comm)
+ */
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeReduce
+ * Signature: (JLjava/lang/Object;Ljava/nio/ByteBuffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeReduce
+(JNIEnv *env, jobject thisObject, jlong comm, jobject send_buf,
+ jobject recv_buf, jint count, jint type_, jint op_, jint root) {
+
+ MPI_Comm mpi_comm = (MPI_Comm) (intptr_t) comm;
+ int rank;
+ int eerCode = MPI_Comm_rank(mpi_comm, &rank);
+
+ int n;
+
+ void *native_send_array = NULL;
+ void *native_result = NULL;
+ jboolean isCopy = JNI_TRUE;
+ MPI_Op op;
+ MPI_Datatype type;
+ int size_of_type = -1; //UNDEFINED
+
+ //set op -- TODO define a macro for this setting
+ if(op_ == MPJ_MAX_CODE) {
+ op = MPI_MAX;
+ } else if(op_ == MPJ_MIN_CODE) {
+ op = MPI_MIN;
+ } else if(op_ == MPJ_SUM_CODE) {
+ op = MPI_SUM;
+ } else if(op_ == MPJ_PROD_CODE) {
+ op = MPI_PROD;
+ } else if(op_ == MPJ_LAND_CODE) {
+ op = MPI_LAND;
+ } else if(op_ == MPJ_BAND_CODE) {
+ op = MPI_BAND;
+ } else if(op_ == MPJ_LOR_CODE) {
+ op = MPI_LOR;
+ } else if(op_ == MPJ_BOR_CODE) {
+ op = MPI_BOR;
+ } else if(op_ == MPJ_LXOR_CODE) {
+ op = MPI_LXOR;
+ } else if(op_ == MPJ_BXOR_CODE) {
+ op = MPI_BXOR;
+ } else if(op_ == MPJ_MAXLOC_CODE) {
+ op = MPI_MAXLOC;
+ } else if(op_ == MPJ_MINLOC_CODE) {
+ op = MPI_MINLOC;
+ }
+
+ //define a macro for this #TODO
+ if(type_ == MPJ_INT) {
+ type = MPI_INT;
+ jintArray send_array = (jintArray) send_buf;
+
+ native_send_array = (*env)->GetIntArrayElements(env, send_array,
+ &isCopy);
+
+ if(rank == root) //only for root
+ //TODO naive case may be its 2 not 1 for MAXLOC ?
+ native_result = malloc(sizeof(int) * count);
+ } else if(type_ == MPJ_FLOAT) {
+
+ type = MPI_FLOAT;
+ jfloatArray send_array = (jfloatArray) send_buf;
+
+ native_send_array = (*env)->GetFloatArrayElements(env, send_array,
+ &isCopy);
+
+ if(rank == root) //only for root
+ //TODO naive case may be its 2 not 1 for MAXLOC ?
+ native_result = malloc(sizeof(float) * count);
+
+ } else if(type_ == MPJ_DOUBLE) {
+
+ type = MPI_DOUBLE;
+ jdoubleArray send_array = (jdoubleArray) send_buf;
+
+ native_send_array = (*env)->GetDoubleArrayElements(env, send_array,
+ &isCopy);
+
+ if(rank == root) //only for root
+ //TODO naive case may be its 2 not 1 for MAXLOC ?
+ native_result = malloc(sizeof(double) * count);
+
+ } else if(type_ == MPJ_SHORT) {
+
+ type = MPI_SHORT;
+ jshortArray send_array = (jshortArray) send_buf;
+
+ native_send_array = (*env)->GetShortArrayElements(env, send_array,
+ &isCopy);
+
+ if(rank == root) //only for root
+ //TODO naive case may be its 2 not 1 for MAXLOC ?
+ native_result = malloc(sizeof(short) * count);
+
+ } else if(type_ == MPJ_LONG) {
+
+ type = MPI_LONG;
+ jlongArray send_array = (jlongArray) send_buf;
+
+ native_send_array = (*env)->GetLongArrayElements(env, send_array,
+ &isCopy);
+
+ if(rank == root) //only for root
+ //TODO naive case may be its 2 not 1 for MAXLOC ?
+ native_result = malloc(sizeof(long) * count);
+
+ }
+
+ // call native MPI_Reduce (.. );
+ MPI_Reduce(native_send_array, native_result, count, type, op,root,
+ mpi_comm);
+
+ //define a macro for this #TODO
+ if(type_ == MPJ_INT) {
+ jintArray send_array = (jintArray) send_buf;
+ (*env)->ReleaseIntArrayElements(env,send_array,native_send_array,0);
+
+ if(rank == root) {
+
+ jclass bbclass = (*env)->FindClass(env, "java/nio/ByteBuffer" );
+ jmethodID putMethod = (*env)->GetMethodID(env, bbclass, "putInt", "(II)Ljava/nio/ByteBuffer;");
+ int i = 0;
+ int val, index;
+ size_of_type = 4; //because int is 32-bit
+ for(i=0; i<count; i++) {
+ val = ((int*)native_result)[i];
+ //index = i*size_of_type;
+ index = i*4;//hard coding this
+
+ (*env)->CallObjectMethod(env, recv_buf, putMethod, index, val );
+
+ }
+ }
+ }if(type_ == MPJ_FLOAT) {
+ jfloatArray send_array = (jfloatArray) send_buf;
+ (*env)->ReleaseFloatArrayElements(env,send_array,native_send_array,0);
+
+ if(rank == root) {
+
+ jclass bbclass = (*env)->FindClass(env, "java/nio/ByteBuffer" );
+ jmethodID putMethod = (*env)->GetMethodID(env, bbclass, "putFloat", "(IF)Ljava/nio/ByteBuffer;");
+ int i = 0;
+ float val;
+ int index;
+ size_of_type = 4; //because float is 32-bit
+ for(i=0; i<count; i++) {
+ val = ((float*)native_result)[i];
+ //index = i*size_of_type;
+ index = i*4;//hard coding this
+
+ (*env)->CallObjectMethod(env, recv_buf, putMethod, index, val );
+
+ }
+ }
+ }if(type_ == MPJ_DOUBLE) {
+ jdoubleArray send_array = (jdoubleArray) send_buf;
+ (*env)->ReleaseDoubleArrayElements(env,send_array,native_send_array,0);
+
+ if(rank == root) {
+
+ jclass bbclass = (*env)->FindClass(env, "java/nio/ByteBuffer" );
+ jmethodID putMethod = (*env)->GetMethodID(env, bbclass, "putDouble", "(ID)Ljava/nio/ByteBuffer;");
+ int i = 0;
+ double val;
+ int index;
+ size_of_type = 8; //because float is 64-bit
+ for(i=0; i<count; i++) {
+ val = ((double*)native_result)[i];
+ //index = i*size_of_type;
+ index = i*8;//hard coding this
+
+ (*env)->CallObjectMethod(env, recv_buf, putMethod, index, val );
+
+ }
+ }
+ }if(type_ == MPJ_SHORT) {
+ jshortArray send_array = (jshortArray) send_buf;
+ (*env)->ReleaseShortArrayElements(env,send_array,native_send_array,0);
+
+ if(rank == root) {
+
+ jclass bbclass = (*env)->FindClass(env, "java/nio/ByteBuffer" );
+ jmethodID putMethod = (*env)->GetMethodID(env, bbclass, "putShort", "(IS)Ljava/nio/ByteBuffer;");
+ int i = 0;
+ short val;
+ int index;
+ size_of_type = 2; //because short is 16-bit
+ for(i=0; i<count; i++) {
+ val = ((short*)native_result)[i];
+ //index = i*size_of_type;
+ index = i*2;//hard coding this
+
+ (*env)->CallObjectMethod(env, recv_buf, putMethod, index, val );
+
+ }
+ }
+ }if(type_ == MPJ_LONG) {
+ jlongArray send_array = (jlongArray) send_buf;
+ (*env)->ReleaseLongArrayElements(env,send_array,native_send_array,0);
+
+ if(rank == root) {
+
+ jclass bbclass = (*env)->FindClass(env, "java/nio/ByteBuffer" );
+ jmethodID putMethod = (*env)->GetMethodID(env, bbclass, "putLong", "(IJ)Ljava/nio/ByteBuffer;");
+ int i = 0;
+ long val;
+ int index;
+ size_of_type = 8; //because long is 64-bit
+ for(i=0; i<count; i++) {
+ val = ((long*)native_result)[i];
+ //index = i*size_of_type;
+ index = i*8;//hard coding this
+
+ (*env)->CallObjectMethod(env, recv_buf, putMethod, index, val );
+
+ }
+ }
+ }
+
+ free(native_result);
+}
+//TODO: use thisObject instead of thisClass be consistent
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllreduce
+ * Signature: (JLmpjbuf/Buffer;Lmpjbuf/Buffer;ILmpi/Op;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllreduce
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jobject recv_buf, jint count, jobject op) {
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeReduce_scatter
+ * Signature: (JLmpjbuf/Buffer;Lmpjbuf/Buffer;[ILmpi/Op;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeReduce_1scatter
+(JNIEnv *env, jobject thisClass, jlong comm, jobject send_buf,
+ jobject recv_buf, jintArray recv_counts, jobject op) {
+
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.h
new file mode 100644
index 0000000..f0f8a28
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_Intracomm.h
@@ -0,0 +1,134 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_Intracomm */
+
+#ifndef _Included_mpjdev_natmpjdev_Intracomm
+#define _Included_mpjdev_natmpjdev_Intracomm
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_init
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeCompare
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeCompare
+ (JNIEnv *, jclass, jlong, jlong);
+
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeBarrier
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeBarrier
+ (JNIEnv *, jobject, jlong);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeBcast
+ * Signature: (JLjava/nio/ByteBuffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeBcast
+ (JNIEnv *, jobject, jlong, jobject, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeGather
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;IIZ)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeGather
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jint, jint, jboolean);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeGatherv
+ * Signature: (JLmpjbuf/Buffer;ILmpjbuf/Buffer;[I[II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeGatherv
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jintArray, jintArray, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeScatter
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeScatter
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeScatterv
+ * Signature: (JLjava/nio/ByteBuffer;[I[ILjava/nio/ByteBuffer;II)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeScatterv
+ (JNIEnv *, jobject, jlong, jobject, jintArray, jintArray, jobject, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllgather
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllgather
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllgatherv
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;[I[I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllgatherv
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jintArray, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAlltoall
+ * Signature: (JLjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAlltoall
+ (JNIEnv *, jobject, jlong, jobject, jint, jobject, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAlltoallv
+ * Signature: (JLjava/nio/ByteBuffer;[I[ILjava/nio/ByteBuffer;[I[I)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAlltoallv
+ (JNIEnv *, jobject, jlong, jobject, jintArray, jintArray, jobject, jintArray, jintArray);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeReduce
+ * Signature: (JLjava/lang/Object;Ljava/nio/ByteBuffer;IIII)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeReduce
+ (JNIEnv *, jobject, jlong, jobject, jobject, jint, jint, jint, jint);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeAllreduce
+ * Signature: (JLjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;ILmpi/Op;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeAllreduce
+ (JNIEnv *, jobject, jlong, jobject, jobject, jint, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_Intracomm
+ * Method: nativeReduce_scatter
+ * Signature: (JLjava/nio/ByteBuffer;Ljava/nio/ByteBuffer;[ILmpi/Op;)V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_Intracomm_nativeReduce_1scatter
+ (JNIEnv *, jobject, jlong, jobject, jobject, jintArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.c
new file mode 100644
index 0000000..4ca6960
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.c
@@ -0,0 +1,283 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+/*
+ * File : mpjdev_natmpjdev_NativeRecvRequest.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+/* class mpjdev_natmpjdev_NativeRecvRequest */
+#include "mpi.h"
+#include "mpjdev_natmpjdev_NativeRecvRequest.h"
+#include "mpjdev_natmpjdev_shared.h"
+
+//jfieldID mpjdev_natmpjdev_NativeRequest_reqhandleID;
+
+jfieldID mpjdev_natmpjdev_NativeRequest_comHandle;
+jfieldID mpjdev_natmpjdev_NativeRequest_mpjbuf;
+jfieldID reqhandleID;
+
+jclass CL_mpjdev_natmpjdev_NativeRequest;
+
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: initNativeRecvRequest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_initNativeRecvRequest
+(JNIEnv *env, jclass thisClass) {
+
+ //mpjdev_natmpjdev_NativeRequest_reqhandleID = (*env)->GetFieldID(env,
+ // thisClass, "handle", "J");
+
+ mpjdev_natmpjdev_NativeRequest_comHandle = (*env)->GetFieldID(env,
+ thisClass, "commHandle", "J");
+
+ mpjdev_natmpjdev_NativeRequest_mpjbuf = (*env)->GetFieldID(env, thisClass,
+ "bufferHandle", "Lmpjbuf/Buffer;");
+
+ CL_mpjdev_natmpjdev_NativeRequest = (*env)->FindClass(env, "mpjdev/natmpjdev/NativeRequest");
+
+ reqhandleID = (*env)->GetFieldID(env, CL_mpjdev_natmpjdev_NativeRequest, "handle",
+ "J");
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: Wait
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_Wait(
+ JNIEnv *env, jobject thisObject, jobject stat) {
+ // printf("native recv iwait: called\n");
+ int elements;
+
+ MPI_Request request = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, reqhandleID));
+
+ MPI_Status mpi_status;
+
+ MPI_Wait(&request, &mpi_status);
+
+ MPI_Get_count(&mpi_status, MPI_BYTE, &elements);
+
+ (*env)->SetIntField(env, stat, mpjdev_Status_sourceID, mpi_status.MPI_SOURCE);
+ (*env)->SetIntField(env, stat, mpjdev_Status_tagID, mpi_status.MPI_TAG);
+
+ //seting the number of elements as size of the buffer and in the iwait() method
+ // we pass it to setSize() method of buffer
+ // bufferHandle.setSize(status.numEls);
+ // later numEls is again initialized with getSectionSize() of the buffer
+ (*env)->SetIntField(env, stat, mpjdev_Status_numEls, elements);
+
+ // I am also setting this because we need it in mpi/Status Get_count
+ // method : TODO remove magic numbers
+ (*env)->SetIntField(env, stat, mpjdev_Status_countInBytes,
+ (jint)(elements - 8 - 8)); // 8 is the size of section header
+ // and 8 recv overhead
+
+ //check if dynamic buffer?
+ jobject mpjbuf;
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char *buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+ mpjbuf = (*env)->GetObjectField(env, thisObject,
+ mpjdev_natmpjdev_NativeRequest_mpjbuf);
+ staticBuffer = (*env)->GetObjectField(env, mpjbuf,
+ FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env, staticBuffer,
+ FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *) (*env)->GetDirectBufferAddress(env,
+ (jobject) directBuffer);
+
+ char encoding = 0;
+ int dbuf_len = -1;
+
+ encoding = buffer_address[0];
+ if (encoding == 1) {
+
+ dbuf_len = (((int) (unsigned char) buffer_address[4]) << 24)
+ | (((int) (unsigned char) buffer_address[5]) << 16)
+ | (((int) (unsigned char) buffer_address[6]) << 8)
+ | (((int) (unsigned char) buffer_address[7]));
+
+ /* Declarations of Dynamic Buffer */
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray darr;
+ jbyte * dBuffer;
+
+ MPI_Status mpi_status_dyn;
+
+ MPI_Comm mpi_comm = (MPI_Comm)(*env)->GetLongField(env, thisObject,
+ mpjdev_natmpjdev_NativeRequest_comHandle);
+
+ darr = (*env)->NewByteArray(env, dbuf_len);
+ // perhaps no need for this - use malloc instead
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+ // magic number ??
+ MPI_Recv(dBuffer, dbuf_len, MPI_BYTE, mpi_status.MPI_SOURCE,
+ mpi_status.MPI_TAG + 10001, mpi_comm, &mpi_status_dyn);
+
+ (*env)->SetByteArrayRegion(env, darr, 0, dbuf_len, dBuffer);
+
+ jmethodID setdbuf = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, mpjbuf, setdbuf, darr);
+
+ }
+
+ return stat;
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: Test
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_Test(
+ JNIEnv *env, jobject thisObject, jobject stat) {
+
+ /*
+ * Conventionaly our itest()
+ * provide iprobe like functionality.
+ *
+ * So we have 3 options:
+ * 1: change our mpi.Request Test() and don't call Wait() then
+ * we have to change implementations of itest() in all the devices
+ *
+ * 2: Put if-else in mpi.Request Test() to distinguish between native
+ * and pure. This is messy. And provide the real MPI_Test() functionality
+ * here.
+ *
+ * 3: Provide iprobe functionality here and don't change anything in
+ * the upper layers. This requires introducing source and tag in
+ * NativeRecvRequest
+ *
+ * We are opting for option 2 right now.
+ *
+ */
+
+ int flag;
+
+ MPI_Request request = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, reqhandleID));
+
+ MPI_Status mpi_status;
+
+ MPI_Test(&request, &flag, &mpi_status);
+
+ if (flag) {
+
+ int elements;
+
+ MPI_Get_count(&mpi_status, MPI_BYTE, &elements);
+
+ (*env)->SetIntField(env, stat, mpjdev_Status_sourceID,
+ mpi_status.MPI_SOURCE);
+ (*env)->SetIntField(env, stat, mpjdev_Status_tagID, mpi_status.MPI_TAG);
+
+ //seting the number of elements as size of the buffer and in the iwait() method
+ // we pass it to setSize() method of buffer
+ // bufferHandle.setSize(status.numEls);
+ // later numEls is again initialized with getSectionSize() of the buffer
+ (*env)->SetIntField(env, stat, mpjdev_Status_numEls, elements);
+
+ // I am also setting this because we need it in mpi/Status Get_count
+ // method : TODO remove magic numbers
+ (*env)->SetIntField(env, stat, mpjdev_Status_countInBytes,
+ (jint)(elements - 8 - 8)); // 8 is the size of section header
+ // and 8 recv overhead
+
+ //check if dynamic buffer?
+ jobject mpjbuf;
+ jobject staticBuffer;
+ jbyteArray directBuffer;
+ char *buffer_address = NULL;
+
+ /* Get the static Buffer Related things.. */
+ mpjbuf = (*env)->GetObjectField(env, thisObject,
+ mpjdev_natmpjdev_NativeRequest_mpjbuf);
+ staticBuffer = (*env)->GetObjectField(env, mpjbuf,
+ FID_mpjbuf_Buffer_staticBuffer);
+ directBuffer = (*env)->GetObjectField(env, staticBuffer,
+ FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *) (*env)->GetDirectBufferAddress(env,
+ (jobject) directBuffer);
+
+ char encoding = 0;
+ int dbuf_len = -1;
+
+ encoding = buffer_address[0];
+ if (encoding == 1) {
+
+ dbuf_len = (((int) (unsigned char) buffer_address[4]) << 24)
+ | (((int) (unsigned char) buffer_address[5]) << 16)
+ | (((int) (unsigned char) buffer_address[6]) << 8)
+ | (((int) (unsigned char) buffer_address[7]));
+
+ /* Declarations of Dynamic Buffer */
+ jboolean isCopy = JNI_TRUE;
+ jbyteArray darr;
+ jbyte * dBuffer;
+
+ MPI_Status mpi_status_dyn;
+
+ MPI_Comm mpi_comm = (MPI_Comm)(*env)->GetLongField(env, thisObject,
+ mpjdev_natmpjdev_NativeRequest_comHandle);
+
+ darr = (*env)->NewByteArray(env, dbuf_len);
+ // perhaps no need for this - use malloc instead
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+
+ // This is wrong here Why blocking? we need to set the NativeSendRequest
+ // wait to not call wait on dynamic buffer, else deadlock arises
+ MPI_Recv(dBuffer, dbuf_len, MPI_BYTE, mpi_status.MPI_SOURCE,
+ mpi_status.MPI_TAG + 10001, mpi_comm, &mpi_status_dyn);
+
+ (*env)->SetByteArrayRegion(env, darr, 0, dbuf_len, dBuffer);
+
+ jmethodID setdbuf = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, mpjbuf, setdbuf, darr);
+
+ }
+
+ return stat;
+
+ } else
+ return NULL;
+
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.h
new file mode 100644
index 0000000..2b2aee6
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeRecvRequest.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_NativeRecvRequest */
+
+#ifndef _Included_mpjdev_natmpjdev_NativeRecvRequest
+#define _Included_mpjdev_natmpjdev_NativeRecvRequest
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: initNativeRecvRequest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_initNativeRecvRequest
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: Wait
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_Wait
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_NativeRecvRequest
+ * Method: Test
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeRecvRequest_Test
+ (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.c b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.c
new file mode 100644
index 0000000..db7de3a
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.c
@@ -0,0 +1,153 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : mpjdev_natmpjdev_NativeSendRequest.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+/* mpjdev_natmpjdev_NativeSendRequest */
+
+#include "mpi.h"
+#include "mpjdev_natmpjdev_NativeSendRequest.h"
+#include "mpjdev_natmpjdev_shared.h"
+
+//jfieldID mpjdev_natmpjdev_NativeRequest_reqhandleID;
+jfieldID reqhandleID;
+
+jfieldID dbufreqhandleID;
+jfieldID dbuflenID;
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: initNativeSendRequest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_initNativeSendRequest
+(JNIEnv *env, jclass thisClass) {
+
+ // mpjdev_natmpjdev_NativeRequest_reqhandleID = (*env)->GetFieldID(env, thisClass,
+ // "handle", "J");
+
+ dbufreqhandleID = (*env)->GetFieldID(env, thisClass, "dbufHandle", "J");
+
+ dbuflenID = (*env)->GetFieldID(env, thisClass, "dbuflen", "I");
+
+ //this can go in JNI_onLOAD
+ jclass CL_mpjdev_natmpjdev_NativeRequest = (*env)->FindClass(env,
+ "mpjdev/natmpjdev/NativeRequest");
+
+ reqhandleID = (*env)->GetFieldID(env, CL_mpjdev_natmpjdev_NativeRequest, "handle",
+ "J");
+
+}
+
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: Wait
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_Wait(
+ JNIEnv *env, jobject thisObject, jobject stat) {
+ int elements;
+
+ MPI_Request request = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, reqhandleID));
+
+ MPI_Status mpi_status;
+
+ MPI_Wait(&request, &mpi_status);
+
+ (*env)->SetIntField(env, stat, mpjdev_Status_sourceID, mpi_status.MPI_SOURCE);
+ (*env)->SetIntField(env, stat, mpjdev_Status_tagID, mpi_status.MPI_TAG);
+
+ int dbuf_len = -1;
+
+ dbuf_len = ((*env)->GetIntField(env, thisObject, dbuflenID));
+ if (dbuf_len > 0) {
+
+ MPI_Request request_dyn = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, dbufreqhandleID));
+ MPI_Status mpi_status_dyn;
+
+ MPI_Wait(&request_dyn, &mpi_status_dyn);
+
+ }
+
+ return stat;
+}
+
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: Test
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_Test(
+ JNIEnv *env, jobject thisObject, jobject stat) {
+
+ int flag;
+
+ MPI_Request request = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, reqhandleID));
+
+ MPI_Status mpi_status;
+
+ MPI_Test(&request, &flag, &mpi_status);
+
+ if (flag) {
+ int elements;
+ //TODO get count or what?
+ (*env)->SetIntField(env, stat, mpjdev_Status_sourceID,
+ mpi_status.MPI_SOURCE);
+ (*env)->SetIntField(env, stat, mpjdev_Status_tagID, mpi_status.MPI_TAG);
+
+ //? MPI_Get_count(&mpi_status, MPI_BYTE, &elements);
+ // (*env)->SetIntField(env, stat, mpjdev_Status_numEls, elements);
+
+ // for dynamic buffer
+ int dbuf_len = -1;
+
+ dbuf_len = ((*env)->GetIntField(env, thisObject, dbuflenID));
+ if (dbuf_len > 0) {
+
+ MPI_Request request_dyn = (MPI_Request)(
+ (*env)->GetLongField(env, thisObject, dbufreqhandleID));
+ MPI_Status mpi_status_dyn;
+
+ //doing wait -- not ideal ???
+ MPI_Wait(&request_dyn, &mpi_status_dyn);
+ }
+
+ return stat;
+
+ } else
+ return NULL;
+}
+
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.h
new file mode 100644
index 0000000..630e016
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_NativeSendRequest.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class mpjdev_natmpjdev_NativeSendRequest */
+
+#ifndef _Included_mpjdev_natmpjdev_NativeSendRequest
+#define _Included_mpjdev_natmpjdev_NativeSendRequest
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: initNativeSendRequest
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_initNativeSendRequest
+ (JNIEnv *, jclass);
+
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: Wait
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_Wait
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: mpjdev_natmpjdev_NativeSendRequest
+ * Method: Test
+ * Signature: (Lmpjdev/Status;)Lmpjdev/Status;
+ */
+JNIEXPORT jobject JNICALL Java_mpjdev_natmpjdev_NativeSendRequest_Test
+ (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_shared.h b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_shared.h
new file mode 100644
index 0000000..ecb90ee
--- /dev/null
+++ b/src/mpjdev/natmpjdev/lib/mpjdev_natmpjdev_shared.h
@@ -0,0 +1,113 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2014
+ 1. SEECS, National University of Sciences and Technology, Pakistan (2013 - 2014)
+ 2. Bibrak Qamar (2013 - 2014)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : mpjdev_natmpjdev_shared.c
+ * Author : Bibrak Qamar
+ * Created : Tue Sept 17 11:15:11 PKT 2013
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2014/03/11 11:30:00 $
+ *
+ */
+
+/* mpjdev_natmpjdev_shared */
+
+#ifndef _Included_mpjdev_natmpjdev_shared
+#define _Included_mpjdev_natmpjdev_shared
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern jfieldID mpjdev_Status_sourceID;
+extern jfieldID mpjdev_Status_tagID;
+// extern jfieldID mpjdev_Status_stathandleID;
+extern jfieldID mpjdev_Status_indexID;
+extern jfieldID mpjdev_Status_numEls;
+extern jfieldID mpjdev_Status_countInBytes;
+extern jfieldID mpjdev_natmpjdev_Comm_CommhandleID;
+
+extern jfieldID FID_mpjbuf_Buffer_staticBuffer;
+extern jfieldID FID_mpjbuf_Buffer_dynamicBuffer;
+extern jfieldID FID_mpjbuf_NIOBuffer_buffer;
+
+extern jclass CL_mpjbuf_Buffer;
+
+//for Request
+//extern jfieldID mpjdev_natmpjdev_NativeRequest_reqhandleID;
+
+// As per MPJ Express 0.38 the values of these macros
+#define IDENT 0
+#define SIMILAR 1
+#define UNEQUAL 2
+#define CONGRUENT 3
+
+// As per MPJ Express 0.38 mpi.Datatype -- the values of these macros
+#define MPJ_UNDEFINED -1
+#define MPJ_NULL 0
+#define MPJ_BYTE 1
+#define MPJ_CHAR 2
+#define MPJ_SHORT 3
+#define MPJ_BOOLEAN 4
+#define MPJ_INT 5
+#define MPJ_LONG 6
+#define MPJ_FLOAT 7
+#define MPJ_DOUBLE 8
+#define MPJ_PACKED 9
+
+// after this non-primitive types begin
+#define MPJ_PRIMITIVE_TYPE_RANGE_UB 9
+
+#define MPJ_LB 10
+#define MPJ_UB 11
+#define MPJ_OBJECT 12
+
+#define MPJ_SHORT2 3
+#define MPJ_INT2 5
+#define MPJ_LONG2 6
+#define MPJ_FLOAT2 7
+#define MPJ_DOUBLE2 8
+
+// As per MPJ Express 0.38 Operator -- the values of these macros
+// these are needed in Reduce ...
+#define MPJ_MAX_CODE 1
+#define MPJ_MIN_CODE 2
+#define MPJ_SUM_CODE 3
+#define MPJ_PROD_CODE 4
+#define MPJ_LAND_CODE 5
+#define MPJ_BAND_CODE 6
+#define MPJ_LOR_CODE 7
+#define MPJ_BOR_CODE 8
+#define MPJ_LXOR_CODE 9
+#define MPJ_BXOR_CODE 10
+#define MPJ_MAXLOC_CODE 11
+#define MPJ_MINLOC_CODE 12
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/runtime/common/IOHelper.java b/src/runtime/common/IOHelper.java
new file mode 100644
index 0000000..560dcf5
--- /dev/null
+++ b/src/runtime/common/IOHelper.java
@@ -0,0 +1,430 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : IOHelper.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 28, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ *
+ *
+ * Zipping and Unzipping methods are taken from this link: http://pastebin.com/ZS1p4N5P
+ */
+
+package runtime.common;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public final class IOHelper {
+
+ public static String getUniqueID() {
+
+ return UUID.randomUUID().toString();
+ }
+
+ public static boolean isNullOrEmpty(String s) {
+
+ if (s == null || s.trim().equals(""))
+ return true;
+
+ return false;
+ }
+
+ public static void CreateDirectory(String folderPath) {
+ File folder = new File(folderPath);
+ if (!folder.isDirectory() && !folder.exists()) {
+ folder.mkdir();
+ }
+ }
+
+ public static String[] getFileList(String directoryPath) {
+
+ File directory = new File(directoryPath);
+
+ if (directory.exists()) {
+ return directory.list();
+ }
+
+ return new String[] {};
+ }
+
+ public static String getFileName(String filePath) {
+ return filePath.substring(filePath.lastIndexOf("/") + 1);
+ }
+
+ public static String readCharacterFile(String path) {
+
+ FileInputStream stream = null;
+ InputStreamReader streamReader = null;
+ BufferedReader bufferedReader = null;
+ StringBuilder buffer = new StringBuilder();
+
+ try {
+
+ stream = new FileInputStream(path);
+ streamReader = new InputStreamReader(stream, "UTF-8");
+ bufferedReader = new BufferedReader(streamReader);
+
+ String line = null;
+
+ while ((line = bufferedReader.readLine()) != null) {
+
+ buffer.append(line);
+ }
+
+ }
+ catch (Exception exp) {
+
+ exp.printStackTrace();
+ return null;
+
+ }
+ finally {
+
+ try {
+
+ bufferedReader.close();
+ stream.close();
+
+ }
+ catch (Exception e) {
+
+ e.printStackTrace();
+ }
+ }
+
+ return buffer.toString();
+ }
+
+ public static boolean deleteFile(String path) {
+
+ try {
+ File f = new File(path);
+ if (f.exists()) {
+ return f.delete();
+
+ } else {
+ System.out.println("File cannot be deleted");
+ }
+
+ }
+ catch (Exception exp) {
+
+ exp.printStackTrace();
+ }
+
+ return false;
+ }
+
+ public static String getUniqueName() {
+ return UUID.randomUUID().toString();
+
+ }
+
+ public static String getFileNameFromFilePath(String path) {
+ String fileName = "";
+ File f = new File(path);
+ fileName = f.getName();
+ return fileName;
+ }
+
+ public static String getFilePath(String path) {
+ String fileName = "";
+ File f = new File(path);
+ fileName = f.getName();
+ if (!(fileName.equals(""))) {
+ path = path.substring(0, path.indexOf(fileName));
+ }
+ path = removeTag(path);
+ return path;
+ }
+
+ public static String removeTag(String str) {
+ if (str.startsWith("/")) {
+ str = str.substring(str.indexOf("/") + 1);
+ }
+ if (str.endsWith("/")) {
+ str = str.substring(0, str.lastIndexOf("/"));
+ }
+ return str;
+ }
+
+ public static String getCharacterDataFromElement(Element e) {
+ if (e != null) {
+ Node child = e.getFirstChild();
+
+ if (child instanceof CharacterData) {
+ CharacterData cd = (CharacterData) child;
+ return cd.getData();
+ }
+ }
+ return "?";
+ }
+
+ public static byte[] ReadBinaryFile(String filename) {
+ byte[] buffer = null;
+ File a_file = new File(filename);
+ try {
+ FileInputStream fis = new FileInputStream(filename);
+ int length = (int) a_file.length();
+ buffer = new byte[length];
+ fis.read(buffer);
+ fis.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ return buffer;
+ }
+
+ public static Boolean writeFile(String path, byte[] contents) {
+ Boolean success = false;
+ try {
+ File outputfile = new File(path);
+ FileOutputStream fos = new FileOutputStream(outputfile);
+ fos.write(contents);
+ fos.flush();
+ fos.close();
+
+ success = true;
+ }
+ catch (Exception ex) {
+ }
+ return success;
+ }
+
+ public static boolean writeCharacterFile(String path, String contents) {
+
+ Writer writer = null;
+ FileOutputStream fileOutputStream = null;
+ boolean bRet = false;
+ try {
+ // if(!f.exists())
+ File f = new File(path);
+ if (!f.exists()) {
+ f.createNewFile();
+ }
+ fileOutputStream = new FileOutputStream(path);
+ writer = new OutputStreamWriter(fileOutputStream, "UTF-8");
+ writer.write(contents);
+ bRet = true;
+
+ }
+ catch (Exception exp) {
+
+ exp.printStackTrace();
+
+ }
+ finally {
+
+ try {
+
+ writer.close();
+
+ }
+ catch (Exception e) {
+
+ e.printStackTrace();
+ }
+ }
+ return bRet;
+
+ }
+
+ public static void zipFolder(String srcDir, String zipFile) {
+
+ try {
+ zipDirectory(srcDir, zipFile);
+ }
+ catch (Exception e) {
+ }
+ }
+
+ private static void zipDirectory(String srcFolder, String destZipFile)
+ throws Exception {
+ ZipOutputStream zip = null;
+ FileOutputStream fileWriter = null;
+ /*
+ * create the output stream to zip file result
+ */
+ fileWriter = new FileOutputStream(destZipFile);
+ zip = new ZipOutputStream(fileWriter);
+ /*
+ * add the folder to the zip
+ */
+ addFolderToZip("", srcFolder, zip);
+ /*
+ * close the zip objects
+ */
+ zip.flush();
+ zip.close();
+ }
+
+ /*
+ * recursively add files to the zip files
+ */
+ private static void addFileToZip(String path, String srcFile,
+ ZipOutputStream zip, boolean flag) throws Exception {
+ /*
+ * create the file object for inputs
+ */
+ File folder = new File(srcFile);
+
+ /*
+ * if the folder is empty add empty folder to the Zip file
+ */
+ if (flag == true) {
+ zip.putNextEntry(new ZipEntry(path + "/" + folder.getName() + "/"));
+ } else { /*
+ * if the current name is directory, recursively traverse it to get
+ * the files
+ */
+ if (folder.isDirectory()) {
+ /*
+ * if folder is not empty
+ */
+ addFolderToZip(path, srcFile, zip);
+ } else {
+ /*
+ * write the file to the output
+ */
+ byte[] buf = new byte[1024];
+ int len;
+ FileInputStream in = new FileInputStream(srcFile);
+ zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
+ while ((len = in.read(buf)) > 0) {
+ /*
+ * Write the Result
+ */
+ zip.write(buf, 0, len);
+ }
+ }
+ }
+ }
+
+ /*
+ * add folder to the zip file
+ */
+ private static void addFolderToZip(String path, String srcFolder,
+ ZipOutputStream zip) throws Exception {
+ File folder = new File(srcFolder);
+
+ /*
+ * check the empty folder
+ */
+ if (folder.list().length == 0) {
+ System.out.println(folder.getName());
+ addFileToZip(path, srcFolder, zip, true);
+ } else {
+ /*
+ * list the files in the folder
+ */
+ for (String fileName : folder.list()) {
+ if (path.equals("")) {
+ addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false);
+ } else {
+ addFileToZip(path + "/" + folder.getName(), srcFolder + "/"
+ + fileName, zip, false);
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) {
+ IOHelper.zipFolder("/home/aleem/code/test", "/home/aleem/code/test.zip");
+ IOHelper.ExtractZip("/home/aleem/code/test.zip", "/home/aleem/code/test2");
+ }
+
+ public static void ExtractZip(String srcFileName, String targetFolder) {
+ ZipInputStream zis = null;
+ try {
+
+ zis = new ZipInputStream(new FileInputStream(srcFileName));
+ ZipEntry entry;
+
+ while ((entry = zis.getNextEntry()) != null) {
+
+ // Create a file on HDD in the destinationPath directory
+ // destinationPath is a "root" folder, where you want to extract your
+ // ZIP file
+ File entryFile = new File(targetFolder, entry.getName());
+ if (entry.isDirectory()) {
+
+ if (entryFile.exists()) {
+ } else {
+ entryFile.mkdirs();
+ }
+
+ } else {
+
+ // Make sure all folders exists (they should, but the safer, the
+ // better ;-))
+ if (entryFile.getParentFile() != null
+ && !entryFile.getParentFile().exists()) {
+ entryFile.getParentFile().mkdirs();
+ }
+
+ // Create file on disk...
+ if (!entryFile.exists()) {
+ entryFile.createNewFile();
+ }
+
+ FileOutputStream fileoutputstream = new FileOutputStream(entryFile);
+ byte[] buf = new byte[1024];
+ int n;
+ while ((n = zis.read(buf, 0, 1024)) > -1) {
+ fileoutputstream.write(buf, 0, n);
+ }
+
+ }
+ }
+ }
+ catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/runtime/common/MPJProcessTicket.java b/src/runtime/common/MPJProcessTicket.java
new file mode 100644
index 0000000..7f27e2a
--- /dev/null
+++ b/src/runtime/common/MPJProcessTicket.java
@@ -0,0 +1,480 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJProcessTicket.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 10, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.common;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.UUID;
+
+public class MPJProcessTicket {
+
+ private UUID ticketID;
+ private String classPath;
+ private int processCount;
+ private int startingRank;
+ private ArrayList<String> jvmArgs;
+ private String workingDirectory;
+ private String mainClass;
+ private boolean zippedSource;
+ private String sourceCode;
+ private String deviceName;
+ private String confFileContents;
+ private ArrayList<String> appArgs;
+ private String userID;
+ /* Hybrid Device */
+ private int networkProcessCount;
+ private int totalProcessCount;
+ private String networkDevice;
+ /* Debugger & Profiler */
+ private boolean isDebug;
+ private boolean isProfiler;
+ private int debugPort;
+
+ public String getClassPath() {
+ return classPath;
+ }
+
+ public void setClassPath(String classPath) {
+ this.classPath = classPath;
+ }
+
+ public int getProcessCount() {
+ return processCount;
+ }
+
+ public void setProcessCount(int processCount) {
+ this.processCount = processCount;
+ }
+
+ public int getStartingRank() {
+ return startingRank;
+ }
+
+ public void setStartingRank(int startingRank) {
+ this.startingRank = startingRank;
+ }
+
+ public ArrayList<String> getJvmArgs() {
+ return jvmArgs;
+ }
+
+ public void setJvmArgs(ArrayList<String> jvmArgs) {
+ this.jvmArgs = jvmArgs;
+ }
+
+ public String getWorkingDirectory() {
+ return workingDirectory;
+ }
+
+ public void setWorkingDirectory(String workingDirectory) {
+ this.workingDirectory = workingDirectory;
+ }
+
+ public String getMainClass() {
+ return mainClass;
+ }
+
+ public void setMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ public String getDeviceName() {
+ return deviceName;
+ }
+
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
+ }
+
+ public String getConfFileContents() {
+ return confFileContents;
+ }
+
+ public void setConfFileContents(String confFileContents) {
+ this.confFileContents = confFileContents;
+ }
+
+ public ArrayList<String> getAppArgs() {
+ return appArgs;
+ }
+
+ public void setAppArgs(ArrayList<String> appArguments) {
+ this.appArgs = appArguments;
+ }
+
+ public UUID getTicketID() {
+ return ticketID;
+ }
+
+ public void setTicketID(UUID ticketID) {
+ this.ticketID = ticketID;
+ }
+
+ public boolean isZippedSource() {
+ return zippedSource;
+ }
+
+ public void setZippedSource(boolean zippedSource) {
+ this.zippedSource = zippedSource;
+ }
+
+ public String getSourceCode() {
+ return sourceCode;
+ }
+
+ public void setSourceCode(String sourceCode) {
+ this.sourceCode = sourceCode;
+ }
+
+ public String getUserID() {
+ return userID;
+ }
+
+ public void setUserID(String userID) {
+ this.userID = userID;
+ }
+
+ public int getNetworkProcessCount() {
+ return networkProcessCount;
+ }
+
+ public void setNetworkProcessCount(int networkProcessCount) {
+ this.networkProcessCount = networkProcessCount;
+ }
+
+ public int getTotalProcessCount() {
+ return totalProcessCount;
+ }
+
+ public void setTotalProcessCount(int totalProcessCount) {
+ this.totalProcessCount = totalProcessCount;
+ }
+
+ public String getNetworkDevice() {
+ return networkDevice;
+ }
+
+ public void setNetworkDevice(String networkDevice) {
+ this.networkDevice = networkDevice;
+ }
+
+ public boolean isDebug() {
+ return isDebug;
+ }
+
+ public void setDebug(boolean isDebug) {
+ this.isDebug = isDebug;
+ }
+
+ public boolean isProfiler() {
+ return isProfiler;
+ }
+
+ public void setProfiler(boolean isProfiler) {
+ this.isProfiler = isProfiler;
+ }
+
+ public int getDebugPort() {
+ return debugPort;
+ }
+
+ public void setDebugPort(int debugPort) {
+ this.debugPort = debugPort;
+ }
+
+ public MPJProcessTicket() {
+ this.classPath = "";
+ this.processCount = 0;
+ this.startingRank = 0;
+ this.jvmArgs = new ArrayList<String>();
+ this.workingDirectory = "";
+ this.mainClass = "";
+ this.deviceName = "";
+ this.confFileContents = "";
+ this.appArgs = new ArrayList<String>();
+
+ zippedSource = false;
+ ticketID = UUID.randomUUID();
+ sourceCode = "";
+ userID = "";
+ totalProcessCount = -1;
+ networkProcessCount = -1;
+ networkDevice = "niodev";
+ isDebug = false;
+ isProfiler = false;
+ debugPort = 24500;
+ }
+
+ public MPJProcessTicket(UUID ticketID, String classPath, int processCount,
+ int startingRank, ArrayList<String> jvmArgs, String workingDirectory,
+ String mainClass, boolean zippedCode, String codeFolder,
+ String deviceName, String confFileContents, ArrayList<String> appArgs,
+ int clientPort, String clientHostAddress, String userID,
+ int nioProcessCount, int totalProcessCount, String networkDevice,
+ boolean isDebug, boolean isProfiler, int debugPort) {
+ super();
+ this.ticketID = ticketID;
+ this.classPath = classPath;
+ this.processCount = processCount;
+ this.startingRank = startingRank;
+ this.jvmArgs = jvmArgs;
+ this.workingDirectory = workingDirectory;
+ this.mainClass = mainClass;
+ this.zippedSource = zippedCode;
+ this.sourceCode = codeFolder;
+ this.deviceName = deviceName;
+ this.confFileContents = confFileContents;
+ this.appArgs = appArgs;
+ this.totalProcessCount = totalProcessCount;
+ this.networkProcessCount = nioProcessCount;
+ this.networkDevice = networkDevice;
+ this.isDebug = isDebug;
+ this.isProfiler = isProfiler;
+ this.debugPort = debugPort;
+ }
+
+ public MPJXml ToXML() {
+
+ // Send true as parameter in case you want sourceCode tag in XML Ticket
+ return ToXML(true);
+ }
+
+ public MPJXml ToXML(boolean src) {
+ MPJXml processInfoXML = new MPJXml(getTag(RTConstants.MPJ_PROCESS_INFO));
+
+ MPJXml ticketIDXML = new MPJXml(getTag(RTConstants.TICKET_ID));
+ ticketIDXML.setText(this.ticketID.toString());
+ processInfoXML.appendChild(ticketIDXML);
+
+ MPJXml classPathXML = new MPJXml(getTag(RTConstants.CLASS_PATH));
+ classPathXML.setText(this.classPath);
+ processInfoXML.appendChild(classPathXML);
+
+ MPJXml processCountXML = new MPJXml(getTag(RTConstants.PROCESS_COUNT));
+ processCountXML.setText(Integer.toString(this.processCount));
+ processInfoXML.appendChild(processCountXML);
+
+ MPJXml startingRankXML = new MPJXml(getTag(RTConstants.STARTING_RANK));
+ startingRankXML.setText(Integer.toString(this.startingRank));
+ processInfoXML.appendChild(startingRankXML);
+
+ MPJXml jvmArgsXML = new MPJXml(getTag(RTConstants.JVM_ARGS));
+ for (String argument : this.jvmArgs) {
+ MPJXml argumentXML = new MPJXml(getTag(RTConstants.ARGUMENT));
+ argumentXML.setText(argument);
+ jvmArgsXML.appendChild(argumentXML);
+ }
+ processInfoXML.appendChild(jvmArgsXML);
+
+ MPJXml workingDirectoryXML = new MPJXml(
+ getTag(RTConstants.WORKING_DIRECTORY));
+ workingDirectoryXML.setText(this.workingDirectory);
+ processInfoXML.appendChild(workingDirectoryXML);
+
+ MPJXml zippedCodeXML = new MPJXml(getTag(RTConstants.ZIPPED_SOURCE));
+ zippedCodeXML.setText(Boolean.toString(this.zippedSource));
+ processInfoXML.appendChild(zippedCodeXML);
+
+ if (src) {
+ MPJXml codeFolderXML = new MPJXml(getTag(RTConstants.SOURCE_CODE));
+ codeFolderXML.setText(this.sourceCode);
+ processInfoXML.appendChild(codeFolderXML);
+ }
+ MPJXml mainClassXML = new MPJXml(getTag(RTConstants.MAIN_CLASS));
+ mainClassXML.setText(this.mainClass);
+ processInfoXML.appendChild(mainClassXML);
+
+ MPJXml deviceNameXML = new MPJXml(getTag(RTConstants.DEVICE_NAME));
+ deviceNameXML.setText(this.deviceName);
+ processInfoXML.appendChild(deviceNameXML);
+
+ MPJXml confFileContentsXML = new MPJXml(
+ getTag(RTConstants.CONF_FILE_CONTENTS));
+ confFileContentsXML.setText(this.confFileContents);
+ processInfoXML.appendChild(confFileContentsXML);
+
+ MPJXml appArgsXML = new MPJXml(getTag(RTConstants.APP_ARGS));
+ for (String argument : this.appArgs) {
+ MPJXml argumentXML = new MPJXml(getTag(RTConstants.ARGUMENT));
+ argumentXML.setText(argument);
+ appArgsXML.appendChild(argumentXML);
+ }
+ processInfoXML.appendChild(appArgsXML);
+
+ MPJXml userIDXML = new MPJXml(getTag(RTConstants.USER_ID));
+ userIDXML.setText(this.userID);
+ processInfoXML.appendChild(userIDXML);
+
+ MPJXml nioProcessCountXML = new MPJXml(
+ getTag(RTConstants.NETWORK_PROCESS_COUNT));
+ nioProcessCountXML.setText(Integer.toString(this.networkProcessCount));
+ processInfoXML.appendChild(nioProcessCountXML);
+
+ MPJXml totalProcessCountXML = new MPJXml(
+ getTag(RTConstants.TOTAL_PROCESS_COUNT));
+ totalProcessCountXML.setText(Integer.toString(this.totalProcessCount));
+ processInfoXML.appendChild(totalProcessCountXML);
+
+ MPJXml networkDeviceXML = new MPJXml(getTag(RTConstants.NETWORK_DEVICE));
+ networkDeviceXML.setText(this.networkDevice);
+ processInfoXML.appendChild(networkDeviceXML);
+
+ MPJXml debugXML = new MPJXml(getTag(RTConstants.DEBUG));
+ debugXML.setText(Boolean.toString(this.isDebug));
+ processInfoXML.appendChild(debugXML);
+
+ MPJXml debugPortXML = new MPJXml(getTag(RTConstants.DEBUG_PORT));
+ debugPortXML.setText(Integer.toString(this.debugPort));
+ processInfoXML.appendChild(debugPortXML);
+
+ MPJXml profilerXML = new MPJXml(getTag(RTConstants.PROFILER));
+ profilerXML.setText(Boolean.toString(this.isProfiler));
+ processInfoXML.appendChild(profilerXML);
+
+ return processInfoXML;
+
+ }
+
+ public void FromXML(String xmlString) {
+ if (xmlString != null) {
+ MPJXml processInfoXml = new MPJXml(xmlString);
+
+ MPJXml ticketIDXML = processInfoXml.getChild(RTConstants.TICKET_ID);
+ this.ticketID = UUID.fromString(ticketIDXML.getText());
+
+ MPJXml classPathXML = processInfoXml.getChild(RTConstants.CLASS_PATH);
+ this.classPath = classPathXML.getText();
+
+ MPJXml processCountXML = processInfoXml
+ .getChild(RTConstants.PROCESS_COUNT);
+ this.processCount = Integer.parseInt(processCountXML.getText());
+
+ MPJXml startingRankXML = processInfoXml
+ .getChild(RTConstants.STARTING_RANK);
+ this.startingRank = Integer.parseInt(startingRankXML.getText());
+
+ MPJXml jvmArgsXML = processInfoXml.getChild(RTConstants.JVM_ARGS);
+ if (jvmArgsXML != null) {
+ ArrayList<MPJXml> arguments = jvmArgsXML
+ .getChildren(RTConstants.ARGUMENT);
+ for (MPJXml argumentXML : arguments) {
+ this.jvmArgs.add(argumentXML.getText());
+ }
+ }
+
+ MPJXml workingDirectoryXML = processInfoXml
+ .getChild(RTConstants.WORKING_DIRECTORY);
+ this.workingDirectory = workingDirectoryXML.getText();
+
+ MPJXml zippedCodeXML = processInfoXml.getChild(RTConstants.ZIPPED_SOURCE);
+ this.zippedSource = Boolean.parseBoolean(zippedCodeXML.getText());
+
+ MPJXml codeFolderXML = processInfoXml.getChild(RTConstants.SOURCE_CODE);
+ this.sourceCode = codeFolderXML.getText();
+
+ MPJXml mainClassXML = processInfoXml.getChild(RTConstants.MAIN_CLASS);
+ this.mainClass = mainClassXML.getText();
+
+ MPJXml deviceNameXML = processInfoXml.getChild(RTConstants.DEVICE_NAME);
+ this.deviceName = deviceNameXML.getText();
+
+ MPJXml confFileContentsXML = processInfoXml
+ .getChild(RTConstants.CONF_FILE_CONTENTS);
+ this.confFileContents = confFileContentsXML.getText();
+
+ MPJXml appArgsXML = processInfoXml.getChild(RTConstants.APP_ARGS);
+ if (appArgsXML != null) {
+ ArrayList<MPJXml> arguments = appArgsXML
+ .getChildren(RTConstants.ARGUMENT);
+ for (MPJXml argumentXML : arguments) {
+ this.appArgs.add(argumentXML.getText());
+ }
+ }
+
+ MPJXml userIDXML = processInfoXml.getChild(RTConstants.USER_ID);
+ this.userID = userIDXML.getText();
+
+ MPJXml nioProcessCountXML = processInfoXml
+ .getChild(RTConstants.NETWORK_PROCESS_COUNT);
+ this.networkProcessCount = Integer.parseInt(nioProcessCountXML.getText());
+
+ MPJXml totalProcessCountXML = processInfoXml
+ .getChild(RTConstants.TOTAL_PROCESS_COUNT);
+ this.totalProcessCount = Integer.parseInt(totalProcessCountXML.getText());
+
+ MPJXml networkDeviceXML = processInfoXml
+ .getChild(RTConstants.NETWORK_DEVICE);
+ this.networkDevice = networkDeviceXML.getText();
+
+ MPJXml debugXML = processInfoXml.getChild(RTConstants.DEBUG);
+ this.isDebug = Boolean.parseBoolean(debugXML.getText());
+
+ MPJXml debugPortXML = processInfoXml.getChild(RTConstants.DEBUG_PORT);
+ this.debugPort = Integer.parseInt(debugPortXML.getText());
+
+ MPJXml profilerXML = processInfoXml.getChild(RTConstants.PROFILER);
+ this.isProfiler = Boolean.parseBoolean(profilerXML.getText());
+ }
+
+ }
+
+ public String getTag(String tagText) {
+ return "<" + tagText.trim() + "/>";
+ }
+
+ /*
+ * public static void main(String args[]) {
+ *
+ * ArrayList<String> jvmArgs = new ArrayList<String>(); jvmArgs.add("arg0");
+ * jvmArgs.add("arg1"); ArrayList<String> appArgs = new ArrayList<String>();
+ * appArgs.add("arg0"); appArgs.add("arg1"); MPJProcessTicket ticket = new
+ * MPJProcessTicket(UUID.randomUUID(), "ClassPath", 10, 1, jvmArgs,
+ * "workingDirectory", "mainClass", false, "", "deviceName",
+ * "confFileContents", appArgs, 1000, "localhost", "Khurram", 5, 10, "niodev",
+ * false, false, 24500); IOHelper.writeCharacterFile("D:\\Test.xml",
+ * ticket.ToXML().toXmlString()); String xmlString =
+ * IOHelper.readCharacterFile("D:\\Test.xml"); MPJProcessTicket ticket2 = new
+ * MPJProcessTicket(); ticket2.FromXML(xmlString);
+ * IOHelper.writeCharacterFile("D:\\Test2.xml",
+ * ticket2.ToXML().toXmlString());
+ *
+ * }
+ */
+
+}
diff --git a/src/runtime/common/MPJRuntimeException.java b/src/runtime/common/MPJRuntimeException.java
new file mode 100755
index 0000000..d40b51f
--- /dev/null
+++ b/src/runtime/common/MPJRuntimeException.java
@@ -0,0 +1,56 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJRuntimeException.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Fri Aug 12 16:50:29 BST 2005
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2005/08/12 19:13:06 $
+ */
+
+package runtime.common;
+
+import mpjdev.MPJDevException;
+
+public class MPJRuntimeException extends RuntimeException {
+
+ public MPJRuntimeException() {
+ super();
+ }
+
+ public MPJRuntimeException(String message) {
+ super(message);
+ }
+
+ public MPJRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/src/runtime/common/MPJUtil.java b/src/runtime/common/MPJUtil.java
new file mode 100644
index 0000000..78b815f
--- /dev/null
+++ b/src/runtime/common/MPJUtil.java
@@ -0,0 +1,165 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJUtil.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.common;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Map;
+
+import runtime.daemonmanager.DMConstants;
+
+public class MPJUtil {
+
+ public static ArrayList<String> readMPJFile(String path) {
+
+ ArrayList<String> machineList = new ArrayList<String>();
+ FileInputStream stream = null;
+ InputStreamReader streamReader = null;
+ BufferedReader bufferedReader = null;
+
+ try {
+ stream = new FileInputStream(path);
+ streamReader = new InputStreamReader(stream, "UTF-8");
+ bufferedReader = new BufferedReader(streamReader);
+ String line = null;
+ while ((line = bufferedReader.readLine()) != null) {
+ line = line.trim();
+ if (line != "" && !machineList.contains(line)) {
+ machineList.add(line);
+ }
+ }
+
+ }
+ catch (Exception exp) {
+
+ System.out.println("<" + path + "> file cannot " + " be found."
+ + " The starter module assumes "
+ + "it to be in the current directory.");
+ return null;
+
+ }
+ finally {
+ try {
+ bufferedReader.close();
+ stream.close();
+
+ }
+ catch (Exception e) {
+
+ // System.out.println(exp.getMessage());
+ }
+ }
+
+ return machineList;
+ }
+
+ public static ArrayList<String> readMachineFile(String path) {
+ return readMPJFile(path);
+ }
+
+ public static String getConfigValue(String property) {
+ for (String configLine : readWrapperConfigFile()) {
+ if (configLine.indexOf(property) > -1) {
+ String[] tokens = configLine.split("=");
+ if (tokens.length > 1)
+ return tokens[1];
+ }
+ }
+ return "";
+ }
+
+ public static ArrayList<String> readWrapperConfigFile() {
+ String path = getWrapperConfPath();
+ return readMPJFile(path);
+ }
+
+ public static String getWrapperConfPath() {
+ return getMPJHomeDir() + DMConstants.CONF + File.separator
+ + DMConstants.WRAPPER_CONF;
+
+ }
+
+ public static String getMPJHomeDir() {
+ String mpjHomeDir = "";
+ Map<String, String> map = System.getenv();
+ mpjHomeDir = map.get("MPJ_HOME");
+ if (mpjHomeDir != "") {
+ if (!mpjHomeDir.endsWith("/"))
+ mpjHomeDir = mpjHomeDir + File.separator;
+ }
+ return mpjHomeDir;
+ }
+
+ public static String getWrapperLogPath() {
+ return getMPJHomeDir() + DMConstants.LOGS + File.separator
+ + DMConstants.WRAPPER_LOG;
+ }
+
+ public static String getJarPath(String jarName) {
+ return getMPJHomeDir() + DMConstants.LIB + File.separator + jarName
+ + DMConstants.EXT_JAR;
+ }
+
+ public static String getMachineFilePath(String fileName) {
+ return fileName;
+ }
+
+ public static String getMachineFilePath() {
+ return DMConstants.MACHINES;
+ }
+
+ public static boolean IsBusy(final InetAddress remote, int port) {
+ try {
+ Socket s = new Socket(remote, port);
+ s.close();
+ return true;
+ }
+ catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static String FormatMessage(String host, String message) {
+ return "[" + host + "] " + message;
+ }
+
+}
diff --git a/src/runtime/common/MPJXml.java b/src/runtime/common/MPJXml.java
new file mode 100644
index 0000000..1b857fa
--- /dev/null
+++ b/src/runtime/common/MPJXml.java
@@ -0,0 +1,259 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJUtil.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : April 03, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.common;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class MPJXml {
+ /**
+ * @uml.property name="xmlString"
+ */
+ private String xmlString;
+ /**
+ * @uml.property name="xmlNode"
+ * @uml.associationEnd multiplicity="(1 1)"
+ */
+ Node xmlNode = null;
+
+ private Element elem() {
+ if (xmlNode instanceof Element)
+ return (Element) xmlNode;
+ return null;
+ }
+
+ public MPJXml(String xml) {
+
+ if (xml == "")
+ throw new NullPointerException();
+ this.xmlString = stripInValidXMLCharacters(xml).trim();
+
+ parseXML();
+ }
+
+ public String stripInValidXMLCharacters(String in) {
+ StringBuffer out = new StringBuffer(); // Used to hold the output.
+ char current; // Used to reference the current character.
+
+ if (in == null || ("".equals(in)))
+ return ""; // vacancy test.
+ for (int i = 0; i < in.length(); i++) {
+ current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught
+ // here; it should not happen.
+ if ((current == 0x9) || (current == 0xA) || (current == 0xD)
+ || ((current >= 0x20) && (current <= 0xD7FF))
+ || ((current >= 0xE000) && (current <= 0xFFFD))
+ || ((current >= 0x10000) && (current <= 0x10FFFF)))
+ out.append(current);
+ }
+ return out.toString();
+ }
+
+ private MPJXml(Element xmlNode) {
+ this.xmlNode = xmlNode;
+ }
+
+ public Node getNode() {
+ return xmlNode;
+ }
+
+ private String localName() {
+ if (elem() != null)
+ return elem().getTagName();
+ return "";
+ }
+
+ public String getTagName() {
+ return localName();
+ }
+
+ public String getAttrib(String arg) {
+ if (elem() != null) {
+ if (elem().hasAttribute(arg)) {
+ return elem().getAttribute(arg);
+ }
+ }
+ return "";
+ }
+
+ public void setAttrib(String attribName, Boolean attribVal) {
+ setAttrib(attribName, attribVal.toString());
+ }
+
+ public void setAttrib(String attribName, double attribVal) {
+ setAttrib(attribName, ((Double) attribVal).toString());
+ }
+
+ public void setAttrib(String attribName, int attribVal) {
+ setAttrib(attribName, Integer.toString(attribVal));
+ }
+
+ public void setAttrib(String attribName, String attribVal) {
+ if (elem() != null)
+ elem().setAttribute(attribName, attribVal);
+ }
+
+ public MPJXml getChild(String tagName) {
+ ArrayList<MPJXml> xl = getChildren(tagName);
+ if (xl.size() > 0) {
+ return xl.get(0);
+ }
+ return null;
+ }
+
+ public ArrayList<MPJXml> getChildren() {
+ ArrayList<MPJXml> xl = new ArrayList<MPJXml>();
+ NodeList nodes = xmlNode.getChildNodes();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ if (nodes.item(i) instanceof Element) {
+ xl.add(new MPJXml((Element) nodes.item(i)));
+ }
+ }
+ return xl;
+ }
+
+ public ArrayList<MPJXml> getChildren(String tagName) {
+ ArrayList<MPJXml> taggedChildren = new ArrayList<MPJXml>();
+ ArrayList<MPJXml> xl = getChildren();
+ for (int i = 0; i < xl.size(); i++) {
+ if (xl.get(i).getTagName().equals(tagName)) {
+ taggedChildren.add(xl.get(i));
+ }
+ }
+ return taggedChildren;
+ }
+
+ public MPJXml appendChild(MPJXml xml) {
+ try {
+ org.w3c.dom.Document domYouAreAddingTheNodeTo = xmlNode
+ .getOwnerDocument();
+ Node tempNode = domYouAreAddingTheNodeTo.importNode(xml.xmlNode, true);
+ this.xmlNode.appendChild(tempNode);
+ }
+ catch (Exception ex) {
+ }
+ return this;
+ }
+
+ public String getText() {
+ return xmlNode.getTextContent();
+ }
+
+ public void setText(String text) {
+ xmlNode.setTextContent(text);
+ }
+
+ private Boolean parseXML() {
+ DocumentBuilder documentBuilder;
+ org.w3c.dom.Document dom = null;
+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
+ .newInstance();
+ docBuilderFactory.setIgnoringElementContentWhitespace(true);
+ try {
+ documentBuilder = docBuilderFactory.newDocumentBuilder();
+ }
+ catch (ParserConfigurationException e) {
+
+ System.out.println("Wrong parser configuration: " + e.getMessage());
+ return null;
+ }
+ try {
+ dom = documentBuilder.newDocument(); // initialize
+ xmlNode = dom.getDocumentElement(); // initialize
+ InputSource in = new InputSource(new StringReader(xmlString));
+ in.setEncoding("UTF-8");
+ dom = documentBuilder.parse(in);
+ xmlNode = dom.getDocumentElement();
+ return true;
+ }
+ catch (SAXException e) {
+ System.out.println("Wrong MPJXml file structure: " + e.getMessage());
+ return null;
+ }
+ catch (IOException e) {
+ System.out.println("Could not read source file: " + e.getMessage());
+ }
+
+ return false;
+ }
+
+ public String toXmlString() {
+ // set up a transformer
+ TransformerFactory transfac = TransformerFactory.newInstance();
+ Transformer trans;
+ try {
+ trans = transfac.newTransformer();
+ }
+ catch (TransformerConfigurationException e1) {
+ e1.printStackTrace();
+ return "";
+ }
+ trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ // create string from xml tree
+ StringWriter sw = new StringWriter();
+ StreamResult result = new StreamResult(sw);
+ DOMSource source = new DOMSource(xmlNode.getOwnerDocument());
+ try {
+ trans.transform(source, result);
+ }
+ catch (TransformerException e) {
+ e.printStackTrace();
+ }
+ return sw.toString();
+ }
+}
diff --git a/src/runtime/common/RTConstants.java b/src/runtime/common/RTConstants.java
new file mode 100644
index 0000000..f417d28
--- /dev/null
+++ b/src/runtime/common/RTConstants.java
@@ -0,0 +1,66 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : RTConstants.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 28, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.common;
+
+public class RTConstants {
+
+ public static String MPJ_PROCESS_INFO = "MPJProcessInfo";
+ public static String CLASS_PATH = "ClassPath";
+ public static String PROCESS_COUNT = "ProcessCount";
+ public static String STARTING_RANK = "StartingRank";
+ public static String JVM_ARGS = "JvmArgs";
+ public static String ARGUMENT = "Argument";
+ public static String WORKING_DIRECTORY = "WorkingDirectory";
+ public static String MAIN_CLASS = "MainClass";
+ public static String DEVICE_NAME = "DeviceName";
+ public static String CONF_FILE_CONTENTS = "ConfFileContents";
+ public static String APP_ARGS = "AppArgs";
+ public static String CLIENT_PORT = "ClientPort";
+ public static String CLIENT_HOST_NAME = "ClientHostName";
+ public static String TICKET_ID = "TicketID";
+ public static String ZIPPED_SOURCE = "ZippedSource";
+ public static String SOURCE_CODE = "sourceCode";
+ public static String USER_ID = "UserID";
+ public static String TOTAL_PROCESS_COUNT = "TotalProcessCount";
+ public static String NETWORK_PROCESS_COUNT = "NetworkProcessCount";
+ public static String NETWORK_DEVICE = "NetworkDevice";
+ public static String DEBUG = "Debug";
+ public static String DEBUG_PORT = "DebugPort";
+ public static String PROFILER = "Profiler";
+
+}
diff --git a/src/runtime/daemon/ConnectionManager.java b/src/runtime/daemon/ConnectionManager.java
new file mode 100644
index 0000000..77a079a
--- /dev/null
+++ b/src/runtime/daemon/ConnectionManager.java
@@ -0,0 +1,83 @@
+package runtime.daemon;
+
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ConnectionManager.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 27, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+import java.io.DataOutputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+public class ConnectionManager extends Thread {
+ public volatile boolean isRun = true;
+
+ public ConnectionManager() {
+ }
+
+ public void run() {
+
+ while (isRun) {
+ for (Socket sock : MPJDaemon.servSockets.keySet()) {
+ OutputStream outToServer = null;
+ try {
+ String line = "@Ping#\n";
+ outToServer = sock.getOutputStream();
+ DataOutputStream out = new DataOutputStream(outToServer);
+ out.write(line.getBytes(), 0, line.getBytes().length);
+
+ }
+ catch (Exception e) {
+ System.out.println("Client Disconnected");
+ MPJDaemon.servSockets.get(sock).killProcesses();
+ MPJDaemon.servSockets.remove(sock);
+ }
+ try {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ System.out.println("Exiting connection manager thread");
+ }
+}
diff --git a/src/runtime/daemon/HybridStarter.java b/src/runtime/daemon/HybridStarter.java
new file mode 100644
index 0000000..4dfbb36
--- /dev/null
+++ b/src/runtime/daemon/HybridStarter.java
@@ -0,0 +1,313 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2013
+ 1. SEECS National University of Sciences and Technology (NUST), Pakistan
+ 2. Ansar Javed (2013 - 2013)
+ 3. Mohsan Jameel (2013 - 2013)
+ 4. Aamir Shafi (2005 -2013)
+ 5. Bryan Carpenter (2005 - 2013)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : HybridStarter.java
+ * Author : Ansar Javed, Mohsan Jameel, Aamir Shafi, Bibrak Qamar
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+/**
+ * This class is used for Hybrid based system stater
+ */
+package runtime.daemon;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+
+import xdev.smpdev.SMPDevProcess;
+
+public class HybridStarter {
+
+ String wdir = null;
+ String config = null;
+ int processes = 0;
+ JarClassLoader classLoader = null;
+ URLClassLoader urlClassLoader = null;
+ String name = null;
+ String className = null;
+ String deviceName = null;
+ String packageName = null;
+ String cmdClassPath = null;
+ String mpjHomeDir = null;
+ String[] nargs = null;
+ String loader = null;
+ String hostName = null;
+ String[] arvs = null;
+ Method[] m;
+ Method[] method;
+ int x;
+ Class[] c;
+ int num;
+ static final Object monitor = new Object();
+ SMPDevProcess[] smpProcess;
+ Integer rank = new Integer(-1);
+ static String appPath = "";
+
+ public HybridStarter() {
+ }
+
+ /**
+ * Executes MPJ program in a new JVM. This method is invoked in main method of
+ * this class, which is started by MPJDaemon. This method can only start a new
+ * JVM but can't start multiple threads in one JVM.
+ *
+ * @param args
+ * Arguments to this method. args[0] is wdir 'String', args[1] number
+ * of processes, args[2] is deviceName, and args[3] is rank started
+ * by this process. args[4] is className ... it will only be used if
+ * URL does not point to a JAR file.
+ */
+ public void execute(String args[]) throws Exception {
+
+ InetAddress localaddr = InetAddress.getLocalHost();
+ hostName = localaddr.getHostName();
+ wdir = args[0]; // this contains working directory ...
+ processes = (new Integer(args[1])).intValue();
+ deviceName = args[2];
+ loader = args[3];
+ cmdClassPath = args[4];
+ className = args[5];
+ int ARGS_USED_HERE = 6;
+ nargs = new String[(args.length - ARGS_USED_HERE)];
+ System.arraycopy(args, ARGS_USED_HERE, nargs, 0, nargs.length);
+
+ arvs = new String[(nargs.length + 3)];
+
+ Runnable[] ab = new Runnable[processes];
+
+ smpProcess = new SMPDevProcess[processes];
+ c = new Class[processes];
+ m = new Method[processes];
+ method = new Method[processes];
+
+ for (x = 0; x < processes; x++) {
+ // System.out.println("x " + x);
+ ab[x] = new Runnable() {
+
+ String argNew[] = new String[arvs.length];
+
+ public void run() {
+
+ int index = Integer.parseInt(Thread.currentThread().getName());
+
+ synchronized (monitor) {
+
+ try {
+ String mpjHome = System.getenv("MPJ_HOME");
+
+ String libPath = null;
+
+ if (!cmdClassPath.equals("EMPTY")) {
+ libPath = cmdClassPath + File.pathSeparator + mpjHome
+ + "/lib/mpi.jar" + File.pathSeparator + mpjHome
+ + "/lib/mpjdev.jar";
+ } else {
+ libPath = mpjHome + "/lib/mpi.jar" + File.pathSeparator
+ + mpjHome + "/lib/mpjdev.jar";
+ }
+
+ if (className.endsWith(".jar")) {
+ if ((new File(className)).isAbsolute()) {
+ appPath = className;
+ } else {
+ appPath = wdir + "/" + className;
+ }
+ } else {
+ appPath = wdir;
+ }
+
+ appPath = appPath + File.pathSeparator + libPath;
+
+ ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+
+ StringTokenizer tok = new StringTokenizer(appPath,
+ File.pathSeparator);
+ int count = tok.countTokens();
+ String[] tokArr = new String[count];
+ File[] f = new File[count];
+ URL[] urls = new URL[count];
+
+ for (int i = 0; i < count; i++) {
+ tokArr[i] = tok.nextToken();
+ f[i] = new File(tokArr[i]);
+ urls[i] = f[i].toURI().toURL();
+ }
+
+ URLClassLoader ucl = new URLClassLoader(urls);
+ Thread.currentThread().setContextClassLoader(ucl);
+
+ if (className.endsWith(".jar")) {
+ String jarFileName = className;
+ JarFile jarFile = new JarFile(jarFileName);
+ Attributes attr = jarFile.getManifest().getMainAttributes();
+ name = attr.getValue(Attributes.Name.MAIN_CLASS);
+ c[index] = Class.forName(name, true, ucl);
+ } else {
+ name = className;
+ c[index] = Class.forName(name, true, ucl);
+ }
+
+ } catch (Exception exx) {
+ exx.printStackTrace();
+ }
+
+ arvs[1] = config;
+ arvs[2] = deviceName;
+
+ for (int i = 0; i < nargs.length; i++) {
+ arvs[i + 3] = nargs[i];
+ }
+
+ try {
+
+ if (classLoader != null && loader.equals("useRemoteLoader")) {
+ // System.out.println("Remote loader invoking class");
+ classLoader.invokeClass(c[num], arvs);
+ } else {
+
+ m[index] = c[index].getMethod("main",
+ new Class[] { arvs.getClass() });
+ m[index].setAccessible(true);
+ int mods = m[index].getModifiers();
+ if (m[index].getReturnType() != void.class
+ || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) {
+ throw new NoSuchMethodException("main");
+ }
+ method[index] = m[index];
+ }
+ } catch (Exception exp) {
+ }
+ // //// placed end //////
+ } // end monitor
+
+ synchronized (monitor) {
+ int val = rank.intValue();
+ val++;
+ rank = new Integer(val);
+ arvs[0] = rank.toString();
+ argNew[0] = rank.toString();
+ }
+
+ for (int k = 1; k < arvs.length; k++) {
+ argNew[k] = arvs[k];
+ }
+
+ // FIXME: need an elegant way to fill the index 1
+ // element, the issue is that it's filled earlier
+ // and here we are actually re-writing it ..
+ // don't like it ..but atleast works now!
+ argNew[1] = (new Integer(processes)).toString();
+
+ boolean tryAgain = true;
+
+ while (tryAgain) {
+
+ try {
+
+ method[index].invoke(null, new Object[] { argNew });
+ tryAgain = false;
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ tryAgain = false;
+ System.exit(0);
+ // tryAgain = true;
+ // System.out.println(" exception while invoking in " +
+ // Thread.currentThread());
+ // goto TRY_AGAIN ;
+ // This should not happen, as we have disabled access checks
+ }
+ }
+
+ }
+ };
+ }
+
+ try {
+ int nprocs = processes;
+ Thread procs[] = new Thread[nprocs];
+ // System.out.println("nprocs " + nprocs);
+ // FIX ME By Aleem Akhtar :
+ // setting all threads thred group to MPI${rank}.
+ // so that we can differeniate them from other threads i.e. system threads
+ for (num = 0; num < nprocs; num++) {
+ // procs[num] = new Thread(ab[num]);
+ // smpProcess[num] = new SMPDevProcess("smp-threadgroup"+num);
+ smpProcess[num] = new SMPDevProcess("MPI" + num);
+ procs[num] = new Thread(smpProcess[num], ab[num], "" + nprocs);
+ String name = String.valueOf(num);
+ procs[num].setName(name);
+ procs[num].start();
+
+ // System.out.println("thread after start" + num+" Thread "+
+ // Thread.currentThread()+" Time "+System.nanoTime());
+ // procs[num].join();
+ // Thread.currentThread().sleep(500);
+ }
+ for (int i = 0; i < nprocs; i++) {
+ procs[i].join();
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } // end execute
+
+ public static void main(String args[]) throws Exception {
+ /*
+ * if(MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ * MPJDaemon.logger.debug ("HybridDaemon.HybridStarter: Starting Thread"); }
+ */
+ HybridStarter mstarter = new HybridStarter();
+ mstarter.execute(args);
+ } // end main
+
+ public static void visitAllDirs(File dir) {
+ if (dir.isDirectory()) {
+ appPath += dir + ":";
+
+ String[] children = dir.list();
+ for (int i = 0; i < children.length; i++) {
+ visitAllDirs(new File(dir, children[i]));
+ }
+ }
+ }
+
+}
diff --git a/src/runtime/daemon/JarClassLoader.java b/src/runtime/daemon/JarClassLoader.java
new file mode 100644
index 0000000..ec8569c
--- /dev/null
+++ b/src/runtime/daemon/JarClassLoader.java
@@ -0,0 +1,140 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : JarClassLoader.java
+ * Author : Taken from URL below ...
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.7 $
+ * Updated : $Date: 2005/08/23 17:09:31 $
+ */
+
+/*
+ * This file is taken from a Sun's tutorial on JAR files. It can be
+ * seen on the following URL ...
+ * http://java.sun.com/developer/Books/javaprogramming/JAR/api/
+ */
+
+package runtime.daemon;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.Attributes;
+
+/**
+ * A class loader for loading jar files, both local and remote.
+ */
+public class JarClassLoader extends URLClassLoader {
+ private URL url;
+
+ /**
+ * Creates a new JarClassLoader for the specified url. First url should point
+ * to user app jar. This jar would be used to find the main class name
+ *
+ * @param url
+ * the url of the jar file
+ */
+ public JarClassLoader(URL[] urls) {
+ super(urls);
+ this.url = urls[0];
+ }
+
+ /**
+ * Returns the name of the jar file main class, or null if no "Main-Class"
+ * manifest attributes was defined.
+ */
+ public String getMainClassName() throws IOException {
+ URL u = new URL("jar", "", url + "!/");
+ JarURLConnection uc = (JarURLConnection) u.openConnection();
+ Attributes attr = uc.getMainAttributes();
+ return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null;
+ }
+
+ /**
+ * Invokes the application in this jar file given the name of the main class
+ * and an array of arguments. The class must define a static method "main"
+ * which takes an array of String arguemtns and is of return type "void".
+ *
+ * @param name
+ * the name of the main class
+ * @param args
+ * the arguments for the application
+ * @exception ClassNotFoundException
+ * if the specified class could not be found
+ * @exception NoSuchMethodException
+ * if the specified class does not contain a "main" method
+ * @exception InvocationTargetException
+ * if the application raised an exception
+ */
+ public void invokeClass(Class c, String[] args)
+ throws ClassNotFoundException, NoSuchMethodException,
+ InvocationTargetException {
+ // Class c = loadClass(name);
+ Method m = c.getMethod("main", new Class[] { args.getClass() });
+ m.setAccessible(true);
+ int mods = m.getModifiers();
+ if (m.getReturnType() != void.class || !Modifier.isStatic(mods)
+ || !Modifier.isPublic(mods)) {
+ throw new NoSuchMethodException("main");
+ }
+ try {
+ m.invoke(null, new Object[] { args });
+ }
+ catch (IllegalAccessException e) {
+ e.printStackTrace();
+ // This should not happen, as we have disabled access checks
+ }
+ }
+
+ public static void main(String args[]) {
+ /*
+ * //if (args.length < 2) { //
+ * System.out.println("Usage: java JarClassLoader <URL> <rank>"); //
+ * System.exit(0); //}
+ *
+ * // JarClassLoader loader = new JarClassLoader(); //args[0] ==
+ * http://holly.dsg.port.ac.uk:15000/client.jar //args[1] == 0 (the rank)
+ *
+ * /* String config = null; String conf =
+ * args[0].substring(0,(args[0].lastIndexOf("/")+1));
+ * System.out.println("conf ==<"+conf+">"); config = conf+"mpjdev.conf";
+ * System.out.println("config ==<"+config+">"); try { JarClassLoader
+ * classLoader = new JarClassLoader( new URL(args[0]) ); String name =
+ * classLoader.getMainClassName(); System.out.println("name ==>"+name);
+ * Class c = classLoader.loadClass(name); //String arvs[] = new String[2];
+ * //arvs[0] = args[1]; //arvs[1] = config; classLoader.invokeClass(c,new
+ * String[0]); }catch(Exception ioe) { ioe.printStackTrace(); }
+ */
+ }
+
+}
diff --git a/src/runtime/daemon/MPJDaemon.java b/src/runtime/daemon/MPJDaemon.java
new file mode 100644
index 0000000..5d2797c
--- /dev/null
+++ b/src/runtime/daemon/MPJDaemon.java
@@ -0,0 +1,209 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2011
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2011)
+ 3. Bryan Carpenter (2005 - 2011)
+ 4. Mark Baker (2005 - 2011)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MPJDaemon.java
+ * Author : Aamir Shafi, Bryan Carpenter, Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.28 $
+ * Updated : $Date: 2013/11/05 17:24:47 $
+ */
+
+package runtime.daemon;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.log4j.DailyRollingFileAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.spi.LoggerRepository;
+
+import runtime.common.MPJRuntimeException;
+
+public class MPJDaemon {
+
+ private int D_SER_PORT = 10000;
+ static final boolean DEBUG = true;
+ static Logger logger = null;
+ private String mpjHomeDir = null;
+ public volatile static ConcurrentHashMap<Socket, ProcessLauncher> servSockets;
+ ConnectionManager connectionManager;
+ PortManagerThread pManager;
+
+ public MPJDaemon(String args[]) throws Exception {
+
+ System.out.println("MPJ Daemon started");
+ InetAddress localaddr = InetAddress.getLocalHost();
+ String hostName = localaddr.getHostName();
+ servSockets = new ConcurrentHashMap<Socket, ProcessLauncher>();
+ Map<String, String> map = System.getenv();
+ mpjHomeDir = map.get("MPJ_HOME");
+ createLogger(mpjHomeDir, hostName);
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("mpjHomeDir " + mpjHomeDir);
+ }
+ if (args.length == 1) {
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" args[0] " + args[0]);
+ logger.debug("setting daemon port to" + args[0]);
+ }
+
+ D_SER_PORT = new Integer(args[0]).intValue();
+
+ } else {
+ throw new MPJRuntimeException("Usage: java MPJDaemon daemonServerPort");
+ }
+ pManager = new PortManagerThread();
+ pManager.start();
+
+ connectionManager = new ConnectionManager();
+ connectionManager.start();
+ serverSocketInit();
+
+ }
+
+ private void createLogger(String homeDir, String hostName)
+ throws MPJRuntimeException {
+
+ if (logger == null) {
+
+ DailyRollingFileAppender fileAppender = null;
+
+ try {
+ fileAppender = new DailyRollingFileAppender(new PatternLayout(
+ " %-5p %c %x - %m\n"), homeDir + "/logs/daemon-" + hostName
+ + ".log", "yyyy-MM-dd-a");
+
+ Logger rootLogger = Logger.getRootLogger();
+ rootLogger.addAppender(fileAppender);
+ LoggerRepository rep = rootLogger.getLoggerRepository();
+ rootLogger.setLevel((Level) Level.ALL);
+ logger = Logger.getLogger("mpjdaemon");
+ String level = getValueFromWrapper("wrapper.logfile.loglevel.mpjdaemon");
+ logger.setLevel(Level.toLevel(level.toUpperCase(), Level.OFF));
+ }
+ catch (Exception e) {
+ throw new MPJRuntimeException(e);
+ }
+ }
+ }
+
+ private void serverSocketInit() {
+
+ ServerSocket serverSocket = null;
+ try {
+ serverSocket = new ServerSocket(D_SER_PORT);
+ do {
+ Socket servSock = serverSocket.accept();
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Accepted connection");
+ }
+ ProcessLauncher pLaunch = new ProcessLauncher(servSock);
+ servSockets.put(servSock, pLaunch);
+ pLaunch.start();
+ } while (true);
+ }
+ catch (IOException ioEx) {
+ System.out.println("Unable to attach to port!");
+ System.exit(1);
+ }
+ if (!serverSocket.isClosed())
+ try {
+ serverSocket.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (pManager != null) {
+ pManager.isRun = false;
+ }
+ if (connectionManager != null) {
+ connectionManager.isRun = false;
+ }
+
+ }
+
+ private static String getValueFromWrapper(String Parameter) {
+
+ String value = "";
+ FileInputStream in = null;
+ DataInputStream din = null;
+ BufferedReader reader = null;
+ String line = "";
+
+ try {
+
+ String path = System.getenv("MPJ_HOME") + "/conf/wrapper.conf";
+ in = new FileInputStream(path);
+ din = new DataInputStream(in);
+ reader = new BufferedReader(new InputStreamReader(din));
+
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(Parameter)) {
+ String trimmedLine = line.replaceAll("\\s+", "");
+ StringTokenizer tokenizer = new StringTokenizer(trimmedLine, "=");
+ tokenizer.nextToken();
+ value = tokenizer.nextToken();
+ break;
+ }
+ }
+
+ in.close();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return value;
+
+ }
+
+ public static void main(String args[]) {
+ try {
+
+ MPJDaemon dae = new MPJDaemon(args);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/runtime/daemon/MultithreadStarter.java b/src/runtime/daemon/MultithreadStarter.java
new file mode 100644
index 0000000..ef9302d
--- /dev/null
+++ b/src/runtime/daemon/MultithreadStarter.java
@@ -0,0 +1,129 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MultithreadStarter.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+/*
+ *@author Aamir Shafi, Bryan Carpenter
+ */
+//package xdev.smpdev;
+package runtime.daemon;
+
+/**
+ * This class is meant to be part of MPJ runtime the main aim of this class
+ * is to simply start N number of threads, where each thread is an MPI
+ * process (when it ll be part of MPJ runtime)
+ */
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class MultithreadStarter {
+ Method method = null;
+ String[] newArgs = new String[2];
+ Integer rank = new Integer(-1);
+
+ public static void main(String args[]) throws Exception {
+ if (args.length < 2) {
+ System.out.println("java className nprocs");
+ return;
+ }
+ MultithreadStarter starter = new MultithreadStarter(args);
+ }
+
+ public MultithreadStarter(String[] args) throws Exception {
+
+ Runnable ab = new Runnable() {
+ public void run() {
+ synchronized (rank) {
+ int val = rank.intValue();
+ val++;
+ rank = new Integer(val);
+ newArgs[1] = rank.toString();
+ // System.out.println(" newArgs[0] "+ newArgs[0] + "__"+
+ // Thread.currentThread() );
+ // System.out.println(" newArgs[1] "+ newArgs[1] + "__"+
+ // Thread.currentThread() );
+ }
+
+ try {
+ System.out.println(" invoking for <" + Thread.currentThread());
+ MultithreadStarter.this.method.invoke(null,
+ new Object[] { MultithreadStarter.this.newArgs });
+ System.out.println(" invoked for <" + Thread.currentThread());
+ }
+ catch (Exception e) {
+ System.out.println(" exception while invoking in "
+ + Thread.currentThread());
+ e.printStackTrace();
+ // This should not happen, as we have disabled access checks
+ }
+
+ }
+
+ };
+
+ String className = args[0];
+ int nprocs = Integer.parseInt(args[1]);
+ Thread procs[] = new Thread[nprocs];
+ newArgs[0] = args[1];
+ Class c = Class.forName(className);
+ method = c.getMethod("main", new Class[] { args.getClass() });
+ method.setAccessible(true);
+ int mods = method.getModifiers();
+
+ if (method.getReturnType() != void.class || !Modifier.isStatic(mods)
+ || !Modifier.isPublic(mods)) {
+ throw new NoSuchMethodException("main");
+ }
+
+ for (int i = 0; i < nprocs; i++) {
+
+ procs[i] = new Thread(ab);
+ // newArgs[0] = String.valueOf(i);
+ procs[i].start();
+ Thread.currentThread().sleep(50);
+ }
+ // System.out.println("className<"+className+">");
+ // System.out.println("nprocs<"+nprocs+">");
+ System.out.println("Calling join ");
+ for (int i = 0; i < nprocs; i++) {
+ procs[i].join();
+ }
+ System.out.println("Exiting multithreadstarter");
+
+ }
+
+}
diff --git a/src/runtime/daemon/OutputHandler.java b/src/runtime/daemon/OutputHandler.java
new file mode 100644
index 0000000..b260563
--- /dev/null
+++ b/src/runtime/daemon/OutputHandler.java
@@ -0,0 +1,89 @@
+package runtime.daemon;
+
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : OutputHandler.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 27, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+
+class OutputHandler extends Thread {
+
+ Process p = null;
+ Socket sock = null;
+
+ public OutputHandler(Process p, Socket cSock) {
+ this.p = p;
+ sock = cSock;
+ }
+
+ public void run() {
+
+ InputStream outp = p.getInputStream();
+ String line = "";
+ BufferedReader reader = new BufferedReader(new InputStreamReader(outp));
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("outputting ...");
+ }
+
+ try {
+ do {
+ if (!line.equals("")) {
+ line.trim();
+
+ synchronized (this) {
+ line += "\n";
+ OutputStream outToServer = sock.getOutputStream();
+ DataOutputStream out = new DataOutputStream(outToServer);
+ out.write(line.getBytes(), 0, line.getBytes().length);
+ out.flush();
+ }
+ }
+ } while ((line = reader.readLine()) != null);
+ // && !kill_signal);
+ }
+ catch (Exception e) {
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("outputHandler =>" + e.getMessage());
+ }
+ e.printStackTrace();
+ }
+ } // end run.
+}
\ No newline at end of file
diff --git a/src/runtime/daemon/PortManager.java b/src/runtime/daemon/PortManager.java
new file mode 100644
index 0000000..8a7c099
--- /dev/null
+++ b/src/runtime/daemon/PortManager.java
@@ -0,0 +1,98 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PortManager.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 27, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.daemon;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class PortManager {
+
+ public static int startingPort = 25000;
+ public static int minPort = 25000;
+ public static int maxPort = 49000;
+
+ public static List<Integer> usedPorts = Collections
+ .synchronizedList(new ArrayList<Integer>());
+
+ public static int getNextAvialablePort() {
+ int portNo = minPort;
+ for (int i = minPort; i <= maxPort; i++) {
+ if (isOpened(i) && !usedPorts.contains(i)) {
+ portNo = i;
+ usedPorts.add(i);
+ minPort += 1;
+ if (minPort >= maxPort - 2)
+ minPort = startingPort;
+ return portNo;
+ }
+ }
+ return portNo;
+ }
+
+ private static boolean isOpened(int port) {
+ ServerSocket sock = null;
+ DatagramSocket dataSock = null;
+ try {
+ sock = new ServerSocket(port);
+ sock.setReuseAddress(true);
+ dataSock = new DatagramSocket(port);
+ dataSock.setReuseAddress(true);
+ return true;
+ }
+ catch (final IOException e) {
+ return false;
+ }
+ finally {
+ if (dataSock != null) {
+ dataSock.close();
+ }
+ if (sock != null) {
+ try {
+ sock.close();
+ }
+ catch (final IOException e) {
+
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/runtime/daemon/PortManagerThread.java b/src/runtime/daemon/PortManagerThread.java
new file mode 100644
index 0000000..1878736
--- /dev/null
+++ b/src/runtime/daemon/PortManagerThread.java
@@ -0,0 +1,114 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PortManagerThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 27, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.daemon;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class PortManagerThread extends Thread {
+ public volatile boolean isRun = true;
+
+ public PortManagerThread() {
+
+ }
+
+ private int port = getServerSocketPortFromWrapper();;
+
+ @Override
+ public void run() {
+ serverSocketInit();
+ }
+
+ private void serverSocketInit() {
+
+ try {
+
+ ServerSocket servSock = new ServerSocket(port);
+ while (isRun) {
+ Socket sock = servSock.accept();
+ PortRequesterThread thread = new PortRequesterThread(sock);
+ thread.start();
+ }
+
+ }
+ catch (Exception cce) {
+
+ System.exit(0);
+ }
+
+ }
+
+ private static int getServerSocketPortFromWrapper() {
+
+ int port = 0;
+ FileInputStream in = null;
+ DataInputStream din = null;
+ BufferedReader reader = null;
+ String line = "";
+
+ try {
+
+ String path = System.getenv("MPJ_HOME") + "/conf/wrapper.conf";
+ in = new FileInputStream(path);
+ din = new DataInputStream(in);
+ reader = new BufferedReader(new InputStreamReader(din));
+
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith("wrapper.app.parameter.3")) {
+ String trimmedLine = line.replaceAll("\\s+", "");
+ port = Integer.parseInt(trimmedLine.substring(24));
+ break;
+ }
+ }
+
+ in.close();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return port;
+
+ }
+
+}
diff --git a/src/runtime/daemon/PortRequesterThread.java b/src/runtime/daemon/PortRequesterThread.java
new file mode 100644
index 0000000..b2baabe
--- /dev/null
+++ b/src/runtime/daemon/PortRequesterThread.java
@@ -0,0 +1,88 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PortRequesterThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 27, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.daemon;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+public class PortRequesterThread extends Thread {
+ private Socket sock;
+
+ public PortRequesterThread(Socket sock) {
+ this.sock = sock;
+ }
+
+ @Override
+ public void run() {
+ processRequest();
+ }
+
+ private void processRequest() {
+ OutputStream outToServer = null;
+ try {
+ outToServer = sock.getOutputStream();
+ DataOutputStream out = new DataOutputStream(outToServer);
+ DataInputStream din = new DataInputStream(sock.getInputStream());
+ int start = din.readInt();
+ Integer rport = PortManager.getNextAvialablePort();
+ Integer wport = PortManager.getNextAvialablePort();
+ out.writeInt(rport);
+ out.writeInt(wport);
+ out.flush();
+ int end = din.readInt();
+
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ finally {
+ try {
+ if (!sock.isClosed())
+ sock.close();
+
+ }
+ catch (IOException ioEx) {
+ System.exit(1);
+ }
+ }
+ }
+
+}
diff --git a/src/runtime/daemon/ProcessArgumentsManager.java b/src/runtime/daemon/ProcessArgumentsManager.java
new file mode 100644
index 0000000..505f67c
--- /dev/null
+++ b/src/runtime/daemon/ProcessArgumentsManager.java
@@ -0,0 +1,486 @@
+package runtime.daemon;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.codec.binary.Base64;
+
+import runtime.common.IOHelper;
+import runtime.common.MPJProcessTicket;
+
+public class ProcessArgumentsManager {
+
+ ArrayList<Integer> ports = new ArrayList<Integer>();
+ String sourceFolder = "";
+ MPJProcessTicket pTicket;
+ String configFilePath = "";
+ String ticketDir = "";
+ int rankArgumentIndex;
+ int debug_argument_index;
+
+ String userDir = "";
+ String usersDir = "";
+ String sourcePath = "";
+
+ public void setSourcePath(String sourcePath) {
+ File f = new File(sourcePath);
+ String files[] = f.list();
+ this.sourcePath = sourcePath + "/" + files[0];
+ }
+
+ public String getUsersDir() {
+ return usersDir;
+ }
+
+ public void setUsersDir(String usersDir) {
+ this.usersDir = usersDir;
+ }
+
+ public String getTicketDir() {
+ return ticketDir;
+ }
+
+ public void setTicketDir(String ticketDir) {
+ this.ticketDir = ticketDir;
+ }
+
+ public String getUserDir() {
+ return userDir;
+ }
+
+ public void setUserDir(String userDir) {
+ this.userDir = userDir;
+ }
+
+ public ProcessArgumentsManager(MPJProcessTicket pTicket) {
+ this.pTicket = pTicket;
+ }
+
+ public ArrayList<Integer> getProcessesPorts() {
+ return ports;
+ }
+
+ public int getRankArgumentIndex() {
+ return rankArgumentIndex;
+ }
+
+ public void setRankArgumentIndex(int rankArgumentIndex) {
+ this.rankArgumentIndex = rankArgumentIndex;
+ }
+
+ public int getDebugArgumentIndex() {
+ return debug_argument_index;
+ }
+
+ public void setDebugArgumentIndex(int debug_argument_index) {
+ this.debug_argument_index = debug_argument_index;
+ }
+
+ public String[] GetArguments(MPJProcessTicket pTicket) {
+ if (pTicket.getDeviceName().equals("niodev")
+ || pTicket.getDeviceName().equals("mxdev")) {
+ return GetNIODeviceArguments();
+ } else if (pTicket.getDeviceName().equals("hybdev")) {
+ return GetHybridDeviceArguments();
+ }
+ return null;
+
+ }
+
+ public String[] GetNIODeviceArguments() {
+
+ WriteSourceFile();
+ WriteConfigFile();
+
+ Map<String, String> map = System.getenv();
+ String mpjHomeDir = map.get("MPJ_HOME");
+ String workingDirectory = pTicket.getWorkingDirectory();
+ if (pTicket.isZippedSource()) {
+ if (pTicket.getClassPath().endsWith(".jar")) {
+ File f = new File(pTicket.getClassPath());
+ pTicket.setClassPath(sourcePath + "/" + f.getName());
+
+ } else
+ pTicket.setClassPath(sourcePath);
+ workingDirectory = sourcePath;
+ }
+
+ boolean now = false;
+ boolean noSwitch = true;
+ for (int e = 0; e < pTicket.getJvmArgs().size(); e++) {
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("jArgs[" + e + "]="
+ + pTicket.getJvmArgs().get(e));
+ }
+
+ if (now) {
+ String cp = pTicket.getJvmArgs().remove(e);
+ cp = "." + File.pathSeparator + "" + mpjHomeDir + "/lib/loader1.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/mpj.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/log4j-1.2.11.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/wrapper.jar"
+ + File.pathSeparator + pTicket.getClassPath() + File.pathSeparator
+ + workingDirectory + File.pathSeparator + cp;
+
+ pTicket.getJvmArgs().add(e, cp);
+ now = false;
+ }
+
+ if (pTicket.getJvmArgs().get(e).equals("-cp")) {
+ now = true;
+ noSwitch = false;
+ }
+ }
+
+ if (noSwitch) {
+ pTicket.getJvmArgs().add("-cp");
+ pTicket.getJvmArgs().add(
+ "." + File.pathSeparator + "" + mpjHomeDir + "/lib/loader1.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/mpj.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/log4j-1.2.11.jar"
+ + File.pathSeparator + "" + mpjHomeDir + "/lib/wrapper.jar"
+ + File.pathSeparator + pTicket.getClassPath()
+ + File.pathSeparator + workingDirectory);
+ }
+
+ for (int e = 0; e < pTicket.getJvmArgs().size(); e++) {
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("modified: jArgs[" + e + "]="
+ + pTicket.getJvmArgs().get(e));
+ }
+ }
+
+ /* ends Here */
+ /*
+ * FIX ME BY RIZWAN HANIF : making arguments to launch MPI Processes
+ */
+ int N_ARG_COUNT = 7;
+ int increment = 1;
+
+ int nArgumentIncrement = 0;
+ if (pTicket.isProfiler())
+ nArgumentIncrement++;
+ if (pTicket.isDebug())
+ nArgumentIncrement++;
+
+ String[] arguments = new String[(N_ARG_COUNT + pTicket.getJvmArgs().size() + pTicket
+ .getAppArgs().size()) + nArgumentIncrement];
+ if (pTicket.isProfiler()) {
+ arguments[0] = "tau_java";
+ increment++;
+ } else
+ arguments[0] = "java";
+ // System.arraycopy ... can be used ..here ...
+ for (int i = 0; i < pTicket.getJvmArgs().size(); i++) {
+ arguments[i + increment] = pTicket.getJvmArgs().get(i);
+ }
+
+ int indx = pTicket.getJvmArgs().size() + increment;
+
+ if (pTicket.isDebug()) {
+ setDebugArgumentIndex(indx);
+ indx++;
+ }
+
+ arguments[indx] = "runtime.daemon.Wrapper";
+ indx++;
+ arguments[indx] = configFilePath;
+ indx++;
+ arguments[indx] = Integer.toString(pTicket.getProcessCount());
+ indx++;
+ arguments[indx] = pTicket.getDeviceName();
+ indx++;
+ arguments[indx] = "" + (-1);
+ /*
+ * FIX ME BY RIZWAN HANIF : This index value is actually the rank of each
+ * MPI Processes
+ */
+ rankArgumentIndex = indx;
+ indx++;
+ arguments[indx] = pTicket.getMainClass();
+ // System.arraycopy ... can be used ..here ...
+ for (int i = 0; i < pTicket.getAppArgs().size(); i++) {
+ arguments[i + N_ARG_COUNT + pTicket.getJvmArgs().size()
+ + nArgumentIncrement] = pTicket.getAppArgs().get(i);
+ }
+ return arguments;
+
+ }
+
+ public String[] GetHybridDeviceArguments() {
+ WriteSourceFile();
+ WriteConfigFile();
+
+ Map<String, String> map = System.getenv();
+ String mpjHomeDir = map.get("MPJ_HOME");
+ boolean now = false;
+ boolean noSwitch = true;
+ String cmdClassPath = " ";
+ String workingDirectory = pTicket.getWorkingDirectory();
+ if (pTicket.isZippedSource()) {
+ if (pTicket.getClassPath().endsWith(".jar")) {
+ File f = new File(pTicket.getClassPath());
+ pTicket.setClassPath(sourcePath + "/" + f.getName());
+
+ } else
+ pTicket.setClassPath(sourcePath);
+ workingDirectory = sourcePath;
+ }
+ String[] jArgs = pTicket.getJvmArgs().toArray(new String[0]);
+ for (int e = 0; e < jArgs.length; e++) {
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("jArgs[" + e + "]=" + jArgs[e]);
+ }
+
+ if (now) {
+ cmdClassPath = pTicket.getJvmArgs().remove(e);
+
+ if (cmdClassPath.matches("(?i).*mpj.jar.*")) {
+ // System.out.println("before <"+cmdClassPath+">");
+ // System.out.println("mpj.jar is present ...") ;
+ cmdClassPath = cmdClassPath.replaceAll("mpj\\.jar", "mpi.jar");
+ // cmdClassPath.replaceAll(Pattern.quote("mpj.jar"),
+ // Matcher.quoteReplacement("mpi.jar")) ;
+ // System.out.println("after <"+cmdClassPath+">");
+ // System.exit(0) ;
+ }
+ // adding hybdev.jar and niodev.jar
+ String cp = mpjHomeDir + "/lib/hybdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/xdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/smpdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/niodev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/mpjbuf.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/loader2.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/starter.jar" + File.pathSeparator
+ // + ""+ pTicket.getClassPath() +File.pathSeparator
+ + "" + mpjHomeDir + "/lib/mpiExp.jar";
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("cp = " + cp);
+ }
+
+ pTicket.getJvmArgs().add(e, cp);
+ now = false;
+ }
+
+ if (jArgs[e].equals("-cp")) {
+ now = true;
+ noSwitch = false;
+ }
+
+ }
+
+ if (noSwitch) {
+ pTicket.getJvmArgs().add("-cp");
+
+ // adding hybdev.jar and niodev.jar
+ String cp = mpjHomeDir + "/lib/hybdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/xdev.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/smpdev.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/niodev.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/mpjbuf.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/loader2.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/starter.jar" + File.pathSeparator
+ // + "" + pTicket.getWorkingDirectory() +File.pathSeparator
+ // + ""+ pTicket.getClassPath() +File.pathSeparator
+ + "" + mpjHomeDir + "/lib/mpiExp.jar";
+
+ pTicket.getJvmArgs().add(cp);
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("cp = " + cp);
+ }
+ }
+
+ jArgs = pTicket.getJvmArgs().toArray(new String[0]);
+
+ for (int e = 0; e < jArgs.length; e++) {
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("modified: jArgs[" + e + "]=" + jArgs[e]);
+ }
+ }
+
+ int CMD_WORDS = 8;
+ int HYB_ARGS = 5;
+ int increment = 1;
+
+ String[] aArgs = pTicket.getAppArgs().toArray(new String[0]);
+ int nArgumentIncrement = 0;
+ if (pTicket.isProfiler())
+ nArgumentIncrement++;
+ if (pTicket.isDebug())
+ nArgumentIncrement++;
+
+ String[] arguments = new String[(CMD_WORDS + jArgs.length + HYB_ARGS + aArgs.length)
+ + nArgumentIncrement];
+ if (pTicket.isProfiler()) {
+ arguments[0] = "tau_java";
+ arguments[1] = "-tau:node=" + Integer.toString(pTicket.getStartingRank());
+ increment++;
+ } else
+ arguments[0] = "java";
+
+ for (int i = 0; i < jArgs.length; i++) {
+ arguments[i + increment] = jArgs[i];
+ }
+
+ int indx = jArgs.length + increment;
+
+ if (pTicket.isDebug()) {
+ setDebugArgumentIndex(indx);
+ indx++;
+ }
+
+ arguments[indx] = "runtime.daemon.HybridStarter";
+ indx++;
+ arguments[indx] = workingDirectory;
+ indx++;
+ int threadPerHost = getThreadsPerHost(pTicket.getTotalProcessCount(),
+ pTicket.getNetworkProcessCount(), pTicket.getStartingRank());
+ arguments[indx] = Integer.toString(threadPerHost);
+ indx++;
+ arguments[indx] = pTicket.getDeviceName();
+ indx++;
+ arguments[indx] = "useLocalLoader";
+ indx++;
+ arguments[indx] = cmdClassPath;
+ indx++;
+
+ if (pTicket.getClassPath().endsWith(".jar"))
+ arguments[indx] = pTicket.getClassPath();
+ else if (pTicket.getMainClass() != null)
+ arguments[indx] = pTicket.getMainClass();
+ else
+ arguments[indx] = pTicket.getClassPath();
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("HybridDaemon: Value of Indx: " + indx
+ + " Count of args till now: "
+ + (CMD_WORDS + jArgs.length + nArgumentIncrement));
+ }
+ indx = CMD_WORDS + jArgs.length + nArgumentIncrement;
+ // args for hybrid device
+ arguments[indx + 0] = Integer.toString(pTicket.getTotalProcessCount());
+ arguments[indx + 1] = Integer.toString(pTicket.getNetworkProcessCount());
+ arguments[indx + 2] = Integer.toString(pTicket.getStartingRank());
+ arguments[indx + 3] = configFilePath;
+ arguments[indx + 4] = "niodev";
+
+ for (int i = 0; i < aArgs.length; i++) {
+ arguments[i + CMD_WORDS + jArgs.length + HYB_ARGS + nArgumentIncrement] = aArgs[i];
+ }
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger
+ .debug("HybridDaemon: Command for process-builder object index: value ");
+ }
+
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("HybridDaemon: creating process-builder object ");
+ }
+
+ return arguments;
+ }
+
+ public ArrayList<Integer> WriteConfigFile() {
+ {
+ String CONF_FILE_NAME = "mpjdev.conf";
+ configFilePath = ticketDir + File.separator + CONF_FILE_NAME;
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("configFilePath");
+ }
+
+ File configFile = new File(configFilePath);
+ try {
+ configFile.createNewFile();
+ }
+ catch (IOException e1) {
+ System.out.println("Unable to create config file ");
+ System.out.println(e1.getMessage() + "\r\n" + e1.getStackTrace());
+ MPJDaemon.logger.debug(e1.getMessage());
+ }
+
+ configFilePath = ticketDir + File.separator + CONF_FILE_NAME;
+ if (MPJDaemon.DEBUG && MPJDaemon.logger.isDebugEnabled()) {
+ MPJDaemon.logger.debug("Config file created :");
+ }
+
+ StringTokenizer conf_file_tokenizer = new StringTokenizer(
+ pTicket.getConfFileContents(), ";");
+ PrintStream cout;
+ FileOutputStream cfos = null;
+
+ try {
+ cfos = new FileOutputStream(configFile);
+ }
+ catch (FileNotFoundException e1) {
+ e1.printStackTrace();
+ }
+ cout = new PrintStream(cfos);
+
+ while (conf_file_tokenizer.hasMoreTokens()) {
+ String token = conf_file_tokenizer.nextToken();
+ if (token.contains("@") && !token.startsWith("#")) {
+ String[] tokens = token.split("@");
+ ports.add(Integer.parseInt(tokens[1]));
+ if (pTicket.getDeviceName() != "mxdev")
+ ports.add(Integer.parseInt(tokens[2]));
+ }
+ cout.println(token);
+ }
+
+ cout.close();
+ try {
+ cfos.close();
+ }
+ catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ return ports;
+
+ }
+ }
+
+ private void WriteSourceFile() {
+ String USERS = "mpj_users";
+ String SRC_DIR = "src";
+ String SRC_ZIP = "src.zip";
+ Map<String, String> map = System.getenv();
+ String mpjHomeDir = map.get("MPJ_HOME");
+ usersDir = System.getProperty("user.home") + File.separator + "." + USERS;
+ IOHelper.CreateDirectory(usersDir);
+ userDir = usersDir + File.separator + pTicket.getUserID();
+ IOHelper.CreateDirectory(userDir);
+ ticketDir = userDir + File.separator + pTicket.getTicketID().toString();
+ IOHelper.CreateDirectory(ticketDir);
+
+ sourceFolder = ticketDir + File.separator + SRC_DIR;
+ String sourceZip = ticketDir + File.separator + SRC_ZIP;
+
+ if (pTicket.isZippedSource()) {
+ byte[] contents = Base64.decodeBase64(pTicket.getSourceCode());
+ IOHelper.writeFile(sourceZip, contents);
+ IOHelper.ExtractZip(sourceZip, sourceFolder);
+ setSourcePath(sourceFolder);
+ }
+
+ }
+
+ public int getThreadsPerHost(int pro, int boxes, int netRank) {
+ int proPerHost = pro / boxes;
+ int rem = pro % boxes;
+ if ((netRank + 1) <= rem) {
+ proPerHost++;
+ }
+ return proPerHost;
+ }
+
+}
diff --git a/src/runtime/daemon/ProcessLauncher.java b/src/runtime/daemon/ProcessLauncher.java
new file mode 100644
index 0000000..0f69494
--- /dev/null
+++ b/src/runtime/daemon/ProcessLauncher.java
@@ -0,0 +1,268 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProcessLauncher.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 10, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.daemon;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+
+import runtime.common.MPJProcessTicket;
+
+public class ProcessLauncher extends Thread {
+
+ boolean DEBUG = true;
+ private Process p[] = null;
+ private Socket sockserver = null;
+ private Logger logger = MPJDaemon.logger;
+ int JvmProcessCount = 0;
+ ProcessArgumentsManager argManager;
+
+ public ProcessLauncher(Socket sockServer) {
+
+ this.sockserver = sockServer;
+ }
+
+ @Override
+ public void run() {
+ ExecuteJob();
+ }
+
+ private void ExecuteJob() {
+
+ System.out.println("Job Started");
+ MPJProcessTicket pTicket = new MPJProcessTicket();
+
+ try {
+
+ String ticketString = getStringFromInputStream(sockserver
+ .getInputStream());
+
+ if (ticketString != "")
+ pTicket.FromXML(ticketString);
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug(pTicket.ToXML(false).toXmlString());
+ }
+
+ }
+ catch (IOException e3) {
+ e3.printStackTrace();
+ return;
+ }
+
+ if (pTicket.getDeviceName().equals("niodev")
+ || pTicket.getDeviceName().equals("mxdev")) {
+ JvmProcessCount = pTicket.getProcessCount();
+ } else if (pTicket.getDeviceName().equals("hybdev")) {
+ JvmProcessCount = 1;
+ }
+
+ OutputHandler[] outputThreads = new OutputHandler[JvmProcessCount];
+ p = new Process[JvmProcessCount];
+ argManager = new ProcessArgumentsManager(pTicket);
+ String[] arguments = argManager.GetArguments(pTicket);
+
+ for (int j = 0; j < JvmProcessCount; j++) {
+ if (pTicket.getDeviceName().equals("niodev")
+ || pTicket.getDeviceName().equals("mxdev")) {
+ String rank = new String("" + (pTicket.getStartingRank() + j));
+ arguments[argManager.getRankArgumentIndex()] = rank;
+ if (pTicket.isProfiler())
+ arguments[1] = "-tau:node=" + rank;
+ }
+ if (pTicket.isDebug()
+ && (pTicket.getDeviceName().equals("niodev") || pTicket
+ .getDeviceName().equals("mxdev"))) {
+ arguments[argManager.getDebugArgumentIndex()] = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
+ + (pTicket.getDebugPort() + j * 2);
+ }
+
+ else if (pTicket.isDebug() && pTicket.getDeviceName().equals("hybdev")) {
+ arguments[argManager.getDebugArgumentIndex()] = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
+ + (pTicket.getDebugPort());
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ for (int i = 0; i < arguments.length; i++) {
+ logger.debug("arguments[" + i + "] = " + arguments[i]);
+ }
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(arguments);
+ String currentDir = System.getProperty("user.dir");
+ pb.directory(new File(currentDir));
+ pb.redirectErrorStream(true);
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("starting the process ");
+ }
+ try {
+ p[j] = pb.start();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ /*
+ * Step 4: Start a new thread to handle output from this particular JVM.
+ * FIXME: Now this seems like a good amount of overhead. If we start 4
+ * JVMs on a quad-core CPU, we also start 4 additional threads to handle
+ * I/O. Is it possible to get rid of this overhead?
+ */
+ outputThreads[j] = new OutputHandler(p[j], sockserver);
+ outputThreads[j].start();
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("started the process ");
+ }
+ } // end for loop.
+
+ // Wait for the I/O threads to finish. They finish when
+ // their corresponding JVMs finish.
+ for (int j = 0; j < JvmProcessCount; j++) {
+ try {
+ outputThreads[j].join();
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Stopping the output");
+ }
+
+ if (sockserver != null && !sockserver.isClosed()
+ && !sockserver.isOutputShutdown()) {
+ OutputStream outToServer = null;
+ try {
+ outToServer = sockserver.getOutputStream();
+
+ DataOutputStream out = new DataOutputStream(outToServer);
+ out.write("EXIT".getBytes(), 0, "EXIT".getBytes().length);
+ System.out.println("Job finished");
+ if (!DEBUG || !logger.isDebugEnabled()) {
+ FileUtils.deleteDirectory(new File(argManager.getUsersDir()));
+ }
+ }
+ catch (IOException e1) {
+ e1.printStackTrace();
+ }
+ finally {
+ if (!sockserver.isClosed())
+ try {
+ outToServer.close();
+ sockserver.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ try {
+ killProcesses();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ MPJDaemon.servSockets.remove(sockserver);
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("\n\n ** .. execution ends .. ** \n\n");
+ }
+
+ }
+
+ public void killProcesses() {
+ // Its important to kill all JVMs that we started ...
+ synchronized (p) {
+ for (int i = 0; i < JvmProcessCount; i++)
+ p[i].destroy();
+
+ }
+ for (Integer port : argManager.getProcessesPorts()) {
+ PortManager.usedPorts.remove(port);
+ }
+ try {
+ if (!sockserver.isClosed())
+ sockserver.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ try {
+ if (!DEBUG || !logger.isDebugEnabled()) {
+ FileUtils.deleteDirectory(new File(argManager.getUsersDir()));
+ }
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private String getStringFromInputStream(InputStream is) {
+
+ DataInputStream in = new DataInputStream(is);
+ int len = 0;
+ try {
+ len = in.readInt();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Ticket length " + len);
+ }
+ byte[] xml = new byte[len];
+ try {
+
+ in.readFully(xml, 0, len);
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ return new String(xml);
+ }
+}
diff --git a/src/runtime/daemon/Wrapper.java b/src/runtime/daemon/Wrapper.java
new file mode 100644
index 0000000..0847b2f
--- /dev/null
+++ b/src/runtime/daemon/Wrapper.java
@@ -0,0 +1,142 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2010)
+ 3. Bryan Carpenter (2005 - 2010)
+ 4. Mark Baker (2005 - 2010)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Wrapper.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.19 $
+ * Updated : $Date: Wed Mar 31 15:22:37 PKT 2010$
+ */
+
+package runtime.daemon;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.lang.reflect.*;
+
+public class Wrapper extends Thread {
+
+ String configFileName = null;
+ int processes = 0;
+ String className = null;
+ Class c = null;
+ String deviceName = null;
+ String rank = null;
+ String[] nargs = null;
+ String hostName = null;
+ String args[] = null;
+
+ public Wrapper(ThreadGroup group, String name) {
+ super(group, name);
+ }
+
+ /**
+ * Executes MPJ program in a new JVM. This method is invoked in main method of
+ * this class, which is started by MPJDaemon. This method can start multiple
+ * threads in a JVM. This will also parse configuration file.
+ *
+ * @param args
+ * Arguments to this method. args[0] is configFileName 'String',
+ * args[1] is number of processes, args[2] is deviceName, args[3] is
+ * rank, args[4] is className
+ */
+ public void execute(String args[]) throws Exception {
+
+ InetAddress localaddr = InetAddress.getLocalHost();
+ hostName = localaddr.getHostName();
+
+ configFileName = args[0];
+ processes = (new Integer(args[1])).intValue();
+ deviceName = args[2];
+ rank = args[3];
+ className = args[4];
+
+ nargs = new String[(args.length - 5)];
+ System.arraycopy(args, 5, nargs, 0, nargs.length);
+
+ c = Class.forName(className);
+
+ try {
+ System.out.println("Starting process <" + rank + "> on <" + hostName
+ + ">");
+
+ String arvs[] = new String[nargs.length + 3];
+
+ arvs[0] = rank;
+ arvs[1] = configFileName;
+ arvs[2] = deviceName;
+
+ for (int i = 0; i < nargs.length; i++) {
+ arvs[i + 3] = nargs[i];
+ }
+
+ Method m = c.getMethod("main", new Class[] { arvs.getClass() });
+ m.setAccessible(true);
+ int mods = m.getModifiers();
+ if (m.getReturnType() != void.class || !Modifier.isStatic(mods)
+ || !Modifier.isPublic(mods)) {
+ throw new NoSuchMethodException("main");
+ }
+
+ m.invoke(null, new Object[] { arvs });
+
+ System.out.println("Stopping process <" + rank + "> on <" + hostName
+ + ">");
+ }
+ catch (Exception ioe) {
+ System.out
+ .println("multi-threaded starter: exception" + ioe.getMessage());
+ ioe.printStackTrace();
+ }
+
+ }
+
+ public void run() {
+ try {
+ execute(args);
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ // Wrapper wrap = new Wrapper();
+ // wrap.execute(args);
+
+ ThreadGroup group = new ThreadGroup("MPI" + args[3]);
+ Wrapper wrap = new Wrapper(group, args[3]);
+ wrap.args = args;
+ // Thread runner = new Thread("Main",wrap,group);
+ wrap.start();
+ wrap.join();
+ }
+}
diff --git a/src/runtime/daemonmanager/BootThread.java b/src/runtime/daemonmanager/BootThread.java
new file mode 100644
index 0000000..94a74ed
--- /dev/null
+++ b/src/runtime/daemonmanager/BootThread.java
@@ -0,0 +1,123 @@
+package runtime.daemonmanager;
+
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PMThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+import runtime.common.MPJUtil;
+
+public class BootThread extends DMThread {
+ private String host = "localhost";
+ private String port = "8888";
+ ProcessBuilder pb = null;
+
+ public BootThread(String machineName, String daemonPort) {
+ host = machineName;
+ port = daemonPort;
+
+ }
+
+ public void run() {
+ try {
+ bootNetWorkMachines();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void bootNetWorkMachines() throws IOException {
+
+ if (validExecutionParams()) {
+ try {
+ String[] command = { "ssh", host, "nohup", "java", "-cp",
+ MPJUtil.getJarPath("daemon") + ":.", "runtime.daemon.MPJDaemon",
+ port,
+
+ };
+ ArrayList<String> consoleMessages = DaemonUtil.runProcess(command,
+ false);
+ String pid = DaemonUtil.getMPJProcessID(host);
+ if (!pid.equals("") && Integer.parseInt(pid) > -1
+ && Integer.parseInt(pid) < 30000) {
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_STARTED + pid));
+ } else {
+ for (String message : consoleMessages)
+ System.out.println(message);
+ }
+
+ }
+ catch (Exception ex) {
+ System.out.print(ex.getMessage());
+ }
+ }
+
+ }
+
+ private boolean validExecutionParams() {
+
+ String pid = DaemonUtil.getMPJProcessID(host, pb);
+ if (!pid.equals("")) {
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_ALREADY_RUNNING + pid));
+ return false;
+ }
+ InetAddress address = null;
+ try {
+
+ address = InetAddress.getByName(host);
+ }
+ catch (UnknownHostException e) {
+
+ e.printStackTrace();
+ System.out.println(e.getMessage());
+ return false;
+ }
+ if (MPJUtil.IsBusy(address, Integer.parseInt(port))) {
+ System.out.println(MPJUtil.FormatMessage(host, DMMessages.BUSY_PORT));
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/runtime/daemonmanager/CLOptions.java b/src/runtime/daemonmanager/CLOptions.java
new file mode 100644
index 0000000..b531568
--- /dev/null
+++ b/src/runtime/daemonmanager/CLOptions.java
@@ -0,0 +1,270 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : CLOptions.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+
+import runtime.common.MPJUtil;
+
+public class CLOptions {
+
+ private ArrayList<String> machineList;
+ private int threadCount;
+ private String cmdType;
+ private String userCmd;
+ private String machineFilePath;
+ private String port;
+
+ public CLOptions(ArrayList<String> machineList, int threadCount,
+ boolean bThreading, String cmdType, String userCmd, String port) {
+ super();
+ this.machineList = machineList;
+ this.threadCount = threadCount;
+ this.cmdType = cmdType;
+ this.userCmd = userCmd;
+ this.port = port;
+ }
+
+ public String getPort() {
+ return port;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public CLOptions() {
+ super();
+ this.machineList = new ArrayList<String>();
+ this.threadCount = 20;
+ this.cmdType = DMConstants.STATUS;
+ this.userCmd = "";
+ this.machineFilePath = "";
+ this.port = MPJUtil.getConfigValue(DMConstants.CONF_PORT_KEY); // PMConstants.DAEMON_PORT_NUMBER;
+ this.machineFilePath = MPJUtil.getMachineFilePath();
+ }
+
+ public ArrayList<String> getMachineList() {
+ return machineList;
+ }
+
+ public void setMachineList(ArrayList<String> machineList) {
+ this.machineList = machineList;
+ }
+
+ public int getThreadCount() {
+ return threadCount;
+ }
+
+ public void setThreadCount(int nThreads) {
+ this.threadCount = nThreads;
+ }
+
+ public String getCmdType() {
+ return cmdType;
+ }
+
+ public void setCmdType(String cmdType) {
+ this.cmdType = cmdType;
+ }
+
+ public String getUserCmd() {
+ return userCmd;
+ }
+
+ public void setUserCmd(String userCmd) {
+ this.userCmd = userCmd;
+ }
+
+ public String getMachineFilePath() {
+ return machineFilePath;
+ }
+
+ public void setMachineFilePath(String machineFilePath) {
+ this.machineFilePath = machineFilePath;
+ }
+
+ public void PrintOptions() {
+ System.out.println("Command Type: " + this.cmdType);
+ System.out.println("Machine File Path: " + this.machineFilePath);
+ for (String hostname : this.machineList)
+ System.out.println("Host Name: " + hostname);
+ System.out.println("No of Threads: " + this.threadCount);
+
+ }
+
+ public void PrintHelp() {
+ System.out.println(FormatCMDoptionMessages("", DMConstants.HELP,
+ DMMessages.CMD_OPT_HELP));
+ System.out.println(FormatCMDoptionMessages(DMConstants.BOOT_OPT,
+ DMConstants.BOOT, DMMessages.CMD_OPT_BOOT));
+ System.out.println(FormatCMDoptionMessages(DMConstants.HALT_OPT,
+ DMConstants.HALT, DMMessages.CMD_OPT_HALT));
+ System.out.println(FormatCMDoptionMessages(DMConstants.CLEAN_OPT,
+ DMConstants.CLEAN, DMMessages.CMD_OPT_CLEAN));
+ System.out.println(FormatCMDoptionMessages(DMConstants.STATUS_OPT,
+ DMConstants.STATUS, DMMessages.CMD_OPT_STATUS));
+ System.out.println(FormatCMDoptionMessages(DMConstants.INFO_OPT,
+ DMConstants.INFO, DMMessages.CMD_OPT_INFO));
+
+ System.out.println(FormatCMDoptionMessages(DMConstants.MACHINE_FILE_OPT,
+ DMConstants.MACHINE_FILE, DMMessages.CMD_OPT_MACHINE_FILE));
+ System.out.println(FormatCMDoptionMessages(DMConstants.HOSTS_OPT,
+ DMConstants.HOSTS, DMMessages.CMD_OPT_HOSTS));
+ System.out.println(FormatCMDoptionMessages(DMConstants.THREAD_COUNT_OPT,
+ DMConstants.THREAD_COUNT, DMMessages.CMD_OPT_THREAD_COUNT));
+ System.out.println(FormatCMDoptionMessages(DMConstants.THREADED_OPT,
+ DMConstants.THREADED, DMMessages.CMD_OPT_THREADED));
+ System.out.println(FormatCMDoptionMessages(DMConstants.PORT_OPT,
+ DMConstants.PORT, DMMessages.CMD_OPT_PORT));
+ System.out.println("");
+
+ }
+
+ public String FormatCMDoptionMessages(String shortOption, String longOption,
+ String description) {
+ String message = "";
+
+ String option = "- ";
+ if (shortOption == "")
+ option = option + longOption + ": ";
+ else
+ option += shortOption + "|" + longOption + ": ";
+
+ for (int i = option.length(); i <= 15; i++)
+ option += " ";
+ message = option + description;
+ return message;
+ }
+
+ @SuppressWarnings("static-access")
+ public void parseCommandLineArgs(String[] args) {
+
+ CommandLineParser parser = new PosixParser();
+
+ Options options = new Options();
+ options.addOption(new Option(DMConstants.HELP_OPT, DMConstants.HELP, false,
+ DMMessages.CMD_OPT_HELP));
+ options.addOption(new Option(DMConstants.BOOT_OPT, DMConstants.BOOT, false,
+ DMMessages.CMD_OPT_BOOT));
+ options.addOption(new Option(DMConstants.HALT_OPT, DMConstants.HALT, false,
+ DMMessages.CMD_OPT_HALT));
+ options.addOption(new Option(DMConstants.CLEAN_OPT, DMConstants.CLEAN,
+ false, DMMessages.CMD_OPT_CLEAN));
+ options.addOption(new Option(DMConstants.STATUS_OPT, DMConstants.STATUS,
+ false, DMMessages.CMD_OPT_STATUS));
+ options.addOption(new Option(DMConstants.INFO_OPT, DMConstants.INFO, false,
+ DMMessages.CMD_OPT_INFO));
+ options.addOption(new Option(DMConstants.MACHINE_FILE_OPT,
+ DMConstants.MACHINE_FILE, true, DMMessages.CMD_OPT_MACHINE_FILE));
+ options.addOption(OptionBuilder.withLongOpt(DMConstants.HOSTS).hasArgs()
+ .withDescription(DMMessages.CMD_OPT_HOSTS).withValueSeparator(' ')
+ .create(DMConstants.HOSTS_OPT));
+ options.addOption(new Option(DMConstants.THREAD_COUNT_OPT,
+ DMConstants.THREAD_COUNT, true, DMMessages.CMD_OPT_THREAD_COUNT));
+ options.addOption(new Option(DMConstants.PORT_OPT, DMConstants.PORT, true,
+ DMMessages.CMD_OPT_PORT));
+ options.addOption(new Option(DMConstants.WIN_BOOT_OPT,
+ DMConstants.WIN_BOOT, false, DMMessages.CMD_OPT_BOOT));
+ options.addOption(new Option(DMConstants.WIN_HALT_OPT,
+ DMConstants.WIN_HALT, false, DMMessages.CMD_OPT_HALT));
+
+ try {
+ CommandLine line = parser.parse(options, args);
+ if (line.hasOption(DMConstants.HELP))
+ this.setCmdType(DMConstants.HELP);
+ else if (line.hasOption(DMConstants.BOOT))
+ this.setCmdType(DMConstants.BOOT);
+ else if (line.hasOption(DMConstants.HALT))
+ this.setCmdType(DMConstants.HALT);
+ else if (line.hasOption(DMConstants.STATUS))
+ this.setCmdType(DMConstants.STATUS);
+ else if (line.hasOption(DMConstants.INFO))
+ this.setCmdType(DMConstants.INFO);
+ else if (line.hasOption(DMConstants.CLEAN))
+ this.setCmdType(DMConstants.CLEAN);
+ else if (line.hasOption(DMConstants.WIN_BOOT))
+ this.setCmdType(DMConstants.WIN_BOOT);
+ else if (line.hasOption(DMConstants.WIN_HALT))
+ this.setCmdType(DMConstants.WIN_HALT);
+
+ if (line.hasOption(DMConstants.HOSTS)) {
+ String[] hosts = line.getOptionValues(DMConstants.HOSTS);
+ for (String host : hosts) {
+ this.getMachineList().add(host);
+ this.setThreadCount(this.getMachineList().size());
+ }
+ } else if (line.hasOption(DMConstants.MACHINE_FILE)) {
+ String machineFilePath = line.getOptionValue(DMConstants.MACHINE_FILE);
+ this.setMachineFilePath(machineFilePath);
+ int nThreads = MPJUtil.readMachineFile(machineFilePath).size();
+ this.setThreadCount(nThreads);
+ }
+
+ if (line.hasOption(DMConstants.THREAD_COUNT)) {
+ int nThreads = Integer.parseInt(line
+ .getOptionValue(DMConstants.THREAD_COUNT));
+ this.setThreadCount(nThreads);
+ }
+
+ if (line.hasOption(DMConstants.PORT)) {
+ Integer port = Integer.parseInt(line.getOptionValue(DMConstants.PORT));
+ this.setPort(port.toString());
+ }
+
+ }
+ catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /*
+ * public static void main(String[] args) { CLOptions options = new
+ * CLOptions(); options.parseCommandLineArgs(args); options.PrintOptions(); }
+ */
+
+}
diff --git a/src/runtime/daemonmanager/CleanUpThread.java b/src/runtime/daemonmanager/CleanUpThread.java
new file mode 100644
index 0000000..8bcbd07
--- /dev/null
+++ b/src/runtime/daemonmanager/CleanUpThread.java
@@ -0,0 +1,69 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : CleanUpThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+
+import runtime.common.MPJUtil;
+
+public class CleanUpThread extends DMThread {
+
+ private String host = "localhost";
+
+ public CleanUpThread(String machineName) {
+ host = machineName;
+ }
+
+ public void run() {
+ cleanUpAllJavaProcesses();
+ }
+
+ public void cleanUpAllJavaProcesses() {
+
+ String[] command = { "ssh", host, "pkill", "-9", "java", };
+ ArrayList<String> consoleMessages = DaemonUtil.runProcess(command);
+ for (String message : consoleMessages) {
+ if (message.indexOf(DMMessages.UNKNOWN_HOST) > 0) {
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.HOST_INACESSABLE));
+ return;
+ }
+ }
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.JAVA_PROCESS_KILLED));
+ }
+}
diff --git a/src/runtime/daemonmanager/DMConstants.java b/src/runtime/daemonmanager/DMConstants.java
new file mode 100644
index 0000000..1bf61c5
--- /dev/null
+++ b/src/runtime/daemonmanager/DMConstants.java
@@ -0,0 +1,80 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PMConstants.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+public class DMConstants {
+ public static String BOOT = "boot";
+ public static String WIN_BOOT = "winboot";
+ public static String HALT = "halt";
+ public static String WIN_HALT = "winhalt";
+ public static String CLEAN = "clean";
+ public static String STATUS = "status";
+ public static String INFO = "info";
+ public static String CONF = "conf";
+ public static String LIB = "lib";
+ public static String LOGS = "logs";
+ public static String WRAPPER_LOG = "wrapper.log";
+ public static String WRAPPER_CONF = "wrapper.conf";
+ public static String EXT_JAR = ".jar";
+ public static String MACHINES = "machines";
+ public static String MPJDAEMON = "MPJDaemon";
+ public static String GREP_JAVA = "ps aux|grep java";
+
+ public static String BOOT_OPT = "b";
+ public static String WIN_BOOT_OPT = "wb";
+ public static String PORT_OPT = "p";
+ public static String HALT_OPT = "h";
+ public static String WIN_HALT_OPT = "wh";
+ public static String CLEAN_OPT = "c";
+ public static String INFO_OPT = "i";
+ public static String STATUS_OPT = "s";
+ public static String MACHINE_FILE_OPT = "m";
+ public static String HOSTS_OPT = "ht";
+ public static String HELP_OPT = "help";
+
+ public static String THREAD_COUNT_OPT = "nt";
+ public static String THREADED_OPT = "th";
+ public static String MACHINE_FILE = "machinesfile";
+ public static String THREAD_COUNT = "nthraeds";
+ public static String THREADED = "threaded";
+ public static String HOSTS = "hosts";
+ public static String PORT = "port";
+ public static String HELP = "help";
+ public static String DAEMON_PORT_NUMBER = "10000";
+ public static String CONF_PORT_KEY = "wrapper.app.parameter.2";
+}
diff --git a/src/runtime/daemonmanager/DMMessages.java b/src/runtime/daemonmanager/DMMessages.java
new file mode 100644
index 0000000..b79fa20
--- /dev/null
+++ b/src/runtime/daemonmanager/DMMessages.java
@@ -0,0 +1,70 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PMMessages.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import runtime.common.MPJUtil;
+
+public class DMMessages {
+ public static String MPJ_HOME_DIR_NOT_AVIABLBE = "MPJ_Home directoy is not avialable";
+ public static String UNKNOWN_HOST = "Name or service not known";
+ public static String INVALID_PORT = "Invalid port specified in wrapper.app.parameter.2 property of wrapper.config file ";
+ public static String BUSY_PORT = "Port is not avialable, Set a different port by modifying the wrapper.app.parameter.2 property in the "
+ + MPJUtil.getWrapperConfPath();
+ public static String MPJDAEMON_ALREADY_RUNNING = "MPJ daemon already running with process id: ";
+ public static String MACHINE_FILE_NOT_SPECIFED = "Machine file is not specified";
+ public static String MPJDAEMON_STARTED = "MPJ Deamon started successfully with process id: ";
+ public static String MPJDAEMON_NOT_AVIALBLE = "MPJ Deamon is not running ";
+ public static String MPJDAEMON_AVIALBLE = "MPJ Deamon is running with process id: ";
+ public static String MPJDAEMON_STOPPED = "MPJ Deamon stopped ";
+ public static String HOST_INACESSABLE = " is not accessable";
+ public static String JAVA_PROCESS_KILLED = " Killed all java processes";
+ public static String NO_JAVA_PROCESS_RUNNING = " No java process is running";
+
+ public static String CMD_OPT_BOOT = "Start MPJ Express daemons on given machine(s)";
+ public static String CMD_OPT_HALT = "Stop MPJ Express daemons on given machine(s)";
+ public static String CMD_OPT_CLEAN = "Clean all java process on given machine(s)";
+ public static String CMD_OPT_STATUS = "Get status of MPJ Express daemons on given machine(s) ";
+ public static String CMD_OPT_INFO = "Get all java processes on given machine(s)";
+
+ public static String CMD_OPT_MACHINE_FILE = "Machine File e.g. <machines>";
+ public static String CMD_OPT_THREAD_COUNT = "Number of threads";
+ public static String CMD_OPT_THREADED = "<true|false> use multithreading";
+ public static String CMD_OPT_HOSTS = "Host name seperated by space <localhost1 localhost2 ... >";
+ public static String CMD_OPT_PORT = "Port no for MPJ Express Deamon listerner";
+ public static String CMD_OPT_HELP = "Help for process manager command line option";
+
+}
diff --git a/src/runtime/daemonmanager/DMThread.java b/src/runtime/daemonmanager/DMThread.java
new file mode 100644
index 0000000..f7f26b0
--- /dev/null
+++ b/src/runtime/daemonmanager/DMThread.java
@@ -0,0 +1,45 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PMThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+public class DMThread extends Thread {
+
+ public DMThread() {
+
+ }
+}
diff --git a/src/runtime/daemonmanager/DMThreadUtil.java b/src/runtime/daemonmanager/DMThreadUtil.java
new file mode 100644
index 0000000..0fc0182
--- /dev/null
+++ b/src/runtime/daemonmanager/DMThreadUtil.java
@@ -0,0 +1,103 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : PMThreadUtil.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import runtime.common.MPJUtil;
+import runtime.daemonmanager.CLOptions;
+import runtime.daemonmanager.DMThread;
+
+public class DMThreadUtil {
+ public static ExecutorService getThreadExecutor(int nThreads) {
+ return Executors.newFixedThreadPool(nThreads);
+ }
+
+ public static void ExecuteThreads(ArrayList<Thread> threads, int nThreads) {
+
+ ExecutorService tpes = getThreadExecutor(nThreads);
+ for (Thread thread : threads) {
+ tpes.execute(thread);
+ }
+ tpes.shutdown();
+ try {
+
+ tpes.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+
+ }
+ catch (InterruptedException e) {
+ // e.printStackTrace();
+ }
+
+ }
+
+ public static void ExecuteCommand(CLOptions options) {
+ String type = options.getCmdType();
+ ArrayList<Thread> threads = new ArrayList<Thread>();
+ ArrayList<String> machinesList = new ArrayList<String>();
+ if (options.getMachineList().size() > 0)
+ machinesList = options.getMachineList();
+ else
+ machinesList = MPJUtil.readMachineFile(options.getMachineFilePath());
+ if (machinesList != null && machinesList.size() > 0) {
+ for (String host : machinesList) {
+ DMThread thread = null;
+ if (type.equals(DMConstants.BOOT)) {
+ thread = new BootThread(host, options.getPort());
+ } else if (type.equals(DMConstants.HALT)) {
+ thread = new HaltThread(host);
+ } else if (type.equals(DMConstants.CLEAN)) {
+ thread = new CleanUpThread(host);
+ } else if (type.equals(DMConstants.STATUS)) {
+ thread = new StatusThread(host);
+ } else if (type.equals(DMConstants.INFO)) {
+ thread = new ProcessInfoThread(host);
+ }
+ if (thread != null) {
+ threads.add(thread);
+ }
+
+ }
+ ExecuteThreads(threads, options.getThreadCount());
+ }
+ }
+
+}
diff --git a/src/runtime/daemonmanager/DaemonUtil.java b/src/runtime/daemonmanager/DaemonUtil.java
new file mode 100644
index 0000000..2c30747
--- /dev/null
+++ b/src/runtime/daemonmanager/DaemonUtil.java
@@ -0,0 +1,126 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : ProcessUtil.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+public class DaemonUtil {
+ public static ArrayList<String> runProcess(String[] command,
+ boolean waitOutput) {
+ ArrayList<String> consoleMessages = new ArrayList<String>();
+ try {
+ ProcessBuilder pb = new ProcessBuilder(command);
+ pb.redirectErrorStream(true);
+ Process process = pb.start();
+ if (waitOutput) {
+
+ InputStreamReader isr = new InputStreamReader(process.getInputStream());
+ BufferedReader br = new BufferedReader(isr);
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ if (line.trim().length() > 0) {
+ consoleMessages.add(line);
+ }
+ }
+ process.getInputStream().close();
+ }
+ }
+ catch (IOException ex) {
+ if (!Thread.currentThread().isInterrupted())
+ System.out.print(ex.getMessage());
+ System.out.print(ex.getMessage());
+ }
+ catch (Exception ex) {
+ System.out.print(ex.getMessage());
+ }
+ return consoleMessages;
+ }
+
+ public static ArrayList<String> runProcess(String[] command) {
+ return runProcess(command, true);
+ }
+
+ public static String getMPJProcessID(String host) {
+ ProcessBuilder pb = new ProcessBuilder();
+ return getMPJProcessID(host, pb);
+ }
+
+ public static ArrayList<String> getJavaProcesses(String host) {
+ ProcessBuilder pb = new ProcessBuilder();
+ return getJavaProcesses(host, pb);
+ }
+
+ public static String getMPJProcessID(String host, ProcessBuilder pb) {
+ int index = 0;
+ int space = 0;
+ String pid = "";
+ ArrayList<String> consoleMessages = new ArrayList<String>();
+ if (System.getProperty("os.name").startsWith("Windows"))
+ consoleMessages = getWinJavaProcesses(host, pb);
+ else
+ consoleMessages = getJavaProcesses(host, pb);
+ for (String message : consoleMessages) {
+ index = message.indexOf("MPJDaemon");
+ if (index > -1) {
+ space = message.indexOf(" ");
+ pid = message.substring(0, space);
+ return pid;
+ }
+ }
+ return pid;
+ }
+
+ public static ArrayList<String> getJavaProcesses(String host,
+ ProcessBuilder pb) {
+ String[] command = { "ssh", host, "nohup", "jps", "-m", };
+ ArrayList<String> consoleMessages = runProcess(command);
+ return consoleMessages;
+
+ }
+
+ public static ArrayList<String> getWinJavaProcesses(String host,
+ ProcessBuilder pb) {
+ String[] command = { "jps", "-m", };
+ ArrayList<String> consoleMessages = runProcess(command);
+ return consoleMessages;
+
+ }
+
+}
diff --git a/src/runtime/daemonmanager/HaltThread.java b/src/runtime/daemonmanager/HaltThread.java
new file mode 100644
index 0000000..40363e2
--- /dev/null
+++ b/src/runtime/daemonmanager/HaltThread.java
@@ -0,0 +1,74 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : HaltThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+
+import runtime.common.MPJUtil;
+
+public class HaltThread extends DMThread {
+ private String host = "localhost";
+
+ public HaltThread(String machineName) {
+ host = machineName;
+ }
+
+ public void run() {
+ haltMPJExpressDeamons();
+ }
+
+ public void haltMPJExpressDeamons() {
+ String pid = DaemonUtil.getMPJProcessID(host);
+ if (pid != "") {
+ String[] command = { "ssh", host, "kill", "-9", pid, };
+ ArrayList<String> consoleMessages = DaemonUtil.runProcess(command);
+ for (String message : consoleMessages) {
+ if (message.indexOf(DMMessages.UNKNOWN_HOST) > 0)
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.HOST_INACESSABLE));
+ }
+ pid = DaemonUtil.getMPJProcessID(host);
+ if (pid == "")
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_STOPPED));
+ } else
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_NOT_AVIALBLE));
+ }
+
+}
diff --git a/src/runtime/daemonmanager/MPJBoot.java b/src/runtime/daemonmanager/MPJBoot.java
new file mode 100644
index 0000000..d93faa6
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJBoot.java
@@ -0,0 +1,58 @@
+package runtime.daemonmanager;
+
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJBoot.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+import runtime.daemonmanager.MPJBoot;
+
+public class MPJBoot {
+
+ /*
+ * public static void main(String[] args) {
+ *
+ * CLOptions options = new CLOptions(); options.parseCommandLineArgs(args);
+ * options.setCmdType(DMConstants.BOOT); MPJBoot pm = new MPJBoot();
+ * pm.bootMPJExpress(options);
+ *
+ * }
+ */
+
+ public void bootMPJExpress(CLOptions options) {
+ DMThreadUtil.ExecuteCommand(options);
+ }
+
+}
diff --git a/src/runtime/daemonmanager/MPJCleanup.java b/src/runtime/daemonmanager/MPJCleanup.java
new file mode 100644
index 0000000..672de23
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJCleanup.java
@@ -0,0 +1,55 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJCleanUp.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import runtime.daemonmanager.MPJCleanup;
+
+public class MPJCleanup {
+
+ /*
+ * public static void main(String[] args) {
+ *
+ * CLOptions options = new CLOptions(); options.parseCommandLineArgs(args);
+ * MPJCleanup cl = new MPJCleanup(); cl.cleanupMPJEnviroment(options);
+ *
+ * }
+ */
+
+ public void cleanupMPJEnviroment(CLOptions options) {
+ DMThreadUtil.ExecuteCommand(options);
+ }
+}
diff --git a/src/runtime/daemonmanager/MPJDaemonManager.java b/src/runtime/daemonmanager/MPJDaemonManager.java
new file mode 100644
index 0000000..ca0c529
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJDaemonManager.java
@@ -0,0 +1,83 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJdaemonmanager.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+import java.io.IOException;
+
+public class MPJDaemonManager {
+ public static void main(String[] args) {
+ CLOptions options = new CLOptions();
+ options.parseCommandLineArgs(args);
+
+ if (options.getCmdType().equals(DMConstants.HELP)) {
+ options.PrintHelp();
+ return;
+ }
+ if (options.getCmdType().toLowerCase().equals(DMConstants.BOOT)) {
+ MPJBoot mpBoot = new MPJBoot();
+ mpBoot.bootMPJExpress(options);
+ } else if (options.getCmdType().equals(DMConstants.HALT)) {
+ MPJHalt mpHalt = new MPJHalt();
+ mpHalt.haltMPJExpress(options);
+ } else if (options.getCmdType().equals(DMConstants.CLEAN)) {
+ MPJCleanup mpCleanup = new MPJCleanup();
+ mpCleanup.cleanupMPJEnviroment(options);
+ } else if (options.getCmdType().equals(DMConstants.STATUS)) {
+ MPJStatus mpQuery = new MPJStatus();
+ mpQuery.getMPJExpressStatus(options);
+ } else if (options.getCmdType().equals(DMConstants.INFO)) {
+ MPJProcessInfo mpInfo = new MPJProcessInfo();
+ mpInfo.getJavaProcessInfo(options);
+ } else if (options.getCmdType().equals(DMConstants.WIN_BOOT)) {
+ WinBoot winBoot = new WinBoot();
+ try {
+ winBoot.startMPJExpress();
+ }
+ catch (IOException e) {
+ System.out.println(e.getMessage());
+ }
+ } else if (options.getCmdType().equals(DMConstants.WIN_HALT)) {
+ WinHalt winHalt = new WinHalt();
+ winHalt.haltMPJExpress();
+ } else {
+ options.PrintHelp();
+ }
+ System.exit(0);
+ }
+
+}
diff --git a/src/runtime/daemonmanager/MPJHalt.java b/src/runtime/daemonmanager/MPJHalt.java
new file mode 100644
index 0000000..76f4127
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJHalt.java
@@ -0,0 +1,56 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJHalt.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+
+package runtime.daemonmanager;
+
+import runtime.daemonmanager.MPJHalt;
+
+public class MPJHalt {
+
+ /*
+ * public static void main(String[] args) {
+ *
+ * CLOptions options = new CLOptions(); options.parseCommandLineArgs(args);
+ * MPJHalt halt = new MPJHalt(); halt.haltMPJExpress(options);
+ *
+ * }
+ */
+
+ public void haltMPJExpress(CLOptions options) {
+ DMThreadUtil.ExecuteCommand(options);
+ }
+}
diff --git a/src/runtime/daemonmanager/MPJProcessInfo.java b/src/runtime/daemonmanager/MPJProcessInfo.java
new file mode 100644
index 0000000..ea3e433
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJProcessInfo.java
@@ -0,0 +1,18 @@
+package runtime.daemonmanager;
+
+public class MPJProcessInfo {
+
+ /*
+ * public static void main(String[] args) {
+ *
+ * CLOptions options = new CLOptions(); options.parseCommandLineArgs(args);
+ * MPJProcessInfo info = new MPJProcessInfo();
+ * info.getJavaProcessInfo(options);
+ *
+ * }
+ */
+
+ public void getJavaProcessInfo(CLOptions options) {
+ DMThreadUtil.ExecuteCommand(options);
+ }
+}
diff --git a/src/runtime/daemonmanager/MPJStatus.java b/src/runtime/daemonmanager/MPJStatus.java
new file mode 100644
index 0000000..714bde7
--- /dev/null
+++ b/src/runtime/daemonmanager/MPJStatus.java
@@ -0,0 +1,55 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJStatus.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import runtime.daemonmanager.MPJStatus;
+
+public class MPJStatus {
+
+ /*
+ * public static void main(String[] args) {
+ *
+ * CLOptions options = new CLOptions(); options.parseCommandLineArgs(args);
+ * MPJStatus status = new MPJStatus(); status.getMPJExpressStatus(options);
+ *
+ * }
+ */
+
+ public void getMPJExpressStatus(CLOptions options) {
+ DMThreadUtil.ExecuteCommand(options);
+ }
+}
diff --git a/src/runtime/daemonmanager/ProcessInfoThread.java b/src/runtime/daemonmanager/ProcessInfoThread.java
new file mode 100644
index 0000000..8e60aec
--- /dev/null
+++ b/src/runtime/daemonmanager/ProcessInfoThread.java
@@ -0,0 +1,33 @@
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+
+public class ProcessInfoThread extends DMThread {
+
+ private String host = "localhost";
+
+ public ProcessInfoThread(String machineName) {
+ host = machineName;
+ }
+
+ public void run() {
+ getJavaProcesses();
+ }
+
+ public void getJavaProcesses() {
+ String userName = System.getProperty("user.name");
+ ArrayList<String> consoleMessages = DaemonUtil.getJavaProcesses(host);
+ int messageCount = 0;
+ for (String message : consoleMessages) {
+ if (message.toLowerCase().indexOf("jps") < 0) {
+ System.out.println("[" + userName + " @ " + host + "] " + message);
+ messageCount++;
+ }
+ }
+ if (messageCount == 0) {
+ System.out.println("[" + userName + " @ " + host + "] "
+ + DMMessages.NO_JAVA_PROCESS_RUNNING);
+ }
+ }
+
+}
diff --git a/src/runtime/daemonmanager/StatusThread.java b/src/runtime/daemonmanager/StatusThread.java
new file mode 100644
index 0000000..2c1ee50
--- /dev/null
+++ b/src/runtime/daemonmanager/StatusThread.java
@@ -0,0 +1,62 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : StatusThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : January 30, 2013 6:00:57 PM 2013
+ * Revision : $
+ * Updated : $
+ */
+package runtime.daemonmanager;
+
+import runtime.common.MPJUtil;
+
+public class StatusThread extends DMThread {
+ private String host = "localhost";
+
+ public StatusThread(String machineName) {
+ host = machineName;
+ }
+
+ public void run() {
+ queryMPJExpressDeamons();
+ }
+
+ public void queryMPJExpressDeamons() {
+ String pid = DaemonUtil.getMPJProcessID(host);
+ if (pid != "")
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_AVIALBLE + pid));
+ else
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_NOT_AVIALBLE));
+ }
+
+}
diff --git a/src/runtime/daemonmanager/WinBoot.java b/src/runtime/daemonmanager/WinBoot.java
new file mode 100644
index 0000000..8d497af
--- /dev/null
+++ b/src/runtime/daemonmanager/WinBoot.java
@@ -0,0 +1,64 @@
+package runtime.daemonmanager;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+import runtime.common.MPJUtil;
+
+public class WinBoot {
+
+ public WinBoot() {
+ }
+
+ private String host = "localhost";
+ private String port = MPJUtil.getConfigValue(DMConstants.CONF_PORT_KEY);
+
+ public void startMPJExpress() throws IOException {
+
+ if (validExecutionParams()) {
+ try {
+ String[] command = { "java", "-cp",
+ MPJUtil.getJarPath("daemon") + ";.", "runtime.daemon.MPJDaemon",
+ port, };
+ ArrayList<String> consoleMessages = DaemonUtil.runProcess(command,
+ false);
+ String pid = DaemonUtil.getMPJProcessID(host);
+ if (!pid.equals("") && Integer.parseInt(pid) > -1
+ && Integer.parseInt(pid) < 30000) {
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_STARTED + pid));
+ } else {
+ for (String message : consoleMessages)
+ System.out.println(message);
+ }
+
+ }
+ catch (Exception ex) {
+ System.out.print(ex.getMessage() + "\n" + ex.getStackTrace());
+ }
+ }
+
+ }
+
+ private boolean validExecutionParams() {
+
+ InetAddress address = null;
+ try {
+ address = InetAddress.getByName(host);
+ }
+ catch (UnknownHostException e) {
+
+ e.printStackTrace();
+ System.out.println(e.getMessage());
+ return false;
+ }
+ if (MPJUtil.IsBusy(address, Integer.parseInt(port))) {
+ System.out.println(MPJUtil.FormatMessage(host, DMMessages.BUSY_PORT));
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/src/runtime/daemonmanager/WinHalt.java b/src/runtime/daemonmanager/WinHalt.java
new file mode 100644
index 0000000..bc0d284
--- /dev/null
+++ b/src/runtime/daemonmanager/WinHalt.java
@@ -0,0 +1,30 @@
+package runtime.daemonmanager;
+
+import java.util.ArrayList;
+import runtime.common.MPJUtil;
+
+public class WinHalt {
+
+ private String host = "localhost";
+
+ public void haltMPJExpress() {
+ ProcessBuilder pb = new ProcessBuilder();
+ String pid = DaemonUtil.getMPJProcessID(host, pb);
+ if (pid != "") {
+ String[] command = { "taskkill", "/f", "/pid", pid, };
+ ArrayList<String> consoleMessages = DaemonUtil.runProcess(command);
+ for (String message : consoleMessages) {
+ if (message.indexOf(DMMessages.UNKNOWN_HOST) > 0)
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.HOST_INACESSABLE));
+ }
+ pid = DaemonUtil.getMPJProcessID(host);
+ if (pid == "")
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_STOPPED));
+ } else
+ System.out.println(MPJUtil.FormatMessage(host,
+ DMMessages.MPJDAEMON_NOT_AVIALBLE));
+ }
+
+}
diff --git a/src/runtime/starter/IOMessagesThread.java b/src/runtime/starter/IOMessagesThread.java
new file mode 100644
index 0000000..0a6aba8
--- /dev/null
+++ b/src/runtime/starter/IOMessagesThread.java
@@ -0,0 +1,90 @@
+/*
+ The MIT License
+
+ Copyright (c) 2013 - 2013
+ 1. High Performance Computing Group,
+ School of Electrical Engineering and Computer Science (SEECS),
+ National University of Sciences and Technology (NUST)
+ 2. Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter (2013 - 2013)
+
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : IOMessagesThread.java
+ * Author : Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Oct 28, 2013
+ * Revision : $
+ * Updated : Nov 05, 2013
+ */
+
+package runtime.starter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Scanner;
+
+public class IOMessagesThread extends Thread {
+
+ Socket clientSock;
+
+ public IOMessagesThread(Socket clientSock) {
+ this.clientSock = clientSock;
+ }
+
+ @Override
+ public void run() {
+ serverSocketInit();
+ }
+
+ private void serverSocketInit() {
+
+ Scanner input = null;
+ PrintWriter output = null;
+ try {
+ input = new Scanner(clientSock.getInputStream());
+ output = new PrintWriter(clientSock.getOutputStream(), true);
+ String message = input.nextLine();
+ while (!(message.endsWith("EXIT"))) {
+ if (!message.startsWith("@Ping#"))
+ System.out.println(message);
+ message = input.nextLine();
+ }
+
+ }
+ catch (Exception cce) {
+
+ System.exit(0);
+ }
+ finally {
+ try {
+ clientSock.close();
+ input.close();
+ output.close();
+ }
+ catch (IOException ioEx) {
+ System.exit(1);
+ }
+ }
+ }
+
+}
diff --git a/src/runtime/starter/MPJRun.java b/src/runtime/starter/MPJRun.java
new file mode 100644
index 0000000..d310082
--- /dev/null
+++ b/src/runtime/starter/MPJRun.java
@@ -0,0 +1,885 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2011
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2011)
+ 3. Bryan Carpenter (2005 - 2011)
+ 4. Mark Baker (2005 - 2011)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MPJRun.java
+ * Author : Aamir Shafi, Bryan Carpenter,Khurram Shahzad, Mohsan Jameel, Aamir Shafi, Bryan Carpenter
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.35 $
+ * Updated : $Date: Wed Nov 5 20:55:53 EST 2013$
+ */
+
+package runtime.starter;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.DailyRollingFileAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.spi.LoggerRepository;
+
+import runtime.common.IOHelper;
+import runtime.common.MPJProcessTicket;
+import runtime.common.MPJRuntimeException;
+import runtime.common.MPJUtil;
+import runtime.common.RTConstants;
+
+public class MPJRun {
+
+ final String DEFAULT_MACHINES_FILE_NAME = "machines";
+ final int DEFAULT_PROTOCOL_SWITCH_LIMIT = 128 * 1024; // 128K
+
+ private int D_SER_PORT = Integer
+ .parseInt(getValueFromWrapper("wrapper.app.parameter.2"));
+
+ private String CONF_FILE_CONTENTS = "#temp line";
+ private int mxBoardNum = 0;
+
+ String machinesFile = DEFAULT_MACHINES_FILE_NAME;
+ private int psl = DEFAULT_PROTOCOL_SWITCH_LIMIT;
+
+ ArrayList<String> jvmArgs = new ArrayList<String>();
+ ArrayList<String> appArgs = new ArrayList<String>();
+ String[] jArgs = null;
+ String[] aArgs = null;
+ static Logger logger = null;
+ private Vector<Socket> peerSockets;
+
+ private ArrayList<String> machineList = new ArrayList<String>();
+ int nprocs = Runtime.getRuntime().availableProcessors();
+ String deviceName = "multicore";
+ String mpjHomeDir = null;
+ byte[] urlArray = null;
+ Hashtable procsPerMachineTable = new Hashtable();
+ int endCount = 0;
+ int streamEndedCount = 0;
+ String wdir;
+ String className = null;
+ String applicationClassPathEntry = null;
+
+ static final boolean DEBUG = true;
+ static final String VERSION = "0.42";
+ private static int RUNNING_JAR_FILE = 2;
+ private static int RUNNING_CLASS_FILE = 1;
+ private boolean zippedSource = false;
+ private String sourceFolder = "";
+ int networkProcesscount = -1;
+
+ private String networkDevice = "niodev";
+ private boolean ADEBUG = false;
+ private boolean APROFILE = false;
+ private int DEBUG_PORT = 24500;
+ private final String CONF_FILE_NAME = "mpjdev.conf";
+ private int portManagerPort = Integer
+ .parseInt(getValueFromWrapper("wrapper.app.parameter.3"));
+
+ /**
+ * Every thing is being inside this constructor :-)
+ */
+ public MPJRun(String args[]) throws Exception {
+
+ java.util.logging.Logger logger1 = java.util.logging.Logger.getLogger("");
+
+ // remove all existing log handlers: remove the ERR handler
+ for (java.util.logging.Handler h : logger1.getHandlers()) {
+ logger1.removeHandler(h);
+ }
+
+ Map<String, String> map = System.getenv();
+ mpjHomeDir = map.get("MPJ_HOME");
+
+ createLogger(args);
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.info(" --MPJRun invoked--");
+ logger.info(" adding shutdown hook thread");
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.info("processInput called ...");
+ }
+
+ processInput(args);
+
+ /* the code is running in the multicore configuration */
+ if (deviceName.equals("multicore")) {
+
+ System.out.println("MPJ Express (" + VERSION + ") is started in the "
+ + "multicore configuration");
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.info("className " + className);
+ }
+
+ int jarOrClass = (applicationClassPathEntry.endsWith(".jar") ? RUNNING_JAR_FILE
+ : RUNNING_CLASS_FILE);
+
+ MulticoreDaemon multicoreDaemon = new MulticoreDaemon(className,
+ applicationClassPathEntry, jarOrClass, nprocs, wdir, jvmArgs,
+ appArgs, ADEBUG, APROFILE, DEBUG_PORT);
+ return;
+
+ } else { /* cluster configuration */
+ System.out.println("MPJ Express (" + VERSION + ") is started in the "
+ + "cluster configuration with " + deviceName);
+ }
+
+ machineList = MPJUtil.readMachineFile(machinesFile);
+ for (int i = machineList.size(); i > nprocs; i--) {
+ machineList.remove(i - 1);
+ }
+
+ machinesSanityCheck();
+ // Changed to incorporate hybrid device configuration
+ if (deviceName.equals("hybdev"))
+ assignTasksHyb();
+ else
+ assignTasks();
+
+ if (ADEBUG) {
+ writeFile(CONF_FILE_CONTENTS + "\n");
+ }
+
+ urlArray = applicationClassPathEntry.getBytes();
+ peerSockets = new Vector<Socket>();
+ clientSocketInit();
+ int peersStartingRank = 0;
+
+ for (int j = 0; j < peerSockets.size(); j++) {
+
+ Socket peerSock = peerSockets.get(j);
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procsPerMachineTable " + procsPerMachineTable);
+ }
+
+ /*
+ * FIXME: should we not be checking all IP addresses of remote machine?
+ * Does it make sense?
+ */
+
+ String hAddress = peerSock.getInetAddress().getHostAddress();
+ String hName = peerSock.getInetAddress().getHostName();
+
+ Integer nProcessesInt = ((Integer) procsPerMachineTable.get(hName));
+
+ if (nProcessesInt == null) {
+ nProcessesInt = ((Integer) procsPerMachineTable.get(hAddress));
+ }
+
+ int nProcesses = nProcessesInt.intValue();
+
+ if (deviceName.equals("hybdev")) {
+ pack(nProcesses, j, peerSock); // starting NETID of hybrid
+ // device should be adjusted
+ // according to node
+ // (NioProcessCount,
+ // StartingRank)
+ } else {
+
+ pack(nProcesses, peersStartingRank, peerSock);
+ peersStartingRank += nProcesses;
+ }
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Sending to " + peerSock);
+ }
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procsPerMachineTable " + procsPerMachineTable);
+ }
+
+ }
+
+ /**
+ * Parses the input ...
+ */
+ private void processInput(String args[]) {
+
+ if (args.length < 1) {
+ printUsage();
+ System.exit(0);
+ }
+
+ boolean parallelProgramNotYetEncountered = true;
+
+ for (int i = 0; i < args.length; i++) {
+
+ if (args[i].equals("-np")) {
+
+ try {
+ nprocs = new Integer(args[i + 1]).intValue();
+ if (nprocs < 1) {
+ System.out
+ .println("Number of Processes should be equal to or greater than 1");
+ System.out.println("exiting ...");
+ System.exit(0);
+ }
+ }
+ catch (NumberFormatException e) {
+ nprocs = Runtime.getRuntime().availableProcessors();
+ }
+
+ i++;
+ }
+
+ else if (args[i].equals("-h")) {
+ printUsage();
+ System.exit(0);
+ }
+
+ else if (args[i].equals("-dport")) {
+ D_SER_PORT = new Integer(args[i + 1]).intValue();
+ i++;
+ }
+
+ else if (args[i].equals("-dev")) {
+ deviceName = args[i + 1];
+ i++;
+ if (!(deviceName.equals("niodev") || deviceName.equals("hybdev")
+ || deviceName.equals("mxdev") || deviceName.equals("multicore"))) {
+ System.out.println("MPJ Express currently does not support the <"
+ + deviceName + "> device.");
+ System.out
+ .println("Possible options are niodev, hybdev, mxdev, natdev, and "
+ + "multicore devices.");
+ System.out.println("exiting ...");
+ System.exit(0);
+ }
+ }
+
+ else if (args[i].equals("-machinesfile")) {
+ machinesFile = args[i + 1];
+ i++;
+ }
+
+ else if (args[i].equals("-wdir")) {
+ wdir = args[i + 1];
+ i++;
+ }
+
+ else if (args[i].equals("-psl")) {
+ psl = new Integer(args[i + 1]).intValue();
+ i++;
+ }
+
+ else if (args[i].equals("-mxboardnum")) {
+ mxBoardNum = new Integer(args[i + 1]).intValue();
+ i++;
+ }
+
+ else if (args[i].equals("-cp") | args[i].equals("-classpath")) {
+ jvmArgs.add("-cp");
+ jvmArgs.add(args[i + 1]);
+ i++;
+ } else if (args[i].equals("-jar")) {
+ File tFile = new File(args[i + 1]);
+ String absJarPath = tFile.getAbsolutePath();
+
+ if (tFile.exists()) {
+ applicationClassPathEntry = new String(absJarPath);
+
+ try {
+ JarFile jarFile = new JarFile(absJarPath);
+ Attributes attr = jarFile.getManifest().getMainAttributes();
+ className = attr.getValue(Attributes.Name.MAIN_CLASS);
+ }
+ catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ parallelProgramNotYetEncountered = false;
+ i++;
+ } else {
+ throw new MPJRuntimeException("mpjrun cannot find the jar file <"
+ + args[i + 1] + ">. Make sure this is the right path.");
+ }
+
+ } else if (args[i].equals("-src")) {
+ this.zippedSource = true;
+ } else if (args[i].equals("-debug")) {
+ DEBUG_PORT = new Integer(args[i + 1]).intValue();
+ i++;
+ ADEBUG = true;
+ } else if (args[i].equals("-profile")) {
+ APROFILE = true;
+ } else {
+ // these are JVM options ..
+ if (parallelProgramNotYetEncountered) {
+ if (args[i].startsWith("-")) {
+ jvmArgs.add(args[i]);
+ } else {
+ // This code takes care of executing class files
+ // directly ....
+ // although does not look like it ....
+ applicationClassPathEntry = System.getProperty("user.dir");
+ className = args[i];
+ parallelProgramNotYetEncountered = false;
+ }
+ }
+
+ // these have to be app arguments ...
+ else {
+ appArgs.add(args[i]);
+ }
+
+ }
+
+ }
+
+ jArgs = jvmArgs.toArray(new String[0]);
+ aArgs = appArgs.toArray(new String[0]);
+
+ if (DEBUG && logger.isDebugEnabled()) {
+
+ logger.debug("###########################");
+ logger.debug("-dport: <" + D_SER_PORT + ">");
+ logger.debug("-np: <" + nprocs + ">");
+ logger.debug("$MPJ_HOME: <" + mpjHomeDir + ">");
+ logger.debug("-dir: <" + wdir + ">");
+ logger.debug("-dev: <" + deviceName + ">");
+ logger.debug("-psl: <" + psl + ">");
+ logger.debug("jvmArgs.length: <" + jArgs.length + ">");
+ logger.debug("className : <" + className + ">");
+ logger.debug("applicationClassPathEntry : <" + applicationClassPathEntry
+ + ">");
+
+ for (int i = 0; i < jArgs.length; i++) {
+ if (DEBUG && logger.isDebugEnabled())
+ logger.debug(" jvmArgs[" + i + "]: <" + jArgs[i] + ">");
+ }
+ if (DEBUG && logger.isDebugEnabled())
+ logger.debug("appArgs.length: <" + aArgs.length + ">");
+
+ for (int i = 0; i < aArgs.length; i++) {
+ if (DEBUG && logger.isDebugEnabled())
+ logger.debug(" appArgs[" + i + "]: <" + aArgs[i] + ">");
+ }
+
+ if (DEBUG && logger.isDebugEnabled())
+ logger.debug("###########################");
+ }
+ }
+
+ /*
+ * 1. Application Classpath Entry (urlArray). This is a String classpath entry
+ * which will be appended by the MPJ Express daemon before starting a user
+ * process (JVM). In the case of JAR file, it's the absolute path and name. In
+ * the case of a class file, its the name of the working directory where
+ * mpjrun command was launched. 2. nProcs- [# of processes] to be started by a
+ * particular MPJ Express daemon. 3. start_rank [starting #(rank) of process]
+ * to be started by a particular MPJ Express daemon. 4. jvmArgs- args to JVM
+ * 5. wdir Working Directory 6. className- Classname to be executed. In the
+ * case of JAR file, this name is taken from the manifest file. In the case of
+ * class file, the class name is specified on the command line by the user. 7.
+ * CONF_FILE_CONTENTS- Configuration File name. This is a ';' delimeted string
+ * of config file contents 8. deviceName-: what device to use? 9. appArgs-:
+ * Application arguments .. 10. networkDevice- niodev in case of Hybdrid 11.
+ * ADEBUG- Flag for launching application in debug mode 12. APROFILE- Flag for
+ * launching application in Profiling mode
+ */
+ private void pack(int nProcesses, int start_rank, Socket sockClient) {
+
+ if (wdir == null) {
+ wdir = System.getProperty("user.dir");
+ }
+
+ MPJProcessTicket ticket = new MPJProcessTicket();
+
+ ticket.setClassPath(new String(urlArray));
+ ticket.setProcessCount(nProcesses);
+ ticket.setStartingRank(start_rank);
+ ticket.setWorkingDirectory(wdir);
+ ticket.setUserID(System.getProperty("user.name"));
+ if (this.zippedSource) {
+ String zipFileName = UUID.randomUUID() + ".zip";
+ this.sourceFolder = wdir;
+ IOHelper.zipFolder(this.sourceFolder, zipFileName);
+ byte[] zipContents = IOHelper.ReadBinaryFile(zipFileName);
+ String encodedString = Base64.encodeBase64String(zipContents);
+ ticket.setSourceCode(encodedString);
+ IOHelper.deleteFile(zipFileName);
+ ticket.setZippedSource(true);
+ }
+ ticket.setMainClass(className);
+ ticket.setConfFileContents(CONF_FILE_CONTENTS);
+ ticket.setDeviceName(deviceName);
+ IOMessagesThread ioMessages = new IOMessagesThread(sockClient);
+ ioMessages.start();
+ ArrayList<String> jvmArgs = new ArrayList<String>();
+ for (int j = 0; j < jArgs.length; j++) {
+ jvmArgs.add(jArgs[j]);
+ }
+ ticket.setJvmArgs(jvmArgs);
+
+ ArrayList<String> appArgs = new ArrayList<String>();
+ for (int j = 0; j < aArgs.length; j++) {
+ appArgs.add(aArgs[j]);
+ }
+ ticket.setAppArgs(appArgs);
+
+ if (deviceName.equals("hybdev")) {
+ ticket.setNetworkProcessCount(networkProcesscount);
+ ticket.setTotalProcessCount(nprocs);
+ ticket.setNetworkDevice(networkDevice);
+ }
+
+ if (ADEBUG) {
+ ticket.setDebug(true);
+ ticket.setDebugPort(DEBUG_PORT);
+ }
+
+ if (APROFILE) {
+ ticket.setProfiler(true);
+ }
+ String ticketString = ticket.ToXML().toXmlString();
+ OutputStream outToServer = null;
+ try {
+ outToServer = sockClient.getOutputStream();
+ }
+ catch (IOException e) {
+ logger.info(" Unable to get deamon stream-");
+ e.printStackTrace();
+ }
+ DataOutputStream out = new DataOutputStream(outToServer);
+
+ try {
+ int length = ticketString.getBytes().length;
+ out.writeInt(length);
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.info("Machine Name: "
+ + sockClient.getInetAddress().getHostName() + " Startting Rank: "
+ + ticket.getStartingRank() + " Process Count: "
+ + ticket.getProcessCount());
+ }
+ out.write(ticketString.getBytes(), 0, length);
+ out.flush();
+ }
+ catch (IOException e) {
+
+ logger.info(" Unable to write on deamon stream-");
+ e.printStackTrace();
+ }
+ }
+
+ private void createLogger(String[] args) throws MPJRuntimeException {
+
+ if (DEBUG && logger == null) {
+
+ DailyRollingFileAppender fileAppender = null;
+
+ try {
+ fileAppender = new DailyRollingFileAppender(new PatternLayout(
+ " %-5p %c %x - %m\n"), mpjHomeDir + "/logs/mpjrun.log",
+ "yyyy-MM-dd-a");
+
+ Logger rootLogger = Logger.getRootLogger();
+ rootLogger.addAppender(fileAppender);
+ LoggerRepository rep = rootLogger.getLoggerRepository();
+ rootLogger.setLevel((Level) Level.ALL);
+ // rep.setThreshold((Level) Level.OFF ) ;
+ logger = Logger.getLogger("runtime");
+ String level = getValueFromWrapper("wrapper.logfile.loglevel.mpjrun");
+ logger.setLevel(Level.toLevel(level.toUpperCase(), Level.OFF));
+ }
+ catch (Exception e) {
+ throw new MPJRuntimeException(e);
+ }
+ }
+ }
+
+ private void printUsage() {
+ System.out
+ .println("mpjrun.[bat/sh] [options] class [args...]"
+ + "\n (to execute a class)"
+ + "\nmpjrun.[bat/sh] [options] -jar jarfile [args...]"
+ + "\n (to execute a jar file)"
+ + "\n\nwhere options include:"
+ + "\n -np val -- <# of cores>"
+ + "\n -dev val -- <multicore>"
+ + "\n -dport val -- <read from wrapper.conf>"
+ + "\n -wdir val -- $MPJ_HOME/bin"
+ + "\n -mpjport val -- Deprecated"
+ + "\n -mxboardnum val -- 0"
+ + "\n -headnodeip val -- ..."
+ + "\n -psl val -- 128Kbytes"
+ + "\n -machinesfile val -- machines"
+ + "\n -debug val -- 24500"
+ + "\n -src val -- false"
+ + "\n -profile val -- false"
+ + "\n -h -- print this usage information"
+ + "\n ...any JVM arguments..."
+ + "\n Note: Value on the right in front of each option is the default value"
+ + "\n Note: 'MPJ_HOME' variable must be set");
+
+ }
+
+ private void assignTasks() throws Exception {
+
+ int rank = 0;
+
+ int noOfMachines = machineList.size();
+
+ CONF_FILE_CONTENTS += ";" + "# Number of Processes";
+ CONF_FILE_CONTENTS += ";" + nprocs;
+ CONF_FILE_CONTENTS += ";" + "# Protocol Switch Limit";
+ CONF_FILE_CONTENTS += ";" + psl;
+ CONF_FILE_CONTENTS += ";"
+ + "# Entry, HOST_NAME/IP at READPORT@WRITEPORT at RANK@DEBUGPORT";
+
+ /*
+ * number of requested parallel processes are less than or equal to compute
+ * nodes
+ */
+ if (nprocs <= noOfMachines) {
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Processes Requested " + nprocs
+ + " are less than than machines " + noOfMachines);
+ logger.debug("Adding 1 processes to the first " + nprocs + " items");
+ }
+
+ for (int i = 0; i < nprocs; i++) {
+ procsPerMachineTable
+ .put(InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress(), new Integer(1));
+
+ if (deviceName.equals("niodev")) {
+ Integer[] ports = getNextAvialablePorts((String) machineList.get(i));
+ int readPort = ports[0];
+ int writePort = ports[1];
+ CONF_FILE_CONTENTS += ";"
+ + InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress() + "@" + readPort + "@" + writePort + "@"
+ + (rank++);
+
+ } else if (deviceName.equals("mxdev")) {
+ CONF_FILE_CONTENTS += ";" + (String) machineList.get(i) + "@"
+ + mxBoardNum + "@" + (rank++);
+ }
+ CONF_FILE_CONTENTS += "@" + (DEBUG_PORT);
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procPerMachineTable==>" + procsPerMachineTable);
+ }
+ }
+
+ /*
+ * number of processes are greater than compute nodes available. we'll
+ * start more than one process on compute nodes to deal with this
+ */
+ } else if (nprocs > noOfMachines) {
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Processes Requested " + nprocs
+ + " are greater than than machines " + noOfMachines);
+ }
+
+ int divisor = nprocs / noOfMachines;
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("divisor " + divisor);
+ }
+ int remainder = nprocs % noOfMachines;
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("remainder " + remainder);
+ }
+
+ for (int i = 0; i < noOfMachines; i++) {
+
+ if (i < remainder) {
+
+ procsPerMachineTable.put(
+ InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress(), new Integer(divisor + 1));
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procPerMachineTable==>" + procsPerMachineTable);
+ }
+
+ for (int j = 0; j < (divisor + 1); j++) {
+
+ if (deviceName.equals("niodev")) {
+
+ Integer[] ports = getNextAvialablePorts((String) machineList
+ .get(i));
+ int readPort = ports[0];
+ int writePort = ports[1];
+
+ CONF_FILE_CONTENTS += ";"
+ + InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress() + "@" + readPort + "@" + writePort
+ + "@" + (rank++);
+
+ } else if (deviceName.equals("mxdev")) {
+ CONF_FILE_CONTENTS += ";" + (String) machineList.get(i) + "@"
+ + (mxBoardNum + j) + "@" + (rank++);
+ }
+ CONF_FILE_CONTENTS += "@" + (DEBUG_PORT + j * 2);
+ }
+ } else if (divisor > 0) {
+ procsPerMachineTable.put(
+ InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress(), new Integer(divisor));
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procPerMachineTable==>" + procsPerMachineTable);
+ }
+
+ for (int j = 0; j < divisor; j++) {
+
+ if (deviceName.equals("niodev")) {
+ Integer[] ports = getNextAvialablePorts((String) machineList
+ .get(i));
+ int readPort = ports[0];
+ int writePort = ports[1];
+
+ CONF_FILE_CONTENTS += ";"
+ + InetAddress.getByName((String) machineList.get(i))
+ .getHostAddress() + "@" + readPort + "@" + writePort
+ + "@" + (rank++);
+ } else if (deviceName.equals("mxdev")) {
+ CONF_FILE_CONTENTS += ";" + (String) machineList.get(i) + "@"
+ + (mxBoardNum + j) + "@" + (rank++);
+ }
+ CONF_FILE_CONTENTS += "@" + (DEBUG_PORT + j * 2);
+ }
+ }
+ }
+ }
+ }
+
+ // ________________ HD _________________________
+
+ private void assignTasksHyb() throws Exception {
+
+ int noOfMachines = machineList.size();
+ networkProcesscount = -1;
+ if (nprocs <= noOfMachines) {
+ networkProcesscount = nprocs;
+ } else { // when np is higher than the nodes available
+ networkProcesscount = noOfMachines;
+ }
+ int netID = 0;
+ CONF_FILE_CONTENTS += ";" + "# Number of NIO Processes";
+ CONF_FILE_CONTENTS += ";" + networkProcesscount;
+ CONF_FILE_CONTENTS += ";" + "# Protocol Switch Limit";
+ CONF_FILE_CONTENTS += ";" + psl;
+ CONF_FILE_CONTENTS += ";"
+ + "# Entry, HOST_NAME/IP at READPORT@WRITEPORT at NETID@DEBUGPORT";
+ // One NIO Process per machine is being implemented, SMP Threads per
+ // node will be decided in SMPDev
+ for (int i = 0; i < networkProcesscount; i++) {
+ procsPerMachineTable.put(
+ InetAddress.getByName((String) machineList.get(i)).getHostAddress(),
+ new Integer(1));
+ Integer[] ports = getNextAvialablePorts((String) machineList.get(i));
+ int readPort = ports[0];
+ int writePort = ports[1];
+ CONF_FILE_CONTENTS += ";"
+ + InetAddress.getByName((String) machineList.get(i)).getHostAddress()
+ + "@" + readPort + "@" + writePort + "@" + (netID++);
+ CONF_FILE_CONTENTS += "@" + (DEBUG_PORT);
+ }
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("procPerMachineTable==>" + procsPerMachineTable);
+ }
+
+ }
+
+ private Integer[] getNextAvialablePorts(String machineName) {
+
+ Integer[] ports = new Integer[2];
+
+ Socket portClient = null;
+ try {
+ portClient = new Socket(machineName, portManagerPort);
+ OutputStream outToServer = portClient.getOutputStream();
+ DataOutputStream out = new DataOutputStream(outToServer);
+ out.writeInt(1);
+ out.flush();
+ DataInputStream din = new DataInputStream(portClient.getInputStream());
+ ports[0] = din.readInt();
+ ports[1] = din.readInt();
+ out.writeInt(2);
+ out.flush();
+
+ }
+ catch (IOException e) {
+ System.out.println("Cannot connect to the daemon " + "at machine <"
+ + machineName + "> and port <" + portManagerPort + ">."
+ + "Please make sure that the machine is reachable "
+ + "and portmanager is running");
+ }
+ finally {
+ try {
+ if (!portClient.isClosed())
+ portClient.close();
+ }
+ catch (IOException e) {
+
+ e.printStackTrace();
+ }
+ }
+ return ports;
+ }
+
+ private void machinesSanityCheck() throws Exception {
+
+ for (int i = 0; i < machineList.size(); i++) {
+
+ String host = (String) machineList.get(i);
+
+ try {
+ InetAddress add = InetAddress.getByName(host);
+
+ }
+ catch (Exception e) {
+ throw new MPJRuntimeException(e);
+ }
+
+ }
+
+ }
+
+ private static String getValueFromWrapper(String Parameter) {
+
+ String value = "";
+ FileInputStream in = null;
+ DataInputStream din = null;
+ BufferedReader reader = null;
+ String line = "";
+
+ try {
+
+ String path = System.getenv("MPJ_HOME") + "/conf/wrapper.conf";
+ in = new FileInputStream(path);
+ din = new DataInputStream(in);
+ reader = new BufferedReader(new InputStreamReader(din));
+
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith(Parameter)) {
+ String trimmedLine = line.replaceAll("\\s+", "");
+ StringTokenizer tokenizer = new StringTokenizer(trimmedLine, "=");
+ tokenizer.nextToken();
+ value = tokenizer.nextToken();
+ break;
+ }
+ }
+
+ in.close();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return value;
+
+ }
+
+ private void clientSocketInit() throws Exception {
+
+ for (int i = 0; i < machineList.size(); i++) {
+ String daemon = (String) machineList.get(i);
+ try {
+
+ if (DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Connecting to " + daemon + "@" + D_SER_PORT);
+ }
+ try {
+ Socket sockClient = new Socket(daemon, D_SER_PORT);
+ if (sockClient.isConnected())
+ peerSockets.add(sockClient);
+ else {
+
+ throw new MPJRuntimeException("Cannot connect to the daemon "
+ + "at machine <" + daemon + "> and port <" + D_SER_PORT + ">."
+ + "Please make sure that the machine is reachable "
+ + "and running the daemon in 'sane' state");
+
+ }
+ }
+ catch (IOException e3) {
+
+ throw new MPJRuntimeException("Cannot connect to the daemon "
+ + "at machine <" + daemon + "> and port <" + D_SER_PORT + ">."
+ + "Please make sure that the machine is reachable "
+ + "and running the daemon in 'sane' state");
+ }
+
+ }
+ catch (Exception ccn1) {
+ System.out.println(" rest of the exceptions ");
+ throw ccn1;
+ }
+ }
+
+ }
+
+ private void writeFile(String configurationFileData) {
+ // Method to write CONF_FILE in user directory that will be later used by
+ // MPJ Express Debugger
+ try {
+ BufferedWriter out = new BufferedWriter(new FileWriter(
+ System.getProperty("user.home") + File.separator + CONF_FILE_NAME));
+ out.write(configurationFileData);
+ out.close();
+ }
+ catch (IOException e) {
+
+ }
+
+ }
+
+ /**
+ * Entry point to the class
+ */
+ public static void main(String args[]) throws Exception {
+
+ try {
+ MPJRun client = new MPJRun(args);
+ }
+ catch (Exception e) {
+ throw e;
+ }
+
+ }
+
+}
diff --git a/src/runtime/starter/MulticoreDaemon.java b/src/runtime/starter/MulticoreDaemon.java
new file mode 100644
index 0000000..007e71f
--- /dev/null
+++ b/src/runtime/starter/MulticoreDaemon.java
@@ -0,0 +1,338 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005
+ 1. Distributed Systems Group, University of Portsmouth
+ 2. Community Grids Laboratory, Indiana University
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MulticoreDaemon.java
+ * Author : Aamir Shafi
+ * Created : Wed Nov 18 13:35:21 PKT 2009
+ * Revision : $Revision: 1.0 $
+ * Updated : $Date: $
+ */
+
+package runtime.starter;
+
+import java.nio.channels.*;
+import java.nio.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.security.*;
+import javax.crypto.*;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Level;
+import org.apache.log4j.DailyRollingFileAppender;
+import org.apache.log4j.spi.LoggerRepository;
+
+import runtime.common.MPJRuntimeException;
+import runtime.daemon.*;
+import java.util.concurrent.Semaphore;
+import java.util.regex.*;
+
+public class MulticoreDaemon {
+
+ private BufferedReader reader = null;
+ private InputStream outp = null;
+ private String hostName = null;
+ private PrintStream out = null;
+ private Semaphore outputHandlerSem = new Semaphore(1, true);
+
+ private String wdir = null;
+ private int numOfProcs = 0;
+ private int pos = 0;
+ private String deviceName = null;
+ private String className = null;
+ private String mpjHome = null;
+ private ArrayList<String> jvmArgs = new ArrayList<String>();
+ private ArrayList<String> appArgs = new ArrayList<String>();
+ private int processes = 0;
+ private String cmd = null;
+ private Process[] processVector = null;
+ private static Logger logger = null;
+ private String mpjHomeDir = null;
+ private String loader = null;
+ private boolean ADEBUG = false;
+ private boolean APROFILE = false;
+ private int DEBUG_PORT = 24500;
+
+ public MulticoreDaemon(String mcClassName, String mcJarName, int classOrJar,
+ int numOfProcessors, String workingDirectory, ArrayList<String> jvmArgs,
+ ArrayList<String> appArgs, boolean ADEBUG, boolean APROFILE,
+ int DEBUG_PORT) throws Exception {
+
+ this.jvmArgs = jvmArgs;
+ this.appArgs = appArgs;
+
+ /* FIXME: It's a dirty hack .. */
+ if (mcJarName.endsWith(".jar"))
+ this.className = mcJarName;
+ else
+ this.className = mcClassName;
+
+ this.processes = numOfProcessors;
+ this.deviceName = "smpdev";
+ this.loader = "useLocalLoader"; // don't need this
+
+ this.ADEBUG = ADEBUG;
+ this.APROFILE = APROFILE;
+ this.DEBUG_PORT = DEBUG_PORT;
+
+ if (workingDirectory == null) {
+ this.wdir = System.getProperty("user.dir");
+ } else {
+ this.wdir = workingDirectory;
+ }
+
+ startNewProcess(mcClassName, numOfProcessors, workingDirectory, mcJarName,
+ classOrJar);
+
+ }
+
+ public void startNewProcess(String mcClassName, int numOfProcessors,
+ String workingDirectory, String jarName, int classOrJar) throws Exception {
+
+ String cmdClassPath = "EMPTY";
+
+ numOfProcs = Runtime.getRuntime().availableProcessors();
+ InetAddress localaddr = InetAddress.getLocalHost();
+ hostName = localaddr.getHostName();
+
+ Map<String, String> map = System.getenv();
+ mpjHomeDir = map.get("MPJ_HOME");
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("mpjHomeDir " + mpjHomeDir);
+ MPJRun.logger.debug("McDaemon is waiting to accept connections ... ");
+ MPJRun.logger.debug("wdir " + wdir);
+ MPJRun.logger.debug("A client has connected");
+ }
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("the daemon will start <" + processes + "> threads");
+ }
+
+ String[] jArgs = jvmArgs.toArray(new String[0]);
+
+ boolean now = false;
+ boolean noSwitch = true;
+
+ for (int e = 0; e < jArgs.length; e++) {
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("jArgs[" + e + "]=" + jArgs[e]);
+ }
+
+ if (now) {
+ cmdClassPath = jvmArgs.remove(e);
+
+ if (cmdClassPath.matches("(?i).*mpj.jar.*")) {
+ // System.out.println("before <"+cmdClassPath+">");
+ // System.out.println("mpj.jar is present ...") ;
+ cmdClassPath = cmdClassPath.replaceAll("mpj\\.jar", "mpi.jar");
+ // cmdClassPath.replaceAll(Pattern.quote("mpj.jar"),
+ // Matcher.quoteReplacement("mpi.jar")) ;
+ // System.out.println("after <"+cmdClassPath+">");
+ // System.exit(0) ;
+ }
+
+ String cp = mpjHomeDir + "/lib/smpdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/xdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/mpjbuf.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/loader2.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/starter.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/mpiExp.jar";
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("cp = " + cp);
+ }
+
+ jvmArgs.add(e, cp);
+ now = false;
+ }
+
+ if (jArgs[e].equals("-cp")) {
+ now = true;
+ noSwitch = false;
+ }
+
+ }
+
+ if (noSwitch) {
+ jvmArgs.add("-cp");
+
+ String cp = mpjHomeDir + "/lib/smpdev.jar" + File.pathSeparator + ""
+ + mpjHomeDir + "/lib/xdev.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/mpjbuf.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/loader2.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/starter.jar" + File.pathSeparator + "" + mpjHomeDir
+ + "/lib/mpiExp.jar";
+
+ jvmArgs.add(cp);
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("cp = " + cp);
+ }
+ }
+
+ jArgs = jvmArgs.toArray(new String[0]);
+
+ for (int e = 0; e < jArgs.length; e++) {
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("modified: jArgs[" + e + "]=" + jArgs[e]);
+ }
+ }
+
+ int CMD_WORDS = 8;
+ /*
+ * FIX ME BY AMJAD AZIZ : When launched in Debug Mode
+ */
+ if (ADEBUG)
+ CMD_WORDS++;
+ String[] aArgs = appArgs.toArray(new String[0]);
+ String[] ex = new String[(CMD_WORDS + jArgs.length + aArgs.length)];
+ if (APROFILE)
+ ex[0] = "tau_java";
+ else
+ ex[0] = "java";
+
+ for (int i = 0; i < jArgs.length; i++) {
+ ex[i + 1] = jArgs[i];
+ }
+
+ int indx = jArgs.length + 1;
+ /*
+ * FIX ME BY AMJAD AZIZ : When launched in Debug Mode
+ */
+ if (ADEBUG)
+ ex[indx++] = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
+ + DEBUG_PORT;
+ ex[indx] = "runtime.starter.MulticoreStarter";
+ indx++;
+ ex[indx] = wdir;
+ indx++;
+ ex[indx] = Integer.toString(processes);
+ indx++;
+ ex[indx] = deviceName;
+ indx++;
+ ex[indx] = loader;
+ indx++;
+ ex[indx] = cmdClassPath;
+ indx++;
+
+ if (className != null) {
+ ex[indx] = className;
+ } else {
+ ex[indx] = jarName;
+ }
+
+ for (int i = 0; i < aArgs.length; i++) {
+ ex[i + CMD_WORDS + jArgs.length] = aArgs[i];
+ }
+
+ for (int i = 0; i < ex.length; i++) {
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug(i + ": " + ex[i]);
+ }
+ }
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("creating process-builder object ");
+ }
+
+ ProcessBuilder pb = new ProcessBuilder(ex);
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("wdir =" + wdir);
+ }
+
+ pb.directory(new File(wdir));
+ pb.redirectErrorStream(true);
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("starting the MultithreadStarter.");
+ }
+
+ Process p = null;
+
+ try {
+ p = pb.start();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("started the MultithreadStarter.");
+ }
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("Stopping the output");
+ }
+
+ String line = "";
+ InputStream outp = p.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(outp));
+
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("outputting ...");
+ }
+
+ try {
+ do {
+ if (!line.equals("")) {
+ line.trim();
+
+ synchronized (this) {
+ System.out.println(line);
+ }
+ }
+ } while ((line = reader.readLine()) != null);
+ }
+ catch (Exception e) {
+ if (MPJRun.DEBUG && MPJRun.logger.isDebugEnabled()) {
+ MPJRun.logger.debug("outputHandler =>" + e.getMessage());
+ }
+ e.printStackTrace();
+ }
+ }
+
+ public static void main(String args[]) {
+ try {
+ MulticoreDaemon dae = null;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/runtime/starter/MulticoreStarter.java b/src/runtime/starter/MulticoreStarter.java
new file mode 100644
index 0000000..321de74
--- /dev/null
+++ b/src/runtime/starter/MulticoreStarter.java
@@ -0,0 +1,355 @@
+/*
+The MIT License
+
+Copyright (c) 2010
+1. Aamir Shafi
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MulticoreStarter.java
+ * Author : Aamir Shafi
+ * Created : Sun Dec 12 12:22:15 BST 2004
+ * Revision : $Revision: 1.17 $
+ * Updated : $Date: 2009/08/03 12:48:55 $
+ */
+/**
+ * This class is used for SMP based system stater
+ */
+package runtime.starter;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.lang.Integer;
+import runtime.daemon.JarClassLoader;
+import xdev.smpdev.SMPDevProcess;
+
+public class MulticoreStarter {
+
+ String wdir = null;
+ String config = null;
+ int processes = 0;
+ JarClassLoader classLoader = null;
+ URLClassLoader urlClassLoader = null;
+ String name = null;
+ String className = null;
+ String deviceName = null;
+ String packageName = null;
+ String cmdClassPath = null;
+ String mpjHomeDir = null;
+ String[] nargs = null;
+ String loader = null;
+ String hostName = null;
+ String[] arvs = null;
+ Method[] m;
+ Method[] method;
+ int x;
+ Class[] c;
+ int num;
+ static final Object monitor = new Object();
+ SMPDevProcess[] smpProcess;
+ Integer rank = new Integer(-1);
+ static String appPath = "";
+
+ public MulticoreStarter() {
+ }
+
+ /**
+ * Executes MPJ program in a new JVM. This method is invoked in main method of
+ * this class, which is started by MPJDaemon. This method can only start a new
+ * JVM but can't start multiple threads in one JVM.
+ *
+ * @param args
+ * Arguments to this method. args[0] is wdir 'String', args[1] number
+ * of processes, args[2] is deviceName, and args[3] is rank started
+ * by this process. args[4] is className ... it will only be used if
+ * URL does not point to a JAR file.
+ */
+ public void execute(String args[]) throws Exception {
+
+ InetAddress localaddr = InetAddress.getLocalHost();
+ hostName = localaddr.getHostName();
+ wdir = args[0]; // this contains working directory ...
+ processes = (new Integer(args[1])).intValue();
+ deviceName = args[2];
+ loader = args[3];
+ cmdClassPath = args[4];
+ className = args[5];
+ int ARGS_USED_HERE = 6;
+ nargs = new String[(args.length - ARGS_USED_HERE)];
+ System.arraycopy(args, ARGS_USED_HERE, nargs, 0, nargs.length);
+
+ arvs = new String[(nargs.length + 3)];
+
+ Runnable[] ab = new Runnable[processes];
+
+ smpProcess = new SMPDevProcess[processes];
+ c = new Class[processes];
+ m = new Method[processes];
+ method = new Method[processes];
+
+ for (x = 0; x < processes; x++) {
+ // System.out.println("x " + x);
+ ab[x] = new Runnable() {
+
+ String argNew[] = new String[arvs.length];
+
+ public void run() {
+
+ int index = Integer.parseInt(Thread.currentThread().getName());
+ // String conf = wdir.substring(0, (wdir.lastIndexOf("/") + 1));
+ // config = conf + "mpjdev.conf";
+ // System.out.println("conf " + config);
+ /*
+ * if (loader.equals("useRemoteLoader")) { if
+ * (className.equals("dummy")) { try {
+ * System.out.println("Hello i am remote"); URL[] urls = {new
+ * URL(wdir), new URL(mpjURL)}; classLoader = new
+ * JarClassLoader(urls); name = classLoader.getMainClassName();
+ * c[index] = classLoader.loadClass(name); //packageName =
+ * c.getPackage().getName(); //name = packageName+name; } catch
+ * (Exception e) { e.printStackTrace(); } } else { try {
+ * System.out.println("Hello i am else of remote"); urlClassLoader =
+ * URLClassLoader.newInstance(new URL[]{ new URL(wdir), new
+ * URL(mpjURL)}); name = className; c[index] =
+ * urlClassLoader.loadClass(name); } catch (Exception e) {
+ * e.printStackTrace(); } } } else {
+ */
+
+ synchronized (monitor) {
+
+ try {
+ String mpjHome = System.getenv("MPJ_HOME");
+
+ String libPath = null;
+
+ if (!cmdClassPath.equals("EMPTY")) {
+ libPath = cmdClassPath + File.pathSeparator + mpjHome
+ + "/lib/mpi.jar" + File.pathSeparator + mpjHome
+ + "/lib/mpjdev.jar";
+ } else {
+ libPath = mpjHome + "/lib/mpi.jar" + File.pathSeparator
+ + mpjHome + "/lib/mpjdev.jar";
+ }
+
+ // System.out.println("className = "+className) ;
+
+ if (className.endsWith(".jar")) {
+ if ((new File(className)).isAbsolute()) {
+ // System.out.println("AbsolutePath") ;
+ // System.out.println("className = "+className) ;
+ appPath = className;
+ } else {
+ appPath = wdir + "/" + className;
+ }
+ } else {
+ appPath = wdir;
+ }
+
+ appPath = appPath + File.pathSeparator + libPath;
+
+ ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
+
+ // System.out.println("appPath = "+appPath) ;
+
+ StringTokenizer tok = new StringTokenizer(appPath,
+ File.pathSeparator);
+ int count = tok.countTokens();
+ String[] tokArr = new String[count];
+ File[] f = new File[count];
+ URL[] urls = new URL[count];
+
+ for (int i = 0; i < count; i++) {
+ tokArr[i] = tok.nextToken();
+ f[i] = new File(tokArr[i]);
+ urls[i] = f[i].toURI().toURL();
+ }
+
+ URLClassLoader ucl = new URLClassLoader(urls);
+ Thread.currentThread().setContextClassLoader(ucl);
+
+ if (className.endsWith(".jar")) {
+ // System.out.println("Hello i am jar loader");
+ // System.out.println("wdir ="+wdir) ;
+ String jarFileName = className;
+ // System.out.println("jarFileName ="+jarFileName) ;
+ JarFile jarFile = new JarFile(jarFileName);
+ Attributes attr = jarFile.getManifest().getMainAttributes();
+ name = attr.getValue(Attributes.Name.MAIN_CLASS);
+ c[index] = Class.forName(name, true, ucl);
+ } else {
+ name = className;
+ // System.out.println("num --" + num + " Thread "
+ // +Thread.currentThread()+" Time "+System.nanoTime());
+ c[index] = Class.forName(name, true, ucl);
+ // c[num] = Class.forName(name);
+ }
+
+ }
+ catch (Exception exx) {
+ exx.printStackTrace();
+ }
+
+ arvs[1] = config;
+ arvs[2] = deviceName;
+
+ for (int i = 0; i < nargs.length; i++) {
+ arvs[i + 3] = nargs[i];
+ }
+
+ try {
+
+ if (classLoader != null && loader.equals("useRemoteLoader")) {
+ // System.out.println("Remote loader invoking class");
+ classLoader.invokeClass(c[num], arvs);
+ } else {
+ // System.out.println("getting method " +
+ // num+" Thread "+Thread.currentThread()+" Time "+System.nanoTime());
+ // System.out.println(" -- getting method "+num);
+
+ m[index] = c[index].getMethod("main",
+ new Class[] { arvs.getClass() });
+ m[index].setAccessible(true);
+ int mods = m[index].getModifiers();
+ if (m[index].getReturnType() != void.class
+ || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) {
+ throw new NoSuchMethodException("main");
+ }
+ // m.invoke(null, new Object[] {arvs});
+ method[index] = m[index];
+ }
+ }
+ catch (Exception exp) {
+ }
+ // //// placed end //////
+ }
+ synchronized (monitor) {
+
+ int val = rank.intValue();
+ val++;
+ rank = new Integer(val);
+ arvs[0] = rank.toString();
+ argNew[0] = rank.toString();
+ // System.out.println("rank " + rank);
+ }
+
+ // argNew[1] = arvs[1];
+ // argNew[2] = arvs[2];
+ for (int k = 1; k < arvs.length; k++) {
+ argNew[k] = arvs[k];
+ // System.out.println(" arg new " + argNew[k]);
+ }
+
+ // FIXME: need an elegant way to fill the index 1
+ // element, the issue is that it's filled earlier
+ // and here we are actually re-writing it ..
+ // don't like it ..but atleast works now!
+ argNew[1] = (new Integer(processes)).toString();
+
+ boolean tryAgain = true;
+
+ while (tryAgain) {
+
+ try {
+ // System.out.println(" num " + index);
+ // System.out.println("Starting process <"+index+"> on <"
+ // +hostName+">");
+ method[index].invoke(null, new Object[] { argNew });
+ tryAgain = false;
+ // System.out.println("Stopping process <"+index+"> on <"
+ // +hostName+">");
+ }
+ catch (Exception e) {
+ // System.out.println("please try running the code again ..");
+ e.printStackTrace();
+ tryAgain = false;
+ System.exit(0);
+ // tryAgain = true;
+ // System.out.println(" exception while invoking in " +
+ // Thread.currentThread());
+ // goto TRY_AGAIN ;
+ // This should not happen, as we have disabled access checks
+ }
+ }
+
+ }
+ };
+ }
+ // #######################################################
+ // /////////////// cutted
+
+ try {
+
+ int nprocs = processes;
+
+ Thread procs[] = new Thread[nprocs];
+ // System.out.println("nprocs " + nprocs);
+ // FIX ME By Rizwan & Amjad :
+ // setting all threads thred group to MPI${rank}.
+ // so that we can differeniate them from other threads i.e. system threads
+ for (num = 0; num < nprocs; num++) {
+
+ // procs[num] = new Thread(ab[num]);
+ // smpProcess[num] = new SMPDevProcess("smp-threadgroup"+num);
+ smpProcess[num] = new SMPDevProcess("MPI" + num);
+ procs[num] = new Thread(smpProcess[num], ab[num], "" + nprocs);
+ String name = String.valueOf(num);
+ procs[num].setName(name);
+ procs[num].start();
+
+ // System.out.println("thread after start" + num+" Thread "+
+ // Thread.currentThread()+" Time "+System.nanoTime());
+ // procs[num].join();
+ // Thread.currentThread().sleep(500);
+
+ }
+
+ for (int i = 0; i < nprocs; i++) {
+ procs[i].join();
+ }
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ } // end execute
+
+ public static void main(String args[]) throws Exception {
+ MulticoreStarter mstarter = new MulticoreStarter();
+ mstarter.execute(args);
+ } // end main
+
+ public static void visitAllDirs(File dir) {
+ if (dir.isDirectory()) {
+ appPath += dir + ":";
+
+ String[] children = dir.list();
+ for (int i = 0; i < children.length; i++) {
+ visitAllDirs(new File(dir, children[i]));
+ }
+ }
+ }
+
+}
diff --git a/src/xdev/Device.java b/src/xdev/Device.java
new file mode 100644
index 0000000..6095633
--- /dev/null
+++ b/src/xdev/Device.java
@@ -0,0 +1,270 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2007)
+ 3. Bryan Carpenter (2005 - 2007)
+ 4. Mark Baker (2005 - 2007)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : Device.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Mon Jan 24 09:44:40 BST 2005
+ * Revision : $Revision: 1.22 $
+ * Updated : $Date: 2005/12/21 13:18:17 $
+ */
+package xdev;
+
+import java.util.UUID ;
+import mpjbuf.BufferFactory ;
+
+/**
+ * <p>
+ * <i> xdev </i> is an abstract class representing an abstract device.
+ * The implementations of this abstract
+ * class would provide various different communication protocols that can
+ * be used by MPJ at the higher-levels. The aim is to allow, flexible swapping
+ * of communication protocols, and also to keep the API simple and small, thus
+ * minimizing the overall development time of the device.
+ * </p>
+ * <p>
+ * Instead of using integer ranks as arguments to send/recv, <i> xdev </i> uses
+ * {@link xdev.ProcessID xdev.ProcessID} as arguments to send/recv.
+ * This essentially means that
+ * xdev doesnot deal with the higher level abstractions of MPI, like
+ * groups, communicators, and contexts -- it only focuses on providing
+ * communication methods, on top of which these higher abstractions of
+ * MPI can be implemented.
+ * </p>
+ */
+public interface Device {
+
+ /**
+ * A wild-card that can be used with the recv methods.
+ */
+ public static final int ANY_SOURCE = -2;
+
+ //public String deviceName ;
+
+ /**
+ * A wild-card for ANY_SOURCE at xdev level. It is a {@link xdev.ProcessID
+ * xdev.ProcessID} object with UUID set to random UUID , and rank set to
+ * ANY_SRC (-2)
+ */
+ public static ProcessID ANY_SRC = new ProcessID(UUID.randomUUID());
+
+ /**
+ * A wild-card that can be used with the recv method to receive the
+ * message from any source within the communicator.
+ */
+ public static final int ANY_TAG = -2;
+
+ /**
+ * This method returns an instance of xdev specified by the argument.
+ * In future, this method may search the classpath to load the
+ * libraries for the appropriate device to use and returns an
+ * instance of that device.
+ * @param dev The name of the xdev Device. The one for Java New I/O is
+ * named 'niodev'. The name of the device is provided to xdev
+ * by MPJ runtime, which in turn gets it from 'mpjrun' script.
+ * @return Device An instance of an implementation of the device.
+ * @throws XDevException If there is no corresponding device to the string
+ * argument provided to this method
+ *
+ public static Device newInstance(String dev) throws XDevException {
+ Device device = null;
+
+ if (dev.equals("niodev")) {
+ device = new xdev.niodev.NIODevice();
+ }
+ else if(dev.equals("mxdev")) {
+ device = new xdev.mxdev.MXDevice();
+ }
+ else {
+ throw new XDevException("No matching device found for <"+dev+">");
+ }
+
+ return device;
+ }
+ */
+
+ /**
+ * Initialize the xdev device. Specific implementations perform
+ * initialization of the device in this method.
+ * @param args Argument array.
+ * @return xdev.ProcessID[] An array with length equal to total number
+ * of processes, and each ProcessID element representing a process.
+ * @throws XDevException If there is an error initializing the device
+ */
+ public abstract ProcessID[] init(String[] args) throws XDevException;
+
+ /*
+ * Get send message over head ...
+ */
+ public abstract int getSendOverhead() ;
+
+ /*
+ * Get recv message over head ...
+ */
+ public abstract int getRecvOverhead() ;
+
+ /**
+ * This method returns the id of the current process
+ * @return xdev.ProcessID ProcessID of the current process.
+ */
+ public abstract ProcessID id();
+
+ /**
+ * This method shutdowns the device.
+ */
+ public abstract void finish() throws XDevException;
+
+ /**
+ * This method is the non-blocking send using standard-mode.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param destID {@link xdev.ProcessID ProcessID} of the destination process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @return mpjdev.Request Request object that can be used to check the status
+ * and/or progress of the communication.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context)
+ throws XDevException;
+
+ /**
+ * This method is the blocking send using standard-mode.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param destID {@link xdev.ProcessID ProcessID} of the destination process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract void send(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws XDevException;
+
+ /**
+ * This method is the non-blocking send using synchronous-mode.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param destID {@link xdev.ProcessID ProcessID} of the destination process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @return mpjdev.Request Request object that can be used to check the status
+ * and/or progress of the communication.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Request issend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context)
+ throws XDevException;
+
+ /**
+ * This method is the blocking send using synchronous-mode.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param destID {@link xdev.ProcessID ProcessID} of the destination process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract void ssend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws XDevException;
+
+ /**
+ * This method is the blocking recv.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param srcID {@link xdev.ProcessID ProcessID} of the source process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @return mpjdev.Status Status object that can be used to check the status
+ * of the communication.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context)
+ throws XDevException;
+
+ /**
+ * This method is the non-blocking recv.
+ * @param buf {@link mpjbuf.Buffer mpjbuf.Buffer} object containing the data
+ * @param srcID {@link xdev.ProcessID ProcessID} of the source process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @param status A {@link mpjdev.Status mpjdev.Status} object initialized
+ * at mpjdev/MPJ level.
+ * @return mpjdev.Request Request object that can be used to check the status
+ * of the communication.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Request irecv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context,
+ mpjdev.Status status)
+ throws XDevException;
+
+ /**
+ * This method is the blocking probe.
+ * @param srcID {@link xdev.ProcessID ProcessID} of the source process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @return mpjdev.Status Status object that can be used to check the status
+ * of the communication.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Status probe(ProcessID srcID, int tag,
+ int context) throws XDevException;
+
+ /**
+ * This method is the non-blocking probe.
+ * @param srcID {@link xdev.ProcessID ProcessID} of the source process
+ * @param tag An integer representing the tag (id) of the message
+ * @param context An integer specifying context.
+ * @return mpjdev.Status Status object if the communication has completed or
+ * null otherwise.
+ * @throws XDevException If there is an exception. The specific exception
+ * depends on the device.
+ */
+ public abstract mpjdev.Status iprobe(ProcessID srcID, int tag,
+ int context) throws XDevException;
+
+ /**
+ * This method is sam as iprobe method but added to facilitate
+ * Hybrid device, only difference is destination Process id is added.
+ * In Hybrid Device we may not know Destination ProcessID
+ * while multiple processes are running on destination host
+ */
+ public abstract mpjdev.Status iprobe(ProcessID srcID, ProcessID dstID,
+ int tag, int context) throws XDevException;
+
+ public abstract mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID,
+ int tag, int context, mpjbuf.Buffer buf ) throws XDevException;
+
+ public abstract mpjdev.Request peek() throws XDevException;
+
+}
diff --git a/src/xdev/ProcessID.java b/src/xdev/ProcessID.java
new file mode 100644
index 0000000..2121f61
--- /dev/null
+++ b/src/xdev/ProcessID.java
@@ -0,0 +1,104 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2007)
+ 3. Bryan Carpenter (2005 - 2007)
+ 4. Mark Baker (2005 - 2007)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : ProcessID.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Mon Jan 24 09:44:40 BST 2005
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/11/27 19:40:12 $
+ */
+package xdev;
+
+import java.util.UUID;
+
+/**
+ * At <i> xdev </i> level, each MPI process is identified by an instance of
+ * this class. The MPJ Device level ( <i> mpjdev </i> maps these ProcessIDs
+ * to ranks.
+ */
+public class ProcessID {
+
+ UUID uuid;
+ //int rank;
+
+ protected ProcessID() {
+ }
+
+ /**
+ * Constructor to create an object of ProcessID
+ * @param uuid UUID of the process
+ * @param rank Rank of the process
+ public ProcessID(UUID uuid, int rank) {
+ this.uuid = uuid;
+ this.rank = rank;
+ }
+ */
+
+ /**
+ * Constructor to create an object of ProcessID
+ * @param uuid UUID of the process
+ */
+ public ProcessID(UUID uuid) {
+ this.uuid = uuid;
+ }
+
+ /**
+ * Sets UUID of this ProcessID object
+ * @param uuid UUID of the process
+ */
+ public void uuid(UUID uuid) {
+ this.uuid = uuid;
+ }
+
+ /**
+ * Sets UUID of this ProcessID object
+ */
+ public UUID uuid() {
+ return this.uuid;
+ }
+
+ /**
+ * Sets rank of this ProcessID object
+ * @param rank Rank of the process
+ public void rank(int rank) {
+ this.rank = rank;
+ }
+ */
+
+ /**
+ * Gets rank of this ProcessID object
+ * @return int Rank of the process
+ public int rank() {
+ return this.rank;
+ }
+ */
+
+}
+
diff --git a/src/xdev/XDevException.java b/src/xdev/XDevException.java
new file mode 100755
index 0000000..2806307
--- /dev/null
+++ b/src/xdev/XDevException.java
@@ -0,0 +1,58 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2007)
+ 3. Bryan Carpenter (2005 - 2007)
+ 4. Mark Baker (2005 - 2007)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package xdev;
+
+/*
+ * File : XDevException.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Wed Jun 22 11:13:42 BST 2005
+ * Revision : $Revision: 1.3 $
+ * Updated : $Date: 2005/07/29 14:03:10 $
+ */
+
+/**
+ * XDevException class
+ * @author Aamir Shafi
+ */
+public class XDevException
+ extends RuntimeException {
+
+ public XDevException() {
+ super();
+ }
+
+ public XDevException(String msg) {
+ super(msg);
+ }
+
+ public XDevException(Throwable cause){
+ super(cause);
+ }
+}
diff --git a/src/xdev/hybdev/HYBDevice.java b/src/xdev/hybdev/HYBDevice.java
new file mode 100644
index 0000000..4715aa3
--- /dev/null
+++ b/src/xdev/hybdev/HYBDevice.java
@@ -0,0 +1,1092 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 20013
+ 1. SEECS National University of Sciences and Technology
+ 2. Aamir Shafi (2005 - 2013)
+ 3. Ansar Javed (2013 - 2013)
+ 4. Mohsan Jameel (2013 - 2013)
+ 5. Bibrak Qamar (2013 - 2013)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : HYBDevice.java
+ * Author : Aamir Shafi, Mohsan Jameel, Ansar Javed, Bibrak Qamar
+ * Created : Mon Aug 5 12:22:15 PKT 2013
+ * Revision : $Revision: 1.28 $
+ * Updated : $Date: 2013/12/17 17:24:47 $
+ *
+ */
+
+package xdev.hybdev;
+
+import java.lang.*;
+import java.net.*;
+import java.util.*;
+import mpjbuf.*;
+import mpjdev.*;
+import xdev.*;
+import xdev.smpdev.*;
+
+import org.apache.log4j.Logger;
+
+
+
+public class HYBDevice implements Device {
+
+
+ class WildcardMessageManager implements Runnable {
+
+ HYBRecvRequest recvRequest ;
+
+ WildcardMessageManager (HYBRecvRequest recvReq) {
+ this.recvRequest = recvReq ;
+ }
+ public void run () {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Host:"+localHostName+" WildcardMessageManager thread is starting ");
+ }
+ String localHostName=null;
+ mpjdev.Status sts = null;
+ try {
+ InetAddress localaddr = InetAddress.getLocalHost();
+ localHostName= localaddr.getHostName();
+ }
+ catch (UnknownHostException unkhe) {
+ throw new XDevException(unkhe);
+ }
+
+ ProcessID srcID = new ProcessID ( recvRequest.srcUUID) ;
+ ProcessID dstID = new ProcessID ( recvRequest.dstUUID) ;
+
+ while (true){
+
+ sts = nioHybDev.iprobeAndFetch(srcID, dstID, recvRequest.tag,
+ recvRequest.context, recvRequest.buffer ) ;
+
+ if (sts!=null){
+ recvRequest.srcUUID = sts.srcID;
+ recvRequest.tag = sts.tag;
+ recvRequest.numEls = sts.numEls;
+ recvRequest.type = sts.type;
+
+
+ recvRequest.setCompleted(true);
+
+ recvRequest.notifyMe();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Host:"+localHostName+" ANY_SRC message Recvd from network");
+ }
+
+ break;
+ }
+ // System.out.println (" hybdev: incomplete Request in niodev, calling smpdev ");
+ sts = smpHybDev.iprobeAndFetch(srcID, dstID, recvRequest.tag,
+ recvRequest.context, recvRequest.buffer ) ;
+
+ if (sts!=null){
+ recvRequest.srcUUID = sts.srcID;
+ recvRequest.tag = sts.tag;
+ recvRequest.numEls = sts.numEls;
+ recvRequest.type = sts.type;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Host:"+localHostName+" ANY_SRC Recvd from smpdev ");
+ }
+
+ recvRequest.setCompleted(true);
+
+ recvRequest.notifyMe();
+
+ break;
+ }
+ try{
+ Thread.currentThread().sleep(2000);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+
+ }
+
+ }
+ }
+
+
+ // SMP processes in the currenet node
+ static int smpProcs = -1;
+ // overall processes in cluster i.e. np
+ static int nProcs = -1;
+ // NIO processes in the cluster
+ static int nioProcs = -1;
+ // NIO Rank of process
+ static int netID = -1;
+// private static boolean isOnceInitialized = false;
+
+ private static int SMP_INITIALIZED_COUNT = 0;
+ //private static long packUuids[] = null;
+ private static ProcessID[] allPids = null;
+ public static boolean allPidsInitialized = false;
+ // Hashtable of uuid to NetID mapping
+ private static Hashtable<UUID, Integer> uuidToNetID = null;
+ // used for finish
+ private static int numRegisteredThreads ;
+ private static Object lock = new Object() ;
+
+ // nioHybDev instance
+ public static Device nioHybDev = null;
+ private static boolean nioInitialized = false;
+ private static ProcessID[] Npids = null;
+
+ // smpHybDev instance
+ private Device smpHybDev = null;
+ private int SMPID=-1; // SMPID is Rank of SMP Thread
+
+
+ //NIO device overhead is 49, it is used as starting point to write
+ // Hybrid Device related information in the buffer.
+ static final int NET_SEND_OVERHEAD = 49;
+ static int SEND_OVERHEAD = 81;
+
+ // for Hybrid Dev Recv overhead
+ static final int RECV_OVERHEAD = 0;
+
+ // sending two UUID (sender & receiver) in Long values
+ static final int HYB_SEND_OVERHEAD = 32;
+
+ static Logger logger = Logger.getLogger("mpj");
+ static String localHostName = null;
+ private final int longLength = 8 ;
+
+ /**
+ * Initializes hybdev.
+ *
+ * @param args
+ * Arguments to HYBDevice.
+ * @return ProcessID[] An array of ProcessIDs.
+ */
+ public ProcessID[] init(String args[]) throws XDevException {
+
+
+ /*
+ * The init method does the following tasks
+ * 1. Initializes an NIO device Instance that is shared among SMP processes
+ * 2. Initializes SMP device Instance
+ * 3. development of Global Process ID array that will be returned to MPJDev.
+ * a. Process netID 0 & SMPID 0 acts as global root and SMPID 0 acts
+ * as local root at each node.
+ * b. Global root receives Local SMP ProcessID table from roots at all
+ * nodes and merge them to make a global process table.
+ * c. Global process table is then communicated to local roots at all nodes.
+ */
+
+ /*
+ * Args usage is
+ * Args[0] = SMPID
+ * Args[1] = SMP Threads on current node
+ * Args[2] = hybdev
+ * Args[3] = total process for job, np
+ * Args[4] = Total NIO process to be used
+ * Args[5] = NIO Rank of Host
+ * Args[6] = NIO Config file path
+ * Args[7] = niodev
+ * */
+
+ xdev.niodev.NIODevice.isHybrid = true;
+ smpHybDev=nioHybDev = null ; //just to make sure device is clean if repeat init.
+ ProcessID[] Spids = null;
+ String SMPArgs[] = new String [3] ;
+
+ SMPID = Integer.parseInt(args[0]); // It contains rank of SMP thread
+
+ try {
+ localHostName = InetAddress.getLocalHost().getHostName();
+ } catch (Exception e) {
+ e.printStackTrace() ;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("--init method of hybdev is called--");
+ logger.info("Name :" + localHostName);
+ logger.info("net rank :" + netID);
+ logger.info("smp rank :" + SMPID);
+ }
+
+ synchronized (lock) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.init(), acquired Init lock, my rank "+myGid() ) ;
+ }
+
+ numRegisteredThreads++;
+
+ if (numRegisteredThreads == Integer.parseInt(args[1]) ) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.Init(), Preparing data for Init() " );
+ }
+
+ // total SMP thread on current host
+ smpProcs = Integer.parseInt(args[1]);
+ // overall processes in cluster i.e. np
+ nProcs = Integer.parseInt(args[3]);
+ // NIO processes in the cluster
+ nioProcs = Integer.parseInt(args[4]);
+ // NIO Rank of process
+ netID = Integer.parseInt(args[5]);
+
+ allPids = new ProcessID[nProcs];
+ uuidToNetID = new Hashtable<UUID, Integer>();
+
+ /* setting SMP overheads according to the overhead used for Network */
+ xdev.smpdev.SMPDevice.SEND_OVERHEAD = SEND_OVERHEAD;
+ xdev.smpdev.SMPDevice.RECV_OVERHEAD = RECV_OVERHEAD;
+
+
+ String niostr [] = new String[3];
+ for (int i = 0; i < niostr.length; i++) {
+ niostr[i] = args[5 + i];
+ }
+
+ nioHybDev = new xdev.niodev.NIODevice();
+ Npids = nioHybDev.init(niostr);
+
+ numRegisteredThreads = 0 ;
+
+ lock.notifyAll();
+
+ } else {
+ try {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Host:"+localHostName+" SMPID "+SMPID+" putting itself to wait for NIO Init ");
+ }
+ lock.wait();
+ } catch (InterruptedException e) {
+ throw new XDevException("In HYBDevice.Init(), unexpected "
+ + "interuption during wait()??");
+ } catch (IllegalMonitorStateException ex) {
+ ex.printStackTrace();
+ throw new XDevException(
+ "HYBDevice.init(), IllegalMonitorStateException during wait()");
+ }
+ }
+ }
+
+ long splittedUuids[] = new long [nProcs * 2];
+
+ for (int i = 0; i < 3; i++) {
+ SMPArgs[i] = args[i];
+ }
+
+ smpHybDev = new xdev.smpdev.SMPDevice();
+ Spids = smpHybDev.init(SMPArgs);
+
+ /* root Receiving in loop from root processes of each node */
+ try {
+ if (netID == 0 && SMPID == 0) {
+ int procPerHost[] = getProcPerHost();
+ int offset[] = new int[nioProcs];
+
+ offset[0] = 0;
+ for (int i = 1; i < nioProcs; i++) {
+ offset[i] = offset[i - 1] + (procPerHost[i - 1] * 2);
+
+ }
+
+
+ ProcessID temppid = null;
+ UUID temp = null;
+ int n = 0;
+ for (int i = 0; i < Spids.length; i++) {
+ temp = Spids[i].uuid();
+ splittedUuids[n] = temp.getMostSignificantBits();
+ n++;
+ splittedUuids[n] = temp.getLeastSignificantBits();
+ n++;
+ }
+
+ mpjdev.Status status = new mpjdev.Status();
+ Type sectionHeader = null;
+ // Receiving in loop
+ for (int i = 1; i < nioProcs; i++) {
+ int bufSize = -1;
+ // multiplying by 2 because each UUID consists of 2 long numbers
+ int recvOverhead = nioHybDev.getRecvOverhead();
+ int sectionSize = 0;
+ bufSize = procPerHost[i] * 2 * longLength;
+ RawBuffer rawBuffer = BufferFactory.create(bufSize);
+ mpjbuf.Buffer recvBuf = new mpjbuf.Buffer(rawBuffer, recvOverhead,
+ recvOverhead + bufSize);
+
+ //updateBuffer(buf, id(), dstID, NET_SEND_OVERHEAD, SEND_OVERHEAD);
+ updateBuffer(recvBuf, Npids[i], Npids[0], 0, HYB_SEND_OVERHEAD);
+ try {
+ recvBuf.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ //setting a random tag & context to send & recv a message
+ status = nioHybDev.recv(recvBuf, Npids[i], 10, 100);
+
+ recvBuf.commit();
+ sectionHeader = recvBuf.getSectionHeader();
+ sectionSize = recvBuf.getSectionSize();
+
+ recvBuf.read(splittedUuids, offset[i], procPerHost[i] * 2);
+ recvBuf.clear();
+ BufferFactory.destroy(rawBuffer);
+ }
+
+ n = 0;
+
+ /*
+ * Global root received process tables from each node level root and
+ * then making a global ProcessID array.
+ */
+ for (int i = 0; i < splittedUuids.length; i += 2) {
+ temp = new UUID(splittedUuids[i], splittedUuids[i + 1]);
+ allPids[n] = new ProcessID(temp);
+ n++;
+ }
+
+ /* Sending global ProcessID array to all node level root processes */
+
+ int bcastBufSize = (splittedUuids.length) * longLength + SEND_OVERHEAD;
+ RawBuffer bcastSendRawBuffer = BufferFactory.create(bcastBufSize);
+ mpjbuf.Buffer bcastSendBuffer = new mpjbuf.Buffer(bcastSendRawBuffer,
+ SEND_OVERHEAD, bcastBufSize);
+
+ for (int i = 1; i < nioProcs; i++) {
+ bcastSendBuffer.putSectionHeader(Type.LONG);
+ bcastSendBuffer.write(splittedUuids, 0, splittedUuids.length);
+ bcastSendBuffer.commit();
+
+ updateBuffer(bcastSendBuffer, Npids[0], Npids[i], NET_SEND_OVERHEAD, SEND_OVERHEAD);
+
+ nioHybDev.send(bcastSendBuffer, Npids[i], 100, 1000);
+
+ bcastSendBuffer.clear();
+ }
+ BufferFactory.destroy(bcastSendRawBuffer);
+
+ }
+ /*
+ * 1. sending current hostuuids to global root.
+ * Then receiving complete uuid list form root
+ */
+ else if (netID != 0 && SMPID == 0) {
+ int sendBufSize = (smpProcs * 2 * longLength) + SEND_OVERHEAD;
+
+ RawBuffer sendRawBuffer = BufferFactory.create(sendBufSize);
+
+ mpjbuf.Buffer sendBufByAll = new mpjbuf.Buffer(sendRawBuffer,
+ SEND_OVERHEAD, sendBufSize);
+
+ sendBufByAll.putSectionHeader(Type.LONG);
+
+ long packUuids [] = new long[smpProcs * 2];
+
+ long msb, lsb;
+ UUID myuuid;
+ int n = 0;
+ // to pack uuids of smpids into long array
+ for (int i = 0; i < smpProcs; i++) {
+ myuuid = Spids[i].uuid();
+ msb = myuuid.getMostSignificantBits();
+ lsb = myuuid.getLeastSignificantBits();
+ packUuids[n] = msb;
+ n++;
+ packUuids[n] = lsb;
+ n++;
+ }
+
+ sendBufByAll.write(packUuids, 0, packUuids.length);
+
+ sendBufByAll.commit();
+
+ updateBuffer(sendBufByAll, Npids[netID], Npids[0], NET_SEND_OVERHEAD, SEND_OVERHEAD) ;
+ //tag and context are decided at random
+ nioHybDev.send(sendBufByAll, Npids[0], 10, 100); // sending to root
+
+ BufferFactory.destroy(sendRawBuffer);
+
+ // Receiving from root
+ mpjdev.Status status = null;
+ Type sectionHeader = null;
+
+ int bufSizeFromRoot = (splittedUuids.length * longLength)+RECV_OVERHEAD;
+
+ RawBuffer rawBufferFromRoot = BufferFactory.create(bufSizeFromRoot);
+
+ mpjbuf.Buffer recvBufFromRoot = new mpjbuf.Buffer(rawBufferFromRoot,
+ RECV_OVERHEAD, bufSizeFromRoot);
+
+ updateBuffer(recvBufFromRoot, Npids[0], Npids[netID], 0, HYB_SEND_OVERHEAD );
+ status = nioHybDev.recv(recvBufFromRoot, Npids[0], 100, 1000);
+
+ recvBufFromRoot.commit();
+ sectionHeader = recvBufFromRoot.getSectionHeader();
+
+ recvBufFromRoot.read(splittedUuids, 0, splittedUuids.length);
+ recvBufFromRoot.clear();
+
+ BufferFactory.destroy(rawBufferFromRoot);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" HYB.init(), Receieved all from root by rank"+netID );
+ }
+
+ n = 0;
+ UUID temp = null;
+
+ for (int i = 0; i < splittedUuids.length; i += 2) {
+ temp = new UUID(splittedUuids[i], splittedUuids[i + 1]);
+ allPids[n] = new ProcessID(temp);
+ // System.out.println (" Rank "+n+" : "+allPids[n].uuid() ) ;
+ n++;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" HYB.init(), all hosts have complete pids");
+ }
+ // System.out.println (" all hosts have complete pids");
+
+ }
+ } catch (BufferException e) {
+ e.printStackTrace();
+ }
+
+ // fill hosttable on each node
+ if (SMPID == 0) {
+ fillUuidToNetID();
+ allPidsInitialized = true;
+ }
+
+ // make hashtable of (uuid, netID)
+ int procPerHost[] = getProcPerHost();
+
+ synchronized (uuidToNetID) {
+ SMP_INITIALIZED_COUNT++;
+ if (SMP_INITIALIZED_COUNT == smpProcs && allPidsInitialized == true) {
+ uuidToNetID.notifyAll();
+ } else {
+ try {
+ uuidToNetID.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ throw new XDevException(
+ "HYBDevice.init(), unexpected interruption during wait()");
+ } catch (IllegalMonitorStateException ex) {
+ ex.printStackTrace();
+ throw new XDevException(
+ "HYBDevice.init(), IllegalMonitorStateException during wait()");
+ }
+ }
+ }
+
+ return allPids; // Global Pids
+
+ }
+
+ public void cleanUp(){
+ uuidToNetID=null;
+ allPids=Npids=null;
+ nioProcs=nProcs=netID=smpProcs=-1;
+ allPidsInitialized = nioInitialized = false;
+ SMP_INITIALIZED_COUNT= numRegisteredThreads =0;
+
+ }
+ /*
+ * Fill HashTable for UUID to NetID transation. Hashtable returns netID of a
+ * given UUID.
+ */
+ public void fillUuidToNetID() {
+ int processesPerHost[] = getProcPerHost();
+ int n = 0;
+ for (int i = 0; i < nioProcs; i++) {
+ for (int j = 0; j < processesPerHost[i]; j++) {
+ uuidToNetID.put(allPids[n].uuid(), i);
+ //System.out.println( localHostName+ " UUID "+allPids[n].uuid()+" NetID "+i) ;
+ n++;
+ }
+ }
+ }
+
+ /* it returns the Global Rank of calling process */
+ public int myGid() {
+ // get GID starting rank for each node then add SMPID id (local smp rank)
+ int gid = SMPID + startRank();
+ return gid;
+ }
+
+ // get starting of Global rank of the SMP prcesses running at current host
+ public int startRank() {
+ int strRank = -1;
+ int perHost = nProcs / nioProcs;
+ if (netID < (nProcs % nioProcs)) {
+ perHost++;
+ strRank = netID * perHost;
+ } else {
+ strRank = (netID * perHost) + (nProcs % nioProcs);
+ }
+ return strRank;
+ }
+
+ /*
+ * This methods gives the number of processes running the each host of the
+ * cluster, It is replica implementation of runtime where it is decided that
+ * how many processes should be launchged at one host
+ */
+ public int[] getProcPerHost() {
+ int counts[] = new int[nioProcs];
+
+ for (int i = 0; i < nioProcs; i++) {
+ counts[i] = nProcs / nioProcs;
+ }
+ int rem = nProcs % nioProcs;
+ for (int j = 0; j < rem; j++) {
+ counts[j] = counts[j] + 1;
+ }
+ return counts;
+ }
+
+
+
+ /* It returns true if both source and destination are on same node
+ * and returns false if both source and destination are not on same node
+ */
+ public static boolean isLocal(ProcessID id) {
+ boolean local = false;
+ //System.out.println(" islocal.uuid "+id.uuid() );
+ int myNetId = uuidToNetID.get(id.uuid());
+ if (myNetId == netID) {
+ local = true;
+ }
+ return local;
+ }
+
+ /*
+ * It is used to get network ProcessID of any SMP process
+ */
+ public ProcessID getNetworkPid(ProcessID id) {
+ int myNetId = uuidToNetID.get(id.uuid());
+ return Npids[myNetId];
+ }
+
+ /*
+ * It populates buffer with source ProcessID, destination ProcessID,
+ * Data is written from startPosition to endPosition
+ */
+ public void updateBuffer(mpjbuf.Buffer buf, ProcessID srcID, ProcessID dstID,
+ int startPos, int endPos) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Setting start position to write in buffer: "+startPos);
+ }
+
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(startPos);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Setting the limmit to write in buffer: "+endPos);
+ }
+
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(endPos);
+
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Adding Source Information in Buffer, Source MSB: "+
+ srcID.uuid().getMostSignificantBits()+" Source LSB: "+
+ srcID.uuid().getLeastSignificantBits() );
+ }
+ // adding source ID information
+ // System.out.println("Src msb: "+srcID.uuid().getMostSignificantBits()) ;
+ // System.out.println("Src lsb: "+srcID.uuid().getLeastSignificantBits()) ;
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().putLong(
+ srcID.uuid().getMostSignificantBits());
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().putLong(
+ srcID.uuid().getLeastSignificantBits());
+
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Adding Destination Information in Buffer, Destination MSB: "+
+ dstID.uuid().getMostSignificantBits()+" Destination LSB: "+
+ dstID.uuid().getLeastSignificantBits() );
+ }
+
+ // adding destination ID information
+ // System.out.println("Dst msb: "+dstID.uuid().getMostSignificantBits()) ;
+ // System.out.println("Dst lsb: "+dstID.uuid().getLeastSignificantBits()) ;
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().putLong(
+ dstID.uuid().getMostSignificantBits());
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().putLong(
+ dstID.uuid().getLeastSignificantBits());
+ }
+
+ /**
+ * Returns the id of this process.
+ *
+ * @return ProcessID An object containing UUID of the process,
+ * UUID value will be that of current SMP process
+ */
+ public ProcessID id() {
+ return xdev.smpdev.SMPDeviceImpl.WORLD.id();
+ }
+
+
+ /* it returns Send Overhead of Hybrid Device */
+ public int getSendOverhead() {
+ return SEND_OVERHEAD;
+ }
+
+ /* it returns Receive Overhead of Hybrid Device */
+ public int getRecvOverhead() {
+ return RECV_OVERHEAD;
+ }
+
+
+ /**
+ * Blocking send method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer object containing the data.
+ * @param dstID
+ * ProcessID of the destination
+ * @param tag
+ * The unique identifier of the message
+ * @param context
+ * An integer providing "safe universe" for messages.
+ * @throws MPJException
+ * If the buffer is null, dest process ID is insane.
+ * @throws java.nio.BufferOverflowException
+ * @throws ReadOnlyBufferException
+ * @throws IOException
+ * If some I/O error occurs
+ */
+ public void send(mpjbuf.Buffer buf, ProcessID dstID, int tag, int context)
+ throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.send, calling isend method");
+ }
+ mpjdev.Request req = isend(buf, dstID, tag, context);
+ req.iwait();
+ }
+
+
+ /**
+ * Non-blocking send method
+ *
+ * @param buf
+ * The mpjbuf.Buffer object containing the data.
+ * @param dstID
+ * ProcessID of the destination process.
+ * @param tag
+ * The unique identifier of the message.
+ * @param context
+ * An integer providing "safe universe" for messages.
+ * @return mpjdev.Request The Request object, which is later used to check the
+ * status of the message.
+ */
+ public mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context) throws XDevException {
+ if (isLocal(dstID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.isend, using SMPDevice \n Source:"+id().uuid()+
+ " \n Destination:"+dstID.uuid()+" \n tag: "+tag+" \n Context: "+context);
+ }
+ // System.out.println(" HYB.Isend, using SMP => Src:"+id().uuid()+
+ // " Dst:"+dstID.uuid()+" tag: "+tag+" Context: "+context );
+
+ return smpHybDev.isend(buf, dstID, tag, context);
+
+ } else {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.isend, using NIODevice \n Source:"+id().uuid()+
+ " \n Destination:"+dstID.uuid()+" \n tag: "+tag+" \n Context: "+context);
+ }
+ // System.out.println(" HYB.Isend, using NIO => Src:"+id().uuid()+
+ // " Dst:"+dstID.uuid()+" tag: "+tag+" Context: "+context );
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.isend, calling updateBuffer method");
+ }
+ updateBuffer(buf, id(), dstID, NET_SEND_OVERHEAD, SEND_OVERHEAD);
+
+ mpjdev.Request req = nioHybDev.isend(buf, getNetworkPid(dstID), tag,
+ context);
+ return req;
+ }
+ }
+
+ /**
+ * This method is the blocking recv method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer object where the user wishes to receive the
+ * actual message
+ * @param srcID
+ * The process id of the sending process
+ * @param tag
+ * The unique identifier of the message
+ * @return Status The status object containing the details of recv
+ * @throws MPJException
+ * If the buffer is null or the src is insane
+ * @throws IOException
+ * If some I/O error occurs
+ * @throws java.lang.IllegalArgumentException
+ */
+ public mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context) throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.recv, using NIODevice \n Source:"+srcID.uuid()+
+ " \n Destination:"+id().uuid()+
+ " \n tag: "+tag+" \n Context: "+context);
+ }
+
+ //System.out.println("HYB.recv, using NIODevice \n Source:"+srcID.uuid()+
+ // " \n Destination:"+id().uuid().uuid()+
+ // " \n tag: "+tag+" \n Context: "+context);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.recv, Posting irecv call") ;
+ }
+ mpjdev.Status status = new mpjdev.Status(srcID.uuid(), tag, -1);
+
+ mpjdev.Request request = irecv(buf, srcID, tag, context, status);
+
+ status = request.iwait();
+
+ return status;
+ }
+
+
+ /**
+ * Non-Blocking receive method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer objereceive the actual message
+ * @param srcID
+ * The process id of the sending process
+ * @param tag
+ * The unique identifier of the message
+ * @param context
+ * An integer that provides "safe communication" universe
+ * @return mpjdev.Status The status object containing the details of recv
+ */
+ public mpjdev.Request irecv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context, mpjdev.Status status) throws XDevException {
+
+
+ //This code will execute if message is a for ANY_SOURCE
+ if(srcID.uuid().equals(Device.ANY_SRC.uuid() ) ) {
+
+ updateBuffer(buf, srcID, id(), 0, HYB_SEND_OVERHEAD);
+ try {
+ buf.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ HYBRecvRequest recvRequest = new HYBRecvRequest ( srcID, id(), tag,
+ context, buf, false ) ;
+
+ WildcardMessageManager recvThread = new WildcardMessageManager(recvRequest) ;
+ new Thread (recvThread).start() ;
+
+ return recvRequest;
+ }
+ else if (isLocal(srcID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.irecv, using SMPDevice \n Source:"+srcID.uuid()+
+ " \n Destination:"+id().uuid()+" \n tag: "+tag+" \n Context: "+context);
+ }
+ // System.out.println(" HYB.Irecv, using SMP: Src:"+srcID.uuid()+
+ // " Dst:"+id().uuid()+" tag: "+tag+" Context: "+context );
+
+ return smpHybDev.irecv(buf, srcID, tag, context, status);
+
+ }
+ else {
+ /*
+ * For posting irecv on Network device we need to use
+ * network address of destination, so we need to add details of Hybrid
+ * (original) source and destination into buffer,
+ * buffer is read and cleared in Network device irecv method to retrieve
+ * orignal source and destination.
+ * Same buffer reused to keep received data.
+ */
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.irecv, using NIODevice \n Source:"+srcID.uuid()+
+ " \n Destination:"+id().uuid()+" \n tag: "+tag+" \n Context: "+context);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.irecv, calling updateBuffer method" ) ;
+ }
+
+ //System.out.println(" Calling update Buffer for irecv") ;
+
+ updateBuffer(buf, srcID, id(), 0, HYB_SEND_OVERHEAD);
+
+ try {
+ buf.commit();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // System.out.println(" HYB.Irecv, using NIO: Src:"+srcID.uuid()+
+ // " Dst:"+id().uuid()+" tag:"+tag+" Context:"+context );
+
+ mpjdev.Request req = nioHybDev.irecv(buf, getNetworkPid(srcID), tag,
+ context, status);
+
+ return req;
+ }
+ }
+
+
+ /**
+ * Blocking synchronous send.
+ */
+ public void ssend(mpjbuf.Buffer buf, ProcessID dstID, int tag, int context)
+ throws XDevException {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.ssend, posting issend method call ");
+ }
+ mpjdev.Request req = issend(buf, dstID, tag, context);
+ req.iwait();
+ }
+
+
+ /**
+ * Non-blocking synchronous send.
+ */
+ public mpjdev.Request issend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context) throws XDevException {
+
+ if (isLocal(dstID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.issend, using SMPDevice \n Source:" + id().uuid()
+ + " \n Destination:" + dstID.uuid() + " \n tag: " + tag
+ + " \n Context: " + context);
+ }
+ //System.out.println(" HYB.issend, using SMP => Src:"+id().uuid()+
+ //" Dst:"+dstID.uuid()+" tag: "+tag+" Context: "+context );
+
+ return smpHybDev.issend(buf, dstID, tag, context);
+
+ } else {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.issend, using NIODevice \n Source:" + id().uuid()
+ + " \n Destination:" + dstID.uuid() + " \n tag: " + tag
+ + " \n Context: " + context);
+ }
+ //System.out.println(" HYB.issend, using NIO => Src:"+id().uuid()+
+ //" Dst:"+dstID.uuid()+" tag: "+tag+" Context: "+context );
+
+ updateBuffer(buf, id(), dstID, NET_SEND_OVERHEAD, SEND_OVERHEAD);
+
+ return nioHybDev.issend(buf, getNetworkPid(dstID), tag, context);
+
+ }
+
+ }
+
+
+ /**
+ * Blocking probe method
+ *
+ * @param srcID
+ * The sourceID of the sender
+ * @param tag
+ * The tag of the message
+ * @param context
+ * The integer specifying the context
+ * @return mpjdev.Status The status object
+ */
+ public mpjdev.Status probe(ProcessID srcID, int tag, int context)
+ throws XDevException {
+ mpjdev.Status status = null;
+ boolean comp = false;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.probe, posting iprove method call");
+ }
+
+ while (!comp) {
+ status = this.iprobe(srcID, tag, context);
+ if (status != null) {
+ comp = true;
+ }
+ }
+ return status;
+ }
+
+ /**
+ * Non-Blocking probe method.
+ *
+ * @param srcID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobe(ProcessID srcID, int tag, int context)
+ throws XDevException {
+
+ if (isLocal(srcID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.iprobe, using SMPDevice \n Source:" + srcID.uuid()
+ + " \n Destination:" + id().uuid() + " \n tag: " + tag
+ + " \n Context: " + context);
+ }
+ // System.out.println(" HYB.iprobe, using SMP => Src:"+id().uuid()+"
+ // +" tag: "+tag+" Context: "+context );
+
+ return smpHybDev.iprobe(srcID, tag, context);
+ } else {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.issend, using NIODevice \n Source:" + srcID.uuid()
+ + " \n Destination:" + id().uuid() + " \n tag: " + tag
+ + " \n Context: " + context);
+ }
+ // calling overloaded iprobe method of NIO Device.
+ return nioHybDev.iprobe(srcID, id(), tag, context);
+ }
+
+ }
+
+
+ /**
+ * Non-Blocking overloaded probe method.
+ *
+ * @param srcID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobe(ProcessID srcID, ProcessID dstID, int tag,
+ int context) throws XDevException {
+ /*
+ * Its implementation is required in in rest of the devices being used
+ * whinin hybdev
+ */
+ return null;
+ }
+
+ /**
+ * Non-Blocking probe and fetch method.
+ *
+ * @param srcID
+ * @param dstID
+ * @param tag
+ * @param context
+ * @param buf
+ * The mpjbuf.Buffer objereceive the actual message
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID, int tag,
+ int context, mpjbuf.Buffer buf ) throws XDevException {
+ /*
+ * Its implementation is required in Network device only
+ * while working for Hybrid device
+ */
+ return null;
+ }
+
+
+ public mpjdev.Request peek() throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.peek, posting NIODevice.peek() method call,"
+ + " SMPDevice peek returns null");
+ }
+
+ return nioHybDev.peek();
+ }
+
+ /**
+ * This method shuts down the device.
+ *
+ * @throws MPJException
+ * @throws IOException
+ * If some I/O error occurs
+ */
+ public void finish() throws XDevException {
+ int myGRank = myGid();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug( myGid() + " HYB.finish(), acquiring finish lock, my rank") ;
+ }
+ smpHybDev.finish();
+ smpHybDev=null;
+
+
+ synchronized (lock) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.finish(), acquired NIO finish lock, my rank "+myGid() ) ;
+ }
+
+ numRegisteredThreads++;
+
+ if (numRegisteredThreads == smpProcs) {
+ xdev.niodev.NIODevice.isHybrid = false;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("HYB.finish(), posting NIODevice.finish(),rank "+myGid());
+ }
+
+ cleanUp();
+ SMPID=-1;
+
+ nioHybDev.finish();
+
+ nioHybDev=null;
+
+ lock.notifyAll();
+ } else {
+ try {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(myGid()+" putting itself to wait for NIO finish ");
+ }
+ SMPID=-1;
+ lock.wait();
+
+ } catch (InterruptedException e) {
+ throw new XDevException("In HYBDevice.finish(), unexpected "
+ + "interuption during wait()??");
+ } catch (IllegalMonitorStateException ex) {
+ ex.printStackTrace();
+ throw new XDevException(
+ "HYBDevice.finish(), IllegalMonitorStateException during wait()");
+ }
+ }
+ }
+ }
+}
diff --git a/src/xdev/hybdev/HYBRecvRequest.java b/src/xdev/hybdev/HYBRecvRequest.java
new file mode 100644
index 0000000..7224478
--- /dev/null
+++ b/src/xdev/hybdev/HYBRecvRequest.java
@@ -0,0 +1,105 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 20013
+ 1. SEECS National University of Sciences and Technology
+ 2. Aamir Shafi (2005 - 2013)
+ 3. Ansar Javed (2013 - 2013)
+ 4. Mohsan Jameel (2013 - 2013)
+ 5. Bibrak Qamar (2013 - 2013)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : HYBDevice.java
+ * Author : Aamir Shafi, Mohsan Jameel, Ansar Javed, Bibrak Qamar
+ * Created : Mon Aug 5 12:22:15 PKT 2013
+ * Revision : $Revision: 1.28 $
+ * Updated : $Date: 2013/12/17 17:24:47 $
+*/
+
+package xdev.hybdev;
+
+import java.util.UUID;
+import java.nio.channels.*;
+import java.nio.*;
+import mpjdev.*;
+import mpjbuf.NIOBuffer ;
+import xdev.*;
+
+public class HYBRecvRequest
+ extends HYBRequest {
+ long sequenceNum ;
+ int code = -1;
+ boolean readPending = false;
+ int bytesRead = 0;
+
+ HYBRecvRequest (ProcessID srcID, ProcessID dstID,
+ int tag, int context, mpjbuf.Buffer buf, boolean completed) {
+
+ this.srcUUID = srcID.uuid() ;
+ this.dstUUID = dstID.uuid() ;
+
+ this.tag = tag;
+ this.completed = completed;
+ this.staticBuffer = ((NIOBuffer)buf.getStaticBuffer()).getBuffer() ;
+ this.sBufSize = buf.getSize() ;
+ this.buffer = buf;
+
+ if(buf.getDynamicBuffer() != null && buf.getDynamicBuffer().length > 0) {
+ this.dynamicBuffer = buf.getDynamicBuffer() ;
+ this.dBufSize = buf.getDynamicBuffer().length ;
+ }
+
+ this.context = context ;
+ this.status = new mpjdev.Status(srcID.uuid(), tag, -1);
+
+ }
+
+ int commMode = 0;
+
+ int getCommMode() {
+ return commMode;
+ }
+
+ void setCommMode(int commMode) {
+ this.commMode = commMode;
+ }
+
+ public Status iwait() {
+ if(alreadyCompleted) {
+ return status ;
+ }
+ this.waitMe();
+
+ /* this should be probably be done somewhere at the start of irecv
+ * method */
+ status.tag = this.tag;
+ status.numEls = this.numEls;
+ status.type = this.type;
+ status.srcID = this.srcUUID;
+ System.out.println ();
+ complete(status);
+ this.alreadyCompleted = true ;
+ return status;
+ }
+
+}
diff --git a/src/xdev/hybdev/HYBRequest.java b/src/xdev/hybdev/HYBRequest.java
new file mode 100644
index 0000000..1c86630
--- /dev/null
+++ b/src/xdev/hybdev/HYBRequest.java
@@ -0,0 +1,163 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 20013
+ 1. SEECS National University of Sciences and Technology
+ 2. Aamir Shafi (2005 - 2013)
+ 3. Ansar Javed (2013 - 2013)
+ 4. Mohsan Jameel (2013 - 2013)
+ 5. Bibrak Qamar (2013 - 2013)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : HYBDevice.java
+ * Author : Aamir Shafi, Mohsan Jameel, Ansar Javed, Bibrak Qamar
+ * Created : Mon Aug 5 12:22:15 PKT 2013
+ * Revision : $Revision: 1.28 $
+ * Updated : $Date: 2013/12/17 17:24:47 $
+ *
+ */
+
+package xdev.hybdev;
+
+import java.util.UUID;
+import java.nio.*;
+import mpjdev.*;
+import xdev.*;
+
+import mpjbuf.RawBuffer ;
+
+public abstract class HYBRequest
+ extends Request {
+
+ HYBRequest nextCompleted, prevCompleted ;
+ boolean inCompletedList ;
+
+ HYBDevice device ;
+
+ /* buffers for storing static/dynamic sections of the buffer */
+ ByteBuffer dBuffer = null;
+ RawBuffer eagerBuffer = null;
+ byte[] dynamicBuffer = null;
+ ByteBuffer staticBuffer;
+ byte[] bytes = null;
+ boolean alreadyCompleted = false ;
+
+
+ boolean dSection = true, sSection = true;
+ int context = -1, tag, commMode, rank_source = 0, sBufSize = 0, dBufSize = 0 ;
+ int sendCounter, recvCounter, numEls = -1 ;
+
+ UUID dstUUID, srcUUID;
+ mpjdev.Status status = null;
+ mpjbuf.Buffer buffer = null;
+ mpjbuf.Type type = null;
+
+ volatile boolean completed = false;
+
+ public boolean cancel() {
+ /* First start considering the sender side
+ * a) Send. --> For eager-send, its not possible.
+ * --> For rendezvous, yeah, can be cancelled.
+ * Isend --> Eager-send, not possible.
+ * --> For rendezvous, not possible.
+ * b) Same for Ready/Send
+ * c) Bsend --> Not possible at all.
+ * d) Ssend --> Possible.
+ * e) Recv --> Eager-send, not possible.
+ * --> Rendezvous-protocol.*/
+
+ return false;
+ }
+
+ synchronized void setCompleted(boolean completed) {
+ this.completed = completed;
+ }
+
+ synchronized boolean isCompleted() {
+ return completed;
+ }
+
+ public static Status iwaitany(HYBRequest [] requests) {
+ System.out.println(" HYBRequest.iwaitany( .. )") ;
+ return null;
+ }
+
+ /**
+ */
+ public abstract Status iwait();
+
+ /**
+ * Method used by iwait() to actually wait for the communication to finish.
+ */
+ synchronized void waitMe() {
+ while (!completed) {
+ try {
+ this.wait();
+ }
+ catch (Exception e) {
+ e.printStackTrace() ;
+ }
+ }
+
+ //device.completedList.remove(this);
+ // .. remove from completedList ..
+ }
+
+ /**
+ * Method used to notify that the communication operation has finished.
+ */
+ synchronized void notifyMe() {
+ this.completed = true;
+
+ try {
+ this.notify();
+ }
+ catch (Exception e) {
+ e.printStackTrace() ;
+ }
+ }
+
+ /** this method returns Status object if the communication is completed,
+ * and if its not completed, it returns zero.
+ */
+ public Status itest() {
+ if(alreadyCompleted) {
+ return null;
+ }
+ synchronized (this) {
+ if (this.isCompleted()) {
+ return new mpjdev.Status(rank_source, tag, -1); //what is index ?
+ }
+ else {
+ return null; //change this to something understand at higher levels ...
+ }
+ }
+ }
+
+ public void free() {
+ }
+
+ public boolean isnull() {
+ return false;
+ }
+}
diff --git a/src/xdev/mxdev/MXDevice.java b/src/xdev/mxdev/MXDevice.java
new file mode 100644
index 0000000..375a39c
--- /dev/null
+++ b/src/xdev/mxdev/MXDevice.java
@@ -0,0 +1,534 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MXDevice.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Oct 23 18:15:07 BST 2005
+ * Revision :
+ * Updated :
+ */
+package xdev.mxdev;
+
+import xdev.Device ;
+import xdev.ProcessID ;
+import xdev.XDevException ;
+import java.util.UUID ;
+import mpjbuf.BufferFactory ;
+import java.io.IOException ;
+import java.util.StringTokenizer;
+import xdev.niodev.ConfigReader; // this will definitely goto xdev pack.
+import mpi.ProcTree ;
+import mpjbuf.Type;
+import java.util.HashMap ;
+
+public class MXDevice implements Device {
+ int rank ;
+ int nprocs = 0;
+ int SEND_OVERHEAD ;
+ int RECV_OVERHEAD ;
+ String[] processNames = null;
+ int [] ranks = null;
+ ProcTree procTree ;
+ int index, root, extent, places;
+ MXProcessID[] pids;
+ Device nioDevice ;
+ static HashMap<Long, MXRequest> requestMap =
+ new HashMap<Long, MXRequest> ();
+
+ public MXDevice() {
+ //this.deviceName = "mxdev";
+ }
+
+ public ProcessID[] init(String[] args) throws XDevException {
+
+ // \/\/\/\/\/\
+ //nioDevice = Device.newInstance("niodev");
+ //nioDevice.init(args);
+ // \/\/\/\/\/\
+ rank = Integer.parseInt(args[0]);
+ SEND_OVERHEAD = getSendOverhead();
+ RECV_OVERHEAD = getRecvOverhead();
+ ConfigReader reader = null;
+
+ try {
+ reader = new ConfigReader(args[1]);
+ nprocs = (new Integer(reader.readNoOfProc())).intValue();
+ int psl = (new Integer(reader.readIntAsString())).intValue();
+ }
+ catch (Exception config_error) {
+ throw new XDevException(config_error);
+ }
+
+ int count = 0;
+ processNames = new String[nprocs];
+ ranks = new int[nprocs];
+ pids = new MXProcessID[nprocs];
+
+ while (count < nprocs) {
+
+ String line = null;
+
+ try {
+ line = reader.readLine();
+ }
+ catch (IOException ioe) {
+ throw new XDevException(ioe);
+ }
+
+ if (line == null || line.equals("") || line.equals("#")) {
+ continue;
+ }
+
+ line = line.trim();
+ StringTokenizer tokenizer = new StringTokenizer(line, "@");
+ processNames [count] = tokenizer.nextToken();
+ //processNames[count] = processNames[count]+":"+tokenizer.nextToken();
+ //processNames[count] = processNames[count]+":0";
+ processNames[count] = processNames[count]+":"+tokenizer.nextToken() ;
+ //tokenizer.nextToken(); //this will return the default port number
+ //because the runtime does not know what
+ //to write in the conf file according to the
+ //device that is being used ...may be make
+ //mx_board_num another entry ...
+ //at the moment ..this is hard coded as you can
+ //see above :0 ;-)
+ ranks[count] = (new Integer(tokenizer.nextToken())).intValue();
+ count++;
+
+ }
+
+ reader.close();
+
+ /* Make a tree structure */
+ index = rank;
+ root = 0;
+ procTree = new ProcTree();
+ extent = nprocs;
+ places = ProcTree.PROCTREE_A * index;
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ ch %= extent;
+
+ if (places < extent) {
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ }
+ }
+
+ if (index == root) {
+ procTree.isRoot = true;
+ }
+ else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ }
+
+ procTree.root = root;
+
+ System.loadLibrary("mxdev");
+
+ pids[rank] = new MXProcessID(UUID.randomUUID());
+ UUID myUUID = pids[rank].uuid();
+ long msb = myUUID.getMostSignificantBits();
+ long lsb = myUUID.getLeastSignificantBits();
+ nativeInit(args,rank,processNames,ranks,nprocs, pids, msb, lsb);
+ //System.out.println("rank "+rank+"calling barrier");
+ barrier();
+ //System.out.println("rank "+rank+"called barrier");
+ return pids;
+ }
+
+ public int getSendOverhead() {
+ return 8;
+ }
+
+ public int getRecvOverhead() {
+ return 8;
+ }
+
+ public ProcessID id() {
+ return pids[rank];
+ }
+
+ private void barrier() {
+ int offset = 0;
+ int[] data = new int[1];
+ int count = 1;
+ int btag = 34*1000 ;
+ int context = 50;
+
+ mpjbuf.Buffer sbuf = new mpjbuf.Buffer(
+ BufferFactory.create(23+SEND_OVERHEAD),
+ SEND_OVERHEAD , 23+SEND_OVERHEAD );
+
+ mpjbuf.Buffer rbuf = new mpjbuf.Buffer(
+ BufferFactory.create(
+ 16+RECV_OVERHEAD),
+ RECV_OVERHEAD,
+ RECV_OVERHEAD+16) ;
+
+ if (procTree.numChildren == -1 || !procTree.isRoot) {
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(data, offset, count);
+ sbuf.commit();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (procTree.isRoot) {
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1) {
+ recv(rbuf, pids[procTree.child[i]], btag, context);
+ try {
+ rbuf.clear() ;
+ }
+ catch(Exception e) {}
+ }
+ }
+ }
+ else {
+ if (procTree.parent == -1) {
+ System.out.println("non root's node parent doesn't exist");
+ }
+
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1) {
+ recv(rbuf, pids[procTree.child[i]], btag, context);
+ try {
+ rbuf.clear() ;
+ }
+ catch(Exception e) {}
+ }
+ }
+
+ send(sbuf, pids[procTree.parent], btag, context);
+ }
+
+ if (procTree.isRoot) {
+ //realFinish();
+ }
+
+ BufferFactory.destroy( sbuf.getStaticBuffer()) ;
+ BufferFactory.destroy( rbuf.getStaticBuffer()) ;
+ }
+
+ public void finish() throws XDevException {
+ //System.out.println(" mxdev.finish() ");
+ barrier();
+ //nioDevice.finish();
+ nativeFinish();
+ }
+
+ public mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID dstID,
+ int tag, int context)
+ throws XDevException {
+ MXSendRequest sendRequest = new MXSendRequest();
+ int staticBufferLength = buf.getSize() ;
+ int dynamicBufferLength;
+ int offset = buf.offset();
+
+ if(buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length ;
+ }
+ else {
+ dynamicBufferLength = 0;
+ }
+
+ //buf.getStaticBuffer().putInt( staticBufferLength, 4 );
+ //buf.getStaticBuffer().put( encoding, 0); .. ..
+ //buf.getStaticBuffer().putInt( dynamicBufferLength, 0 );
+
+ //System.out.println("offset "+offset);
+ //System.out.println("staticBufferLength "+staticBufferLength );
+ //System.out.println("dynamicBufferLength"+dynamicBufferLength);
+
+ nativeIsend(buf, dstID, tag, context, staticBufferLength,
+ dynamicBufferLength, sendRequest, offset );
+ requestMap.put( new Long(sendRequest.handle), sendRequest) ;
+ return sendRequest ;
+ }
+
+ public void send(mpjbuf.Buffer buf, ProcessID dstID,
+ int tag, int context) throws XDevException {
+ int staticBufferLength = buf.getSize() ;
+ int dynamicBufferLength;
+ int offset = buf.offset();
+ //System.out.println("offset "+offset);
+
+ if(buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length ;
+ }
+ else {
+ dynamicBufferLength = 0;
+ }
+
+ //we can write the control-section here ..
+ nativeSend(buf, dstID, tag, context, staticBufferLength,
+ dynamicBufferLength);
+ }
+
+ public mpjdev.Request issend(mpjbuf.Buffer buf, ProcessID dstID,
+ int tag, int context)
+ throws XDevException {
+ MXSendRequest sendRequest = new MXSendRequest();
+ int staticBufferLength = buf.getSize() ;
+ int dynamicBufferLength;
+
+ if(buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length ;
+ }
+ else {
+ dynamicBufferLength = 0;
+ }
+ nativeIssend(buf, dstID, tag, context, staticBufferLength,
+ dynamicBufferLength, sendRequest );
+ requestMap.put( new Long(sendRequest.handle), sendRequest) ;
+ return sendRequest ;
+ }
+
+ public void ssend(mpjbuf.Buffer buf, ProcessID dstID,
+ int tag, int context) throws XDevException {
+ int staticBufferLength = buf.getSize() ;
+ int dynamicBufferLength;
+
+ if(buf.getDynamicBuffer() != null) {
+ dynamicBufferLength = buf.getDynamicBuffer().length ;
+ }
+ else {
+ dynamicBufferLength = 0;
+ }
+
+ nativeSsend(buf, dstID, tag, context, staticBufferLength,
+ dynamicBufferLength);
+ }
+
+ public mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context)
+ throws XDevException {
+
+ mpjdev.Status status = new mpjdev.Status();
+ //we do not need any of this bollocks if the native code can set
+ // "status.srcID and status.tag"
+ int ANY_SRC = 0; //0 is false and 1 is true
+ if(srcID.uuid().equals(xdev.Device.ANY_SRC.uuid()) ) {
+ ANY_SRC = 1;
+ }
+ //else if(srcID.uuid().equals(xdev.Device.ANY_SRC.uuid())) {
+ // ANY_SRC = 1;
+ // status.tag = tag;
+ //} else if(tag == Device.ANY_TAG) {
+ // status.srcID = srcID.uuid();
+ //} else {
+ // status.srcID = srcID.uuid();
+ // status.tag = tag;
+ //}
+
+ nativeRecv( buf, srcID, tag, context, status, ANY_SRC);
+ status.srcID = pids[status.source].uuid();
+ try {
+ buf.commit();
+ status.type = buf.getSectionHeader() ;
+ status.numEls = buf.getSectionSize() ;
+ }
+ catch(Exception e) {
+ throw new XDevException(e);
+ }
+ return status;
+
+ }
+
+ public mpjdev.Request irecv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context,
+ mpjdev.Status status)
+ throws XDevException {
+ MXRecvRequest recvRequest = new MXRecvRequest(this);
+ int ANY_SRC = 0; //0 is false and 1 is true
+
+ if(srcID.uuid().equals(xdev.Device.ANY_SRC.uuid())) {
+ ANY_SRC = 1;
+ }
+
+ recvRequest.status = new mpjdev.Status();
+ nativeIrecv(buf, srcID, tag, context, status, recvRequest,
+ ANY_SRC);
+ requestMap.put( new Long(recvRequest.handle), recvRequest) ;
+ return recvRequest;
+ }
+
+ public mpjdev.Status probe(ProcessID srcID, int tag,
+ int context) throws XDevException {
+ mpjdev.Status status = new mpjdev.Status();
+ int ANY_SRC = 0; //0 is false and 1 is true
+ if(srcID.uuid().equals(xdev.Device.ANY_SRC.uuid())) {
+ ANY_SRC = 1;
+ }
+ //else {
+ // status.srcID = srcID.uuid();
+ // status.tag = tag;
+ //}
+ nativeProbe(srcID, tag, context, status, ANY_SRC);
+ status.srcID = pids[status.source].uuid();
+ return status;
+ }
+
+ public mpjdev.Status iprobe(ProcessID srcID, ProcessID dstID, int tag,
+ int context) throws XDevException {
+ return null;
+ }
+
+ public mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID, int tag,
+ int context, mpjbuf.Buffer buf) throws XDevException {
+ return null;
+ }
+
+ public mpjdev.Status iprobe(ProcessID srcID, int tag,
+ int context) throws XDevException {
+ mpjdev.Status status = new mpjdev.Status();
+ int ANY_SRC = 0; //0 is false and 1 is true
+ if(srcID.uuid().equals(xdev.Device.ANY_SRC.uuid())) {
+ ANY_SRC = 1;
+ }
+ int isCompleted = 0 ;
+ //System.out.println(" context(iprobe) "+context);
+ isCompleted = nativeIprobe(srcID, tag,
+ context, status, ANY_SRC, isCompleted );
+ //System.out.println(" isCompleted (after probe) <"+isCompleted+">");
+ //System.out.println(" isCompleted (after probe) <"+status+">");
+ if(isCompleted == 1) {
+ status.srcID = pids[status.source].uuid();
+ }
+ //we need to return null in case there is no message that has been
+ //probed.
+ return ((isCompleted == 1) ? status : null);
+ }
+
+
+ // TODO: need to get rid of isPeeked flag ..its not required anymore ...
+ public mpjdev.Request peek() throws XDevException {
+ long natPeekedReqHandle ;
+ //this status is dummy ...no use ...
+ mpjdev.Status completedStatus = new mpjdev.Status() ;
+ natPeekedReqHandle = nativePeek(completedStatus) ;
+ //note that peekedRequest is not deleted from requestMap ...
+ //iwait is supposed to do this ...
+ MXRequest peekedRequest = requestMap.get(new Long(natPeekedReqHandle)) ;
+ //peekedRequest.isPeeked = 1 ;
+ //peekedRequest.status = completedStatus ;
+ return peekedRequest ;
+ }
+
+/*
+ public static mpjdev.Status iwaitany(mpjdev.Request[] requests) {
+
+ MXRequest peekedRequest ;
+ long natPeekedReqHandle ;
+ mpjdev.Status completedStatus = new mpjdev.Status() ;
+ boolean found = false;
+ boolean inActive = true ;
+
+ // check if there is a valid request which could be peeked
+ for(int i=0 ; i< requests.length ; i++) {
+ if(requests[i] != null) {
+ inActive = false;
+ }
+ }
+
+ if(inActive) {
+ return null;
+ }
+
+ do {
+ natPeekedReqHandle = nativePeek(completedStatus) ;
+ //iwait will delete it ...
+ peekedRequest = requestMap.get(new Long(natPeekedReqHandle)) ;
+ //peekedRequest = (MXRequest) nativePeek(completedStatus);
+ //peekedRequest.isPeeked = 1;
+ completedStatus = peekedRequest.iwait() ;
+ //deletePeekedRequest(peekedRequest, peekedRequest.requestStruct) ;
+ // see if the peekedRequest is in the argument
+ for(int j=0 ;j<requests.length ; j++) {
+ if(requests[j] != null) {
+ if(peekedRequest == requests[j]) {
+ completedStatus.index = j ;
+ found = true;
+ break;
+ }
+ }
+ }
+ if(!found) {
+ System.out.println(" The message peeked is not what we are looking for"+
+ "... trying more ... ");
+ }
+ } while(!found);
+
+ //completedStatus = peekedRequest.iwait();
+ // need to delete global reference ...
+ return completedStatus ;
+
+ }
+ */ //iwaitany ends ...
+
+ native void nativeInit(String[] args, int rank,
+ String[] processNames, int[] ranks, int nprocs,
+ MXProcessID[] pids, long msb, long lsb) ;
+ native void nativeIsend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context, int staticBufferLength,
+ int dynamicBufferLength, MXSendRequest req,
+ int offset );
+ native void nativeSend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context, int staticBufferLength,
+ int dynamicBufferLength);
+ native void nativeIssend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context, int staticBufferLength,
+ int dynamicBufferLength, MXSendRequest req);
+ native void nativeSsend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context, int staticBufferLength,
+ int dynamicBufferLength);
+ native void nativeIrecv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context, mpjdev.Status status, MXRecvRequest req,
+ int anySrc);
+ native void nativeRecv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context, mpjdev.Status status, int anySrc);
+ native void nativeProbe(ProcessID srcID, int tag, int context,
+ mpjdev.Status status, int anySrc);
+ native int nativeIprobe(ProcessID srcID, int tag, int context,
+ mpjdev.Status status, int anySrc, int isCompleted);
+ native long nativePeek(mpjdev.Status completedStatus) ;
+ static native void deletePeekedRequest(MXRequest request,
+ long requestStruct) ;
+ native void nativeFinish();
+
+}
diff --git a/src/xdev/mxdev/MXProcessID.java b/src/xdev/mxdev/MXProcessID.java
new file mode 100644
index 0000000..d804d75
--- /dev/null
+++ b/src/xdev/mxdev/MXProcessID.java
@@ -0,0 +1,53 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MXProcessID.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Oct 23 18:15:07 BST 2005
+ * Revision :
+ * Updated :
+ */
+
+package xdev.mxdev ;
+
+import xdev.ProcessID ;
+import java.util.UUID;
+
+public class MXProcessID extends ProcessID {
+ long processHandle ;
+ int id = 0 ;
+
+ MXProcessID() {
+ }
+
+ MXProcessID(UUID uuid) {
+ super(uuid);
+ }
+}
diff --git a/src/xdev/mxdev/MXRecvRequest.java b/src/xdev/mxdev/MXRecvRequest.java
new file mode 100644
index 0000000..badce8d
--- /dev/null
+++ b/src/xdev/mxdev/MXRecvRequest.java
@@ -0,0 +1,116 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MXRecvRequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Oct 23 18:59:59 GMT 2005
+ * Revision :
+ * Updated :
+ *
+ */
+
+package xdev.mxdev ;
+
+import java.util.UUID;
+import java.nio.channels.*;
+import java.nio.*;
+import mpjdev.*;
+import mpjbuf.NIOBuffer ;
+import xdev.*;
+
+public class MXRecvRequest
+ extends MXRequest {
+
+ //probaby very ugly to put a reference for the device here.
+ //the problem is that status contains this rank(id) that is used
+ //get the srcID of the process. this srcID is a pain in the ass,
+ //i think we should just get rid of it. what we need is a mapping
+ //from commRank to devRank ....devRank will be similar to
+ //commRank in WORLD Communicator.
+ MXDevice device ;
+ int [] ctrlMsg = new int[2];
+
+ MXRecvRequest(MXDevice device) {
+ this.device = device ;
+ }
+
+ protected long matchRecvHandle, matchRecvMaskHandle, sBufLengthHandle,
+ dBufLengthHandle, bufferAddressHandle,
+ ctrlMsgHandle ;
+
+ public Status iwait() {
+ // System.out.println("this <"+this+"> calling iwait with testCalled <"+testCalled+">");
+ nativeIwait(status);
+ //System.out.println("this <"+this+"> called iwait with testCalled <"+testCalled+">");
+ status.srcID = device.pids[status.source].uuid();
+ //System.out.println(" this <"+this+"> bufferHandle.getSize() "+bufferHandle.getSize());
+ // not putting this in itest because at MPI level, each Test() calls
+ // device's test() followed by wait() ..
+
+ MXDevice.requestMap.remove(new Long(this.handle));
+ try {
+ bufferHandle.commit();
+ status.type = bufferHandle.getSectionHeader();
+ status.numEls = bufferHandle.getSectionSize();
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ //throw new XDevException(e);
+ }
+ complete(status);
+ testCalled = 1;
+ return status;
+ }
+
+ public Status itest() {
+ //System.out.println("this <"+this+
+// "> calling itest with testCalled <"+testCalled+">");
+ if(testCalled == 1) {
+// System.out.println(" returning as this has been called before ");
+ return status;
+ }
+ int isCompleted = nativeItest(status);
+ //System.out.println("this <"+this+
+// "> called itest with testCalled <"+testCalled+">");
+ if(isCompleted == 1) {
+ status.srcID = device.pids[status.source].uuid();
+ testCalled = 1;
+ }
+ return ((isCompleted == 1)?status:null) ;
+ }
+
+ native void nativeIwait(Status status);
+ native int nativeItest(Status status);
+ private static native void nativeRequestInit();
+
+ static {
+ nativeRequestInit();
+ }
+
+}
diff --git a/src/xdev/mxdev/MXRequest.java b/src/xdev/mxdev/MXRequest.java
new file mode 100644
index 0000000..7949fc7
--- /dev/null
+++ b/src/xdev/mxdev/MXRequest.java
@@ -0,0 +1,98 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : MXRequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Oct 23 18:56:11 GMT 2005
+ * Revision :
+ * Updated :
+ *
+ */
+
+package xdev.mxdev;
+
+import java.util.UUID;
+import java.nio.*;
+import mpjdev.*;
+import xdev.*;
+
+import mpjbuf.RawBuffer ;
+
+public abstract class MXRequest
+ extends Request {
+
+ // in theory do not need this for SendRequest ...it is required for recv
+ // requests ...when wiat completes after irecv ..it fills in all the info
+ // in this and this guy is returned ..i am also using it in nativepeek ...
+ // when the first wait is called .. it has some info that has to be
+ // filled in the status ..so i am this status object to fill that info in ..
+ // later when wait is called after calling peek ..we make sure that we dont
+ // call wait for primary message as it has already been called ..thus
+ // we need info like what was the size of primary message and tag ..and
+ // that info is in this status object ...
+ mpjdev.Status status ;
+ long handle, localEndpointHandle, requestStruct ;
+ protected mpjbuf.Buffer bufferHandle;
+ //long nativeRequestHandle ;
+ int testCalled = 0;
+ int isPeeked = 0 ;
+
+ public boolean cancel() {
+ /* First start considering the sender side
+ * a) Send. --> For eager-send, its not possible.
+ * --> For rendezvous, yeah, can be cancelled.
+ * Isend --> Eager-send, not possible.
+ * --> For rendezvous, not possible.
+ * b) Same for Ready/Send
+ * c) Bsend --> Not possible at all.
+ * d) Ssend --> Possible.
+ * e) Recv --> Eager-send, not possible.
+ * --> Rendezvous-protocol.*/
+
+ return false;
+ }
+
+ /**
+ */
+ public abstract Status iwait();
+
+ /** this method returns Status object if the communication is completed,
+ * and if its not completed, it returns zero.
+ */
+ public abstract Status itest();
+
+ public void free() {
+ }
+
+ public boolean isnull() {
+ return false;
+ }
+
+}
diff --git a/src/xdev/mxdev/MXSendRequest.java b/src/xdev/mxdev/MXSendRequest.java
new file mode 100644
index 0000000..0f2e9af
--- /dev/null
+++ b/src/xdev/mxdev/MXSendRequest.java
@@ -0,0 +1,81 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : MXSendRequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Sun Oct 23 18:59:59 GMT 2005
+ * Revision :
+ * Updated :
+ *
+ */
+
+package xdev.mxdev ;
+
+import java.util.UUID;
+import java.nio.channels.*;
+import java.nio.*;
+import mpjdev.*;
+import mpjbuf.NIOBuffer ;
+import xdev.*;
+
+public class MXSendRequest
+ extends MXRequest {
+
+ long dbufHandle ;
+ int dbuflen ;
+
+ public Status iwait() {
+ mpjdev.Status status = new mpjdev.Status();
+ nativeIwait(status);
+ // not putting this in itest because at MPI level, each Test() calls
+ // device's test() followed by wait() ..
+ MXDevice.requestMap.remove(new Long(this.handle));
+ complete(status);
+ testCalled = 1 ;
+ return status;
+ }
+
+ public Status itest() {
+ mpjdev.Status status = new mpjdev.Status();
+ int isCompleted = nativeItest(status);
+ if(isCompleted == 1) {
+ testCalled = 1 ;
+ }
+ return ((isCompleted == 1)?status:null) ;
+ }
+
+ native void nativeIwait(Status status);
+ native int nativeItest(Status status);
+ private static native void nativeRequestInit();
+
+ static {
+ nativeRequestInit();
+ }
+
+}
diff --git a/src/xdev/mxdev/lib/mxdev_const.h b/src/xdev/mxdev/lib/mxdev_const.h
new file mode 100644
index 0000000..c7280c0
--- /dev/null
+++ b/src/xdev/mxdev/lib/mxdev_const.h
@@ -0,0 +1,28 @@
+/** The MIT License
+
+Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+*/
+#include "myriexpress.h"
+#include "jni.h"
+
+#define ANY_TAG -2
+#define PRI_MATCH(CONTEXT, SRC, TAG) \
+ ((((uint64_t) CONTEXT) << 32)|(((uint64_t) SRC)<< 48)|0x80000000|\
+ ((uint64_t)TAG))
+#define SEC_MATCH(CONTEXT, SRC, TAG) \
+ ((((uint64_t) CONTEXT) << 32)|(((uint64_t) SRC ) << 48) | ((uint64_t) TAG ))
+#define MASK_TAG (UINT64_C(0x000000007fffffff))
+#define MASK_SRC (UINT64_C(0xffff000000000000))
+#define EMPTY (UINT64_C(0x0000000000000000))
+#define MATCH_CONTEXT (UINT64_C(0x0000ffff80000000))
+#define GET_TAG(M) ((M) & 0x7fffffff)
+#define GET_SRC(M) (((M) >> 48 ) & 0xffff)
+
+//typedef struct jrequeststruct {
+// jobject jrequest ;
+//} JRequestStruct;
+
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.c b/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.c
new file mode 100644
index 0000000..abcf948
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.c
@@ -0,0 +1,1341 @@
+/** The MIT License
+
+Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+*/
+#include "myriexpress.h"
+#include <stdio.h>
+#include "xdev_mxdev_MXDevice.h"
+#include "jni.h"
+#include "mxdev_const.h"
+
+//***********************************************************
+//** block diagram for the tag ..it is a 64 bit number **
+//** <---16-----><------16------><--1--><--------31------->**
+//** ------------------------------------------------------**
+//** | context | src | PRI | tag |**
+//** ------------------------------------------------------**
+//***********************************************************
+
+static JavaVM *jvm;
+
+int myRank ;
+int procs ;
+
+jclass CL_mpjdev_Status ;
+jclass CL_mpjbuf_Buffer;
+jclass CL_xdev_mxdev_MXProcessID;
+jclass CL_mpjbuf_NIOBuffer;
+jclass CL_mpjbuf_Type;
+jclass CL_xdev_ProcessID;
+jclass CL_xdev_mxdev_MXRequest ;
+
+jfieldID FID_mpjbuf_Buffer_staticBuffer;
+jfieldID FID_mpjbuf_Buffer_dynamicBuffer;
+jfieldID FID_mpjbuf_Buffer_size;
+jfieldID FID_mpjbuf_Buffer_capacity;
+jfieldID FID_mpjbuf_NIOBuffer_buffer;
+jfieldID FID_mpjbuf_Type_code;
+jfieldID FID_xdev_ProcessID_uuid;
+jfieldID FID_xdev_mxdev_MXRequest_status ;
+jfieldID FID_xdev_mxdev_MXRequest_requestStruct ;
+jfieldID processhandleID;
+jfieldID processidID;
+jfieldID status_src_ID ;
+jfieldID status_tag_ID ;
+jfieldID countInBytesID;
+
+/* Caching of JNI stuff ..*/
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+
+ JNIEnv *env;
+ jvm=vm;
+
+ if (JNI_OK!=(*vm)->GetEnv(vm,(void **)&env,JNI_VERSION_1_4)) {
+ exit(1);
+ }
+
+ // why am i not deleting these two global references ... (?)
+ CL_mpjbuf_Buffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env,"mpjbuf/Buffer"));
+ CL_xdev_mxdev_MXProcessID = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env,"xdev/mxdev/MXProcessID"));
+ CL_xdev_mxdev_MXRequest = (*env)->FindClass(env,"xdev/mxdev/MXRequest");
+ CL_mpjbuf_NIOBuffer = (*env)->NewGlobalRef(env,
+ (*env)->FindClass(env,"mpjbuf/NIOBuffer"));
+ CL_mpjbuf_Type = (*env)->FindClass(env,"mpjbuf/Type");
+ CL_xdev_ProcessID = (*env)->FindClass(env,"xdev/ProcessID");
+ CL_mpjdev_Status = (*env)->FindClass(env,"mpjdev/Status");
+
+ FID_mpjbuf_Buffer_size = (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"size","I");
+ FID_mpjbuf_Buffer_capacity =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"capacity","I");
+ FID_mpjbuf_Buffer_staticBuffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"staticBuffer","Lmpjbuf/RawBuffer;");
+ FID_mpjbuf_Buffer_dynamicBuffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_Buffer,"dynamicBuffer","[B");
+ FID_mpjbuf_NIOBuffer_buffer =
+ (*env)->GetFieldID(env,CL_mpjbuf_NIOBuffer,"buffer","Ljava/nio/ByteBuffer;");
+ FID_mpjbuf_Type_code = (*env)->GetFieldID(env,CL_mpjbuf_Type,"code","I");
+ FID_xdev_ProcessID_uuid =
+ (*env)->GetFieldID(env,CL_xdev_ProcessID,"uuid","Ljava/util/UUID;");
+ processhandleID =
+ (*env)->GetFieldID(env, CL_xdev_mxdev_MXProcessID,"processHandle", "J") ;
+ processidID = (*env)->GetFieldID(env, CL_xdev_mxdev_MXProcessID,
+ "id", "I");
+ status_src_ID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "source", "I");
+ status_tag_ID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "tag", "I");
+ countInBytesID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "countInBytes", "I");
+ FID_xdev_mxdev_MXRequest_status = (*env)->GetFieldID(env,
+ CL_xdev_mxdev_MXRequest,"status","Lmpjdev/Status;");
+ FID_xdev_mxdev_MXRequest_requestStruct = (*env)->GetFieldID(env,
+ CL_xdev_mxdev_MXRequest,"requestStruct","J");
+
+ if (FID_mpjbuf_Buffer_staticBuffer && FID_mpjbuf_Buffer_size \
+ && FID_mpjbuf_NIOBuffer_buffer && FID_mpjbuf_Buffer_capacity \
+ && FID_xdev_ProcessID_uuid) {
+ return JNI_VERSION_1_4;
+ } else {
+ {fprintf(stderr,"\n Fatal error getting FIDs"); exit(3);}
+ }
+
+}
+
+/* Caching of JNI stuff (done)..*/
+
+mx_endpoint_t local_endpoint;
+
+uint32_t filter = 0xcafebabe;
+
+//extern mx_endpoint_t local_endpoint;
+static mx_endpoint_addr_t * peer_endpoints = NULL;
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeInit
+ * Signature: ([Ljava/lang/String;I[Ljava/lang/String;[II[Lxdev/mxdev/MXProcessID;JJ)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeInit
+ (JNIEnv *env, jobject jthis, jobjectArray argv, jint rank,
+ jobjectArray processNames, jintArray ranks, jint nprocs,
+ jobjectArray pids , jlong msb, jlong lsb) {
+
+ mx_return_t rc;
+ rc = mx_init();
+ mx_set_error_handler( MX_ERRORS_RETURN );
+
+ if(rc == MX_SUCCESS) {
+ //printf("mx_init called \n");
+ }
+
+ rc = mx_open_endpoint(MX_ANY_NIC, MX_ANY_ENDPOINT, filter, 0, 0,
+ &local_endpoint);
+ //printf(" nic id upper <%d> \n", MX_U32(nic_id));
+ //printf(" nic id lower <%d> \n", MX_L32(nic_id));
+ if(rc == MX_SUCCESS) {
+ //printf("opened a local end-point \n");
+ }
+
+ //sleep(5);
+
+ jclass CL_java_util_UUID = (*env)->FindClass(env, "java/util/UUID");
+ jmethodID uuid_c = (*env)->GetMethodID(env, CL_java_util_UUID,
+ "<init>", "(JJ)V") ;
+ jmethodID pid_c = (*env)->GetMethodID(env, CL_xdev_mxdev_MXProcessID,
+ "<init>", "(Ljava/util/UUID;)V") ;
+
+ myRank = rank ;
+ procs = nprocs ;
+ peer_endpoints = (mx_endpoint_addr_t *)
+ malloc(procs*sizeof(mx_endpoint_addr_t));
+ //.. ..
+ uint64_t nic_id;
+ //printf("native init method \n");
+
+
+ jobject pid;
+ int len = (*env)->GetArrayLength(env,processNames);
+ char** pNames = (char**)calloc(len, sizeof(char*));
+ int i=0;
+ char *pName;
+
+ for (i=0; i<len; i++) {
+ pName =(jstring)(*env)->GetObjectArrayElement(env,processNames,i);
+ pNames[i] = (*env)->GetStringUTFChars(env,pName,0);
+ }
+
+ /* connect loop */
+ for(i=0 ; i<nprocs ; i++) {
+ //printf(" connecting to <%s> \n", pNames[i]);
+ rc = mx_hostname_to_nic_id( pNames[i] , &nic_id);
+ if(rc == MX_SUCCESS) {
+ //printf("getting nic_id from hostname \n");
+ }
+
+
+ NC:
+ //printf("calling connect() \n");
+ //printf(" nic id upper <%d> \n", MX_U32(nic_id));
+ //printf(" nic id lower <%d> \n", MX_L32(nic_id));
+ rc = mx_connect(local_endpoint, nic_id, 0, filter,
+ MX_INFINITE, &peer_endpoints [i]);
+ //printf("called connect() \n");
+ if(rc == MX_SUCCESS) {
+ //printf("connected to remote host <%s> \n", pNames[i]);
+ } else {
+ //printf("could not connect to <%s> \n", pNames[i]);
+ //printf("trying again ...");
+ goto NC; //need to get rid of this ..we just need a do while loop.
+ }
+
+ }
+
+ //fflush(stdout);
+ // ids set up could be done here ...
+ //printf("nativeIdsSetup rank <%d> of <%d> \n", myRank, procs);
+
+ // sending accessories
+ mx_segment_t buffer_desc[3];
+ mx_request_t send_handle[procs] ;
+ uint64_t send_tag ;
+ mx_status_t send_status ;
+ uint32_t result ;
+
+ // irecv accessories
+ mx_segment_t recv_buffer[3];
+ mx_request_t recv_handle ;
+ uint64_t match_tag;
+ uint64_t match_mask;
+ mx_status_t recv_status;
+ uint32_t recv_result;
+
+ buffer_desc[0].segment_ptr = &msb;
+ buffer_desc[0].segment_length = 64;
+ buffer_desc[1].segment_ptr = &lsb;
+ buffer_desc[1].segment_length = 64;
+ buffer_desc[2].segment_ptr = &rank;
+ buffer_desc[2].segment_length = 4;
+ //printf("rank <%d> \n",rank);
+ //this needs to be fixed ..basically use the tag macros once I have
+ //defined them ...
+ send_tag = myRank << 32; //| UINT64_C(0x0000000000000000);
+
+ for(i=0 ; i<procs ; i++) {
+ if( i == myRank) {
+ continue;
+ }
+ //printf("pro <%d> calling send to pro <%d> \n",
+ // myRank, i); fflush(stdout);
+ rc = mx_isend(local_endpoint, buffer_desc, 3, peer_endpoints[i],
+ send_tag, NULL, &send_handle[i]);
+ //if( rc == MX_SUCCESS ) {
+ // printf("pro <%d> called isend to pro <%d> \n",
+ // myRank, i); fflush(stdout);
+ //}
+ }
+
+ //printf("pro <%d> reached A \n",myRank ); fflush(stdout);
+
+ jlong _msb, _lsb;
+ jint _rank ;
+ match_mask = UINT64_C(0x00000000ffffffff);
+
+ for(i=0 ; i<procs ; i++) {
+ if( i == myRank) {
+ continue;
+ }
+
+ recv_buffer[0].segment_ptr = &_msb;
+ recv_buffer[0].segment_length = 64;
+ recv_buffer[1].segment_ptr = &_lsb;
+ recv_buffer[1].segment_length = 64;
+ recv_buffer[2].segment_ptr = &_rank;
+ recv_buffer[2].segment_length = 4;
+
+ match_tag = i << 32 ;
+
+ //printf("pro <%d> receiving from process <%d> \n",
+ // myRank, i); fflush(stdout);
+ rc = mx_irecv(local_endpoint, recv_buffer, 3, match_tag, match_mask,
+ NULL , &recv_handle);
+ //printf(" calling wait \n"); fflush(stdout);
+ rc = mx_wait(local_endpoint, & recv_handle, MX_INFINITE,
+ &recv_status, &result);
+ if(rc == MX_SUCCESS) {
+ // printf("pro <%d> received from process <%d> \n",
+ // myRank, i); fflush(stdout);
+ }else {
+ printf("error \n");
+ }
+
+ jobject uid = (*env)->NewObject(env, CL_java_util_UUID,
+ uuid_c, _msb, _lsb);
+ pid = (*env)->NewObject(env, CL_xdev_mxdev_MXProcessID,
+ pid_c, uid);
+
+ (*env)->SetLongField(env,pid, processhandleID, (jlong)&peer_endpoints[i]);
+ (*env)->SetIntField(env,pid, processidID, _rank);
+ (*env)->SetObjectArrayElement(env,pids,i,pid);
+
+ }
+
+ //printf("process <%d> reached B \n",myRank ); fflush(stdout);
+ for(i=0 ; i<procs ; i++) {
+ if( i == myRank) {
+ continue;
+ }
+ //printf("pro <%d> calling send_wait to process <%d> \n",
+ // myRank, i); fflush(stdout);
+ mx_wait(local_endpoint, &send_handle[i], MX_INFINITE,
+ &recv_status, &recv_result);
+ //printf("pro <%d> called send_wait to process <%d> \n",
+ // myRank, i); fflush(stdout);
+ }
+
+ //a. <get objectarrayelement for this process>
+ pid = (*env)->GetObjectArrayElement(env,pids,myRank);
+
+ //b. <set long field for it ...>
+ (*env)->SetLongField(env,pid, processhandleID,
+ (jlong)&peer_endpoints[myRank]);
+
+ //c. <set integer field for it ...>
+ (*env)->SetIntField(env,pid, processidID, myRank);
+
+
+ //printf("process <%d> reached C \n",myRank ); fflush(stdout) ;
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeSsend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIII)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeSsend
+ (JNIEnv *env, jobject this, jobject buf, jobject dstID,
+ jint tag, jint context, jint sbuf_length, jint dbuf_length) {
+
+ /* MX accessories for calling mx_isend */
+ mx_return_t rc ;
+ mx_request_t send_handle;
+ mx_status_t status;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_send, dbuf_tag ;
+ uint32_t result;
+ mx_endpoint_addr_t * dest;
+ dest = (mx_endpoint_addr_t *)
+ ((*env)->GetLongField(env, dstID, processhandleID )) ;
+
+ match_send = PRI_MATCH(context, myRank, tag);
+ //printf("send_recv U32 <%x> \n",MX_U32(match_send));fflush(stdout);
+ //printf("send_recv L32 <%x> \n",MX_L32(match_send));fflush(stdout);
+
+ /* static buffer related declarations */
+ char *buffer_address=NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+
+ /* dynamic buffer related declarations */
+ jboolean isCopy=JNI_TRUE;
+ jbyteArray dynamicBuffer ;
+ jbyte* dBuffer;
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer, FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+
+ /* get dynamic buffer related stuff */
+ dynamicBuffer =
+ (jbyteArray) (*env)->GetObjectField(env,buf,
+ FID_mpjbuf_Buffer_dynamicBuffer);
+ if(dbuf_length > 0) {
+ dBuffer = (*env)->GetByteArrayElements(env, dynamicBuffer, &isCopy);
+ }
+ //.. write the first eight bytes ..
+ // _________________________
+ // | E | X | X | X | DSIZE |
+ // -------------------------
+ char encoding = 1;
+ buffer_address[0] = encoding ;
+ buffer_address[4] = (((unsigned int) dbuf_length) >> 24) & 0xFF ;
+ buffer_address[5] = (((unsigned int) dbuf_length) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbuf_length) >> 8) & 0xFF ;
+ buffer_address[7] = ((unsigned int) dbuf_length) & 0xFF;
+
+ /* compose message, sort out tag/context and remote endpoints */
+ buffer_desc[0].segment_ptr = buffer_address ;
+ buffer_desc[0].segment_length = sbuf_length+8; //+offset;
+
+ /* send message */
+ //printf("native:send sending \n");
+ rc = mx_issend(local_endpoint, buffer_desc, 1, * dest, match_send,
+ NULL, &send_handle);
+ //printf("native:send sent \n");
+
+ mx_segment_t dbuf_desc [1] ;
+ dbuf_tag = SEC_MATCH(context, myRank, tag);
+ mx_request_t dbufsend_handle;
+
+ dbuf_desc[0].segment_ptr = dBuffer ;
+ dbuf_desc[0].segment_length = dbuf_length;
+
+ if(dbuf_length > 0) {
+ rc = mx_issend(local_endpoint, dbuf_desc, 1, * dest, dbuf_tag,
+ NULL, &dbufsend_handle);
+ }
+
+ // so which one should be called here first?
+ rc = mx_wait(local_endpoint, &send_handle, MX_INFINITE,
+ &status, &result);
+ if(dbuf_length > 0) {
+ rc = mx_wait(local_endpoint, &dbufsend_handle, MX_INFINITE,
+ &status, &result);
+ }
+}
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeSend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIII)V
+ */
+
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeSend
+ (JNIEnv *env, jobject this, jobject buf, jobject dstID,
+ jint tag, jint context, jint sbuf_length, jint dbuf_length) {
+ //printf(" nativeSend first statement \n"); fflush(stdout);
+ /* MX accessories for calling mx_isend */
+ mx_return_t rc ;
+ mx_request_t send_handle;
+ mx_status_t status;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_send, dbuf_tag ;
+ uint32_t result;
+ mx_endpoint_addr_t * dest;
+ dest = (mx_endpoint_addr_t *)
+ ((*env)->GetLongField(env, dstID, processhandleID )) ;
+
+ match_send = PRI_MATCH(context, myRank, tag);
+ //printf("send_recv U32 <%x> \n",MX_U32(match_send));fflush(stdout);
+ //printf("send_recv L32 <%x> \n",MX_L32(match_send));fflush(stdout);
+
+ /* static buffer related declarations */
+ char *buffer_address=NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+
+ /* dynamic buffer related declarations */
+ jboolean isCopy=JNI_TRUE;
+ jbyteArray dynamicBuffer ;
+ jbyte* dBuffer;
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer, FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+
+ //printf("1 \n");fflush(stdout);
+ /* get dynamic buffer related stuff */
+ dynamicBuffer =
+ (jbyteArray) (*env)->GetObjectField(env,buf,
+ FID_mpjbuf_Buffer_dynamicBuffer);
+ if(dbuf_length > 0) {
+ dBuffer = (*env)->GetByteArrayElements(env, dynamicBuffer, &isCopy);
+ }
+ //.. write the first eight bytes ..
+ // _________________________
+ // | E | X | X | X | DSIZE |
+ // -------------------------
+ char encoding = 1;
+ buffer_address[0] = encoding ;
+ buffer_address[4] = (((unsigned int) dbuf_length) >> 24) & 0xFF ;
+ buffer_address[5] = (((unsigned int) dbuf_length) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbuf_length) >> 8) & 0xFF ;
+ buffer_address[7] = ((unsigned int) dbuf_length) & 0xFF;
+
+ /* compose message, sort out tag/context and remote endpoints */
+ buffer_desc[0].segment_ptr = buffer_address ;
+ buffer_desc[0].segment_length = sbuf_length+8; //+offset;
+
+ /* send message */
+ //printf("native:send sending \n");
+ rc = mx_isend(local_endpoint, buffer_desc, 1, * dest, match_send,
+ NULL, &send_handle);
+ //printf("native:send sent \n");
+
+ mx_segment_t dbuf_desc [1] ;
+ dbuf_tag = SEC_MATCH(context, myRank, tag);
+ mx_request_t dbufsend_handle;
+
+ dbuf_desc[0].segment_ptr = dBuffer ;
+ dbuf_desc[0].segment_length = dbuf_length;
+
+ if(dbuf_length > 0) {
+ rc = mx_isend(local_endpoint, dbuf_desc, 1, * dest, dbuf_tag,
+ NULL, &dbufsend_handle);
+ }
+
+ // so which one should be called here first?
+ rc = mx_wait(local_endpoint, &send_handle, MX_INFINITE,
+ &status, &result);
+ if(dbuf_length > 0) {
+ rc = mx_wait(local_endpoint, &dbufsend_handle, MX_INFINITE,
+ &status, &result);
+ }
+ //printf("nativeSend finished \n"); fflush(stdout);
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIssend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILxdev/mxdev/MXSendRequest;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIssend
+ (JNIEnv *env, jobject obj1, jobject buf, jobject dstID, jint tag,
+ jint context, jint sbuf_length, jint dbuf_length, jobject req) {
+ //.. ..
+ int offset = 8;
+ /* stuff required for non-blocking */
+ jclass req_class = (*env)->GetObjectClass(env, req);
+ jfieldID reqhandleID =
+ (*env)->GetFieldID(env, req_class, "handle", "J") ;
+ jfieldID dbufreqhandleID =
+ (*env)->GetFieldID(env, req_class, "dbufHandle", "J");
+ jfieldID lepID =
+ (*env)->GetFieldID(env, req_class, "localEndpointHandle", "J") ;
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, req_class, "bufferHandle", "Lmpjbuf/Buffer;") ;
+ jfieldID dbuflenID =
+ (*env)->GetFieldID(env, req_class, "dbuflen", "I") ;
+
+ /* MX accessories for calling mx_isend */
+ mx_return_t rc ;
+ mx_request_t send_handle;
+ mx_status_t status;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_send, dbuf_tag ;
+ uint32_t result;
+ mx_endpoint_addr_t * dest;
+ dest = (mx_endpoint_addr_t *)
+ ((*env)->GetLongField(env, dstID, processhandleID )) ;
+
+ match_send = PRI_MATCH(context, myRank, tag);
+ //printf("send_recv U32 <%x> \n",MX_U32(match_send));fflush(stdout);
+ //printf("send_recv L32 <%x> \n",MX_L32(match_send));fflush(stdout);
+
+ /* static buffer related declarations */
+ char *buffer_address=NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+
+ /* dynamic buffer related declarations */
+ jboolean isCopy=JNI_TRUE;
+ jbyteArray dynamicBuffer ;
+ jbyte* dBuffer;
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer, FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+
+ /* get dynamic buffer related stuff */
+ dynamicBuffer =
+ (jbyteArray) (*env)->GetObjectField(env,buf,
+ FID_mpjbuf_Buffer_dynamicBuffer);
+ if(dbuf_length > 0) {
+ dBuffer = (*env)->GetByteArrayElements(env, dynamicBuffer, &isCopy);
+ }
+ //.. write the first eight bytes ..
+ // _________________________
+ // | E | X | X | X | DSIZE |
+ // -------------------------
+ char encoding = 1;
+ buffer_address[0] = encoding ;
+ buffer_address[4] = (((unsigned int) dbuf_length) >> 24) & 0xFF ;
+ buffer_address[5] = (((unsigned int) dbuf_length) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbuf_length) >> 8) & 0xFF ;
+ buffer_address[7] = ((unsigned int) dbuf_length) & 0xFF;
+
+ /* compose message, sort out tag/context and remote endpoints */
+ buffer_desc[0].segment_ptr = buffer_address ;
+ buffer_desc[0].segment_length = sbuf_length+offset;
+
+ /* send message */
+ //printf("native:send sending \n");
+ rc = mx_issend(local_endpoint, buffer_desc, 1, * dest, match_send,
+ NULL, &send_handle);
+ //printf("native:send sent \n");
+
+ (*env)->SetLongField(env,req,reqhandleID,(jlong)send_handle);
+ (*env)->SetLongField(env,req,lepID,(jlong)local_endpoint);
+ (*env)->SetObjectField(env,req,bufferhandleID,buf);
+
+ mx_segment_t dbuf_desc [1] ;
+ mx_request_t dbufsend_handle;
+
+ dbuf_desc[0].segment_ptr = dBuffer ;
+ dbuf_desc[0].segment_length = dbuf_length;
+
+ if(dbuf_length > 0) {
+ dbuf_tag = SEC_MATCH(context, myRank, tag);
+ rc = mx_isend(local_endpoint, dbuf_desc, 1, * dest, dbuf_tag,
+ NULL, &dbufsend_handle);
+ }
+
+ (*env)->SetIntField(env,req,dbuflenID,dbuf_length);
+ (*env)->SetLongField(env,req,dbufreqhandleID,(jlong)dbufsend_handle );
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIsend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILxdev/mxdev/MXSendRequest;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIsend
+ (JNIEnv *env, jobject obj1, jobject buf, jobject dstID,
+ jint tag, jint context, jint sbuf_length, jint dbuf_length,
+ jobject req, jint offset) {
+
+ /* stuff required for non-blocking */
+ jclass req_class = (*env)->GetObjectClass(env, req);
+ jfieldID reqhandleID =
+ (*env)->GetFieldID(env, req_class, "handle", "J") ;
+ jfieldID dbufreqhandleID =
+ (*env)->GetFieldID(env, req_class, "dbufHandle", "J");
+ jfieldID lepID =
+ (*env)->GetFieldID(env, req_class, "localEndpointHandle", "J") ;
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, req_class, "bufferHandle", "Lmpjbuf/Buffer;") ;
+ jfieldID dbuflenID =
+ (*env)->GetFieldID(env, req_class, "dbuflen", "I") ;
+
+ /* MX accessories for calling mx_isend */
+ mx_return_t rc ;
+ mx_request_t send_handle;
+ mx_status_t status;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_send, dbuf_tag ;
+ uint32_t result;
+ mx_endpoint_addr_t * dest;
+ dest = (mx_endpoint_addr_t *)
+ ((*env)->GetLongField(env, dstID, processhandleID )) ;
+
+ match_send = PRI_MATCH(context, myRank, tag);
+ //printf("send_recv U32 <%x> \n",MX_U32(match_send));fflush(stdout);
+ //printf("send_recv L32 <%x> \n",MX_L32(match_send));fflush(stdout);
+
+ /* static buffer related declarations */
+ char *buffer_address=NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+
+ /* dynamic buffer related declarations */
+ jboolean isCopy=JNI_TRUE;
+ jbyteArray dynamicBuffer ;
+ jbyte* dBuffer;
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer, FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+
+ /* get dynamic buffer related stuff */
+ dynamicBuffer =
+ (jbyteArray) (*env)->GetObjectField(env,buf,
+ FID_mpjbuf_Buffer_dynamicBuffer);
+ if(dbuf_length > 0) {
+ dBuffer = (*env)->GetByteArrayElements(env, dynamicBuffer, &isCopy);
+ }
+ //.. write the first eight bytes ..
+ // _________________________
+ // | E | X | X | X | DSIZE |
+ // -------------------------
+ char encoding = 1;
+ buffer_address[0] = encoding ;
+ buffer_address[4] = (((unsigned int) dbuf_length) >> 24) & 0xFF ;
+ buffer_address[5] = (((unsigned int) dbuf_length) >> 16) & 0xFF;
+ buffer_address[6] = (((unsigned int) dbuf_length) >> 8) & 0xFF ;
+ buffer_address[7] = ((unsigned int) dbuf_length) & 0xFF;
+
+ /* compose message, sort out tag/context and remote endpoints */
+ buffer_desc[0].segment_ptr = buffer_address ;
+ buffer_desc[0].segment_length = sbuf_length+offset;
+
+ /* send message */
+ //printf("native:send sending \n"); fflush(stdout);
+ rc = mx_isend(local_endpoint, buffer_desc, 1, * dest, match_send,
+ NULL, &send_handle);
+
+ if(rc != MX_SUCCESS) {
+ printf("error in isend"); fflush(stdout);
+ }
+ //printf("native:send sent \n"); fflush(stdout);
+
+ (*env)->SetLongField(env,req,reqhandleID,(jlong)send_handle);
+ (*env)->SetLongField(env,req,lepID,(jlong)local_endpoint);
+ (*env)->SetObjectField(env,req,bufferhandleID,buf);
+
+ mx_segment_t dbuf_desc [1] ;
+ dbuf_tag = SEC_MATCH(context, myRank, tag);
+ mx_request_t dbufsend_handle;
+
+ dbuf_desc[0].segment_ptr = dBuffer ;
+ dbuf_desc[0].segment_length = dbuf_length;
+ if(dbuf_length > 0) {
+ rc = mx_isend(local_endpoint, dbuf_desc, 1, * dest, dbuf_tag,
+ NULL, &dbufsend_handle);
+ }
+
+ (*env)->SetLongField(env,req,dbufreqhandleID,(jlong)dbufsend_handle );
+ (*env)->SetIntField(env,req,dbuflenID,dbuf_length);
+
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeRecv
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILmpjdev/Status;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeRecv
+ (JNIEnv *env, jobject this, jobject buf, jobject srcID, jint tag,
+ jint context, jobject status, jint any_src) {
+
+ jboolean isCopy = JNI_TRUE;
+
+ //jclass req_class = (*env)->GetObjectClass(env, req);
+ //we probably need to get hold of status here ...
+ int src_id = ((*env)->GetIntField(env, srcID, processidID )) ;
+
+ /* static buffer declarations */
+ char *buffer_address=NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+ //int * sbuf_length;
+ int capacity ;
+
+ /* dynamic buffer declarations */
+ jbyteArray darr;
+ jbyte* dBuffer;
+
+ /* MX related declarations */
+ mx_return_t rc ;
+ mx_request_t recv_handle ;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_recv, match_recv2, match_mask , proc_mask, tag_mask ;
+ mx_status_t recv_status;
+ uint32_t result;
+
+ if(tag == ANY_TAG) {
+ tag_mask = EMPTY ;
+ }
+ else {
+ tag_mask = MASK_TAG ;
+ }
+
+ if(any_src == 1) {
+ src_id = 0 ;
+ proc_mask = EMPTY;
+ }
+ else {
+ proc_mask = MASK_SRC ;
+ }
+
+ match_mask = MATCH_CONTEXT | proc_mask | tag_mask ;
+
+ if(tag == ANY_TAG) {
+ match_recv = PRI_MATCH(context, src_id, 0);
+ match_recv2 = SEC_MATCH(context, src_id, 0);
+ } else {
+ match_recv = PRI_MATCH(context, src_id, tag);
+ match_recv2 = SEC_MATCH(context, src_id, tag);
+ }
+
+ //printf("src_id <%d> \n", src_id );
+ //printf("context <%d> \n", context);
+ //printf("match_mask U32 <%x> \n",MX_U32(match_mask));
+ //printf("match_recv U32 <%x> \n",MX_U32(match_recv));
+ //printf("match_mask L32 <%x> \n",MX_L32(match_mask));
+ //printf("match_recv L32 <%x> \n",MX_L32(match_recv));
+ //fflush(stdout);
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer,
+ FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+ capacity = (unsigned int)
+ (*env)->GetIntField(env,buf,FID_mpjbuf_Buffer_capacity);
+
+ /* compose message ,sort out tag/context*/
+ buffer_desc[0].segment_ptr = buffer_address;
+ buffer_desc[0].segment_length = capacity+8 ;//+offset ..
+
+ /* recv the message */
+ rc = mx_irecv(local_endpoint, buffer_desc, 1, match_recv, match_mask,
+ NULL, &recv_handle);
+
+ /* wait for it complete */
+ rc = mx_wait(local_endpoint, & recv_handle, MX_INFINITE,
+ &recv_status, &result);
+ //printf("********** \n");
+ //printf("tag <%d> \n", GET_TAG(recv_status.match_info));
+ //printf("src <%d> \n", GET_SRC(recv_status.match_info));
+ //printf("********** \n");
+ //status.src = recv_status.match_info ;
+ //need a translation back from src to srcID ...
+ //status.tag = recv_status.match_info ;
+
+ (*env)->SetIntField(env,status, status_src_ID,
+ GET_SRC(recv_status.match_info) );
+ (*env)->SetIntField(env,status, status_tag_ID,
+ GET_TAG(recv_status.match_info) );
+ (*env)->SetIntField(env,status, countInBytesID ,
+ recv_status.msg_length - 16); //-8 is offset ...
+
+ //printf("recv:req called wait for control message \n"); fflush(stdout);
+
+ char encoding = 1;
+ int dbuf_length ;
+ //.. dbuf_length ..
+ encoding = buffer_address[0] ;
+ dbuf_length =
+ (((int)(unsigned char) buffer_address[4]) << 24) |
+ (((int)(unsigned char) buffer_address[5]) << 16) |
+ (((int)(unsigned char) buffer_address[6]) << 8) |
+ (((int)(unsigned char) buffer_address[7]) );
+
+ //printf("dbuf_length [after strange] <%d> \n",dbuf_length);
+
+ //int dbuf_length = byte22int(buffer_address,0);
+ int sbuf_length = recv_status.msg_length - 8 ; //- offset
+
+ if(dbuf_length > 0) {
+ darr = (*env)->NewByteArray (env, dbuf_length);
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+ buffer_desc[0].segment_ptr = dBuffer;
+ buffer_desc[0].segment_length = dbuf_length;
+
+ rc = mx_irecv(local_endpoint, buffer_desc, 1, match_recv2, match_mask,
+ NULL, &recv_handle);
+
+ /* wait for it complete */
+ rc = mx_wait(local_endpoint, & recv_handle, MX_INFINITE,
+ &recv_status, &result);
+
+ (*env)->SetByteArrayRegion(env,darr,0,dbuf_length,dBuffer);
+ jmethodID setdbuf = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, buf, setdbuf, darr);
+
+ }
+
+ jmethodID set_size = (*env)->GetMethodID(env, CL_mpjbuf_Buffer,
+ "setSize", "(I)V");
+ (*env)->CallVoidMethod(env, buf, set_size, sbuf_length );
+ //---------------- this is non-blocking recv ...
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIrecv
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILmpjdev/Status;Lxdev/mxdev/MXRecvRequest;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIrecv
+ (JNIEnv *env, jobject obj1, jobject buf, jobject srcID, jint tag,
+ jint context, jobject status, jobject req, jint any_src) {
+
+ jboolean isCopy = JNI_TRUE;
+
+ /* We could move these to init methods */
+ jclass req_class = (*env)->GetObjectClass(env, req);
+ jfieldID matchrecvhandleID =
+ (*env)->GetFieldID(env, req_class, "matchRecvHandle", "J") ;
+ jfieldID ctrlmsghandleID =
+ (*env)->GetFieldID(env, req_class, "ctrlMsgHandle", "J") ;
+ jfieldID matchrecvmaskhandleID =
+ (*env)->GetFieldID(env, req_class, "matchRecvMaskHandle", "J") ;
+ jfieldID bufferaddresshandleID =
+ (*env)->GetFieldID(env, req_class, "bufferAddressHandle", "J") ;
+ jfieldID reqhandleID =
+ (*env)->GetFieldID(env, req_class, "handle", "J") ;
+ jfieldID lepID =
+ (*env)->GetFieldID(env, req_class, "localEndpointHandle", "J") ;
+ jfieldID bufferhandleID =
+ (*env)->GetFieldID(env, req_class,
+ "bufferHandle", "Lmpjbuf/Buffer;") ;
+
+ int src_id = ((*env)->GetIntField(env, srcID, processidID )) ;
+
+ /* static buffer declarations */
+ char *buffer_address = NULL;
+ jobject staticBuffer;
+ jbyteArray directbuffer;
+ //int * sbuf_length;
+ int capacity ;
+
+ /* dynamic buffer declarations */
+ jbyteArray darr;
+ jbyte* dBuffer;
+
+ /* MX related declarations */
+ mx_return_t rc ;
+ mx_request_t recv_handle ;
+ mx_segment_t buffer_desc[1];
+ uint64_t match_recv, match_recv2, match_mask , proc_mask, tag_mask ;
+ mx_status_t recv_status;
+ uint32_t result;
+
+ if(tag == ANY_TAG) {
+ tag_mask = EMPTY ;
+ }
+ else {
+ tag_mask = MASK_TAG ;
+ }
+
+ if(any_src == 1) {
+ src_id = 0 ;
+ proc_mask = EMPTY;
+ }
+ else {
+ proc_mask = MASK_SRC ;
+ }
+
+ match_mask = MATCH_CONTEXT | proc_mask | tag_mask ;
+
+ if(tag == ANY_TAG) {
+ match_recv = PRI_MATCH(context, src_id, 0);
+ match_recv2 = SEC_MATCH(context, src_id, 0);
+ } else {
+ match_recv = PRI_MATCH(context, src_id, tag);
+ match_recv2 = SEC_MATCH(context, src_id, tag);
+ }
+
+ //printf("src_id <%d> \n", src_id );
+ //printf("context <%d> \n", context);
+ //printf("match_mask U32 <%x> \n",MX_U32(match_mask));
+ //printf("match_recv U32 <%x> \n",MX_U32(match_recv));
+ //printf("match_mask L32 <%x> \n",MX_L32(match_mask));
+ //printf("match_recv L32 <%x> \n",MX_L32(match_recv));
+ //fflush(stdout);
+
+ /* get static buffer related stuff */
+ staticBuffer =
+ (*env)->GetObjectField(env,buf,FID_mpjbuf_Buffer_staticBuffer);
+ directbuffer =
+ (jbyteArray) (*env)->GetObjectField(env,
+ staticBuffer,
+ FID_mpjbuf_NIOBuffer_buffer);
+ buffer_address = (char *)(*env)->GetDirectBufferAddress(env,
+ (jobject)directbuffer);
+ capacity = (unsigned int)
+ (*env)->GetIntField(env,buf,FID_mpjbuf_Buffer_capacity);
+
+ /* compose message ,sort out tag/context*/
+ buffer_desc[0].segment_ptr = buffer_address;
+ buffer_desc[0].segment_length = capacity+8 ;//+offset ..
+
+ //JRequestStruct *jreq = NULL;
+ //jreq = (JRequestStruct *) malloc(sizeof(JRequestStruct)) ;
+ //jobject globalRequestObject = (*env)->NewGlobalRef(env, req);
+ //jreq->jrequest = globalRequestObject ;
+
+ /* recv the message */
+ rc = mx_irecv(local_endpoint, buffer_desc, 1, match_recv, match_mask,
+ NULL, &recv_handle); //jreq instead of NULL
+ if(rc != MX_SUCCESS) {
+ printf("error in irecv"); fflush(stdout);
+ }
+
+ (*env)->SetLongField(env,req,reqhandleID,(jlong)recv_handle);
+ (*env)->SetLongField(env,req,lepID,(jlong)local_endpoint);
+ (*env)->SetObjectField(env,req,bufferhandleID,buf);
+ (*env)->SetLongField(env,req,matchrecvhandleID,(jlong)match_recv2);
+ (*env)->SetLongField(env,req,matchrecvmaskhandleID,(jlong)match_mask);
+ (*env)->SetLongField(env,req,bufferaddresshandleID,(jlong)buffer_address);
+
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIprobe
+ * Signature: (Lxdev/ProcessID;IILmpjdev/Status;II)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXDevice_nativeIprobe
+ (JNIEnv *env, jobject jthis, jobject srcID, jint tag, jint context,
+ jobject status, jint any_src, jint isCompleted ) {
+ //printf("native probe method \n");
+ mx_return_t rc;
+ mx_status_t c_status;
+ uint64_t result = EMPTY ;
+ uint64_t match_recv, proc_mask, tag_mask, match_mask ;
+ int src_id = ((*env)->GetIntField(env, srcID, processidID )) ;
+
+ if(tag == ANY_TAG) {
+ tag_mask = EMPTY ;
+ }
+ else {
+ tag_mask = MASK_TAG ;
+ }
+
+ if(any_src == 1) {
+ src_id = 0 ;
+ proc_mask = EMPTY;
+ }
+ else {
+ proc_mask = MASK_SRC ;
+ }
+
+ match_mask = MATCH_CONTEXT | proc_mask | tag_mask ;
+
+ if(tag == ANY_TAG) {
+ match_recv = PRI_MATCH(context, src_id, 0);
+ } else {
+ match_recv = PRI_MATCH(context, src_id, tag);
+ }
+
+ //printf(" result upper (b)<%d> \n", MX_U32(result));
+ //printf(" result lower (b)<%d> \n", MX_L32(result));
+ rc = mx_iprobe(local_endpoint,
+ match_recv,
+ match_mask,
+ &c_status,
+ &result);
+ //printf(" result upper (a)<%d> \n", MX_U32(result));
+ //printf(" result lower (a)<%d> \n", MX_L32(result));
+
+ if(result == EMPTY) {
+ //printf(" aint any message "); fflush(stdout);
+ }
+ else {
+ //printf(" yes message "); fflush(stdout);
+ isCompleted = 1;
+ (*env)->SetIntField(env,status, status_src_ID,
+ GET_SRC(c_status.match_info) );
+ (*env)->SetIntField(env,status, status_tag_ID,
+ GET_TAG(c_status.match_info) );
+ (*env)->SetIntField(env,status, countInBytesID ,
+ c_status.msg_length - 16); //-8 is offset ...
+ }
+
+ return isCompleted ;
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeProbe
+ * Signature: (Lxdev/ProcessID;IILmpjdev/Status;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeProbe
+ (JNIEnv *env, jobject jthis, jobject srcID, jint tag, jint context,
+ jobject status, jint any_src) {
+ //printf("native iprobe method \n");
+ mx_return_t rc;
+ mx_status_t c_status;
+ uint64_t result ;
+
+ uint64_t match_recv, proc_mask, tag_mask, match_mask ;
+ int src_id = ((*env)->GetIntField(env, srcID, processidID )) ;
+
+ if(tag == ANY_TAG) {
+ tag_mask = EMPTY ;
+ }
+ else {
+ tag_mask = MASK_TAG ;
+ }
+
+ if(any_src == 1) {
+ src_id = 0 ;
+ proc_mask = EMPTY;
+ }
+ else {
+ proc_mask = MASK_SRC ;
+ }
+
+ match_mask = MATCH_CONTEXT | proc_mask | tag_mask ;
+
+ if(tag == ANY_TAG) {
+ match_recv = PRI_MATCH(context, src_id, 0);
+ //match_recv2 = SEC_MATCH(context, src_id, 0);
+ } else {
+ match_recv = PRI_MATCH(context, src_id, tag);
+ //match_recv2 = SEC_MATCH(context, src_id, tag);
+ }
+
+ rc = mx_probe(local_endpoint,
+ MX_INFINITE,
+ match_recv,
+ match_mask,
+ &c_status,
+ &result);
+ (*env)->SetIntField(env,status, status_src_ID,
+ GET_SRC(c_status.match_info) );
+ (*env)->SetIntField(env,status, status_tag_ID,
+ GET_TAG(c_status.match_info) );
+ (*env)->SetIntField(env,status, countInBytesID ,
+ c_status.msg_length - 16); //-8 is offset ...
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativePeek
+ * Signature: (Lmpjdev/Status;)J
+ */
+JNIEXPORT jlong JNICALL Java_xdev_mxdev_MXDevice_nativePeek
+ (JNIEnv *env, jclass jthis, jobject status) {
+ //printf(" nativePeek \n");fflush(stdout);
+ mx_request_t peekedRequest ;
+ mx_return_t rc ;
+ //mx_status_t status ;
+ uint32_t result ;
+ //JRequestStruct *jrequest ;
+ //jobject javaRequest, statusInRequest ;
+
+ rc = mx_peek(local_endpoint, MX_INFINITE, &peekedRequest, &result);
+
+ if(rc != MX_SUCCESS) {
+ printf(" error while peeking the message \n");
+ }
+
+ if(result) {
+ //printf(" message peeked successfully \n"); fflush(stdout);
+ }
+
+ /* commented because of hashtable approach ...
+
+ rc = mx_wait( local_endpoint, &peekedRequest,
+ MX_INFINITE, &status, &result);
+
+ jrequest = (JRequestStruct *) status.context ;
+ javaRequest = jrequest->jrequest ;
+ statusInRequest = (*env)->GetObjectField( env,
+ javaRequest, FID_xdev_mxdev_MXRequest_status );
+ //.. save javaRequest in Request's long field ..
+ (*env)->SetLongField(env,javaRequest, FID_xdev_mxdev_MXRequest_requestStruct,
+ (jlong)jrequest);
+ //printf(" returning from native peek \n"); fflush(stdout);
+ //jobject copiedJavaRequest = javaRequest ;
+ //(*env)->DeleteGlobalRef(env, javaRequest);
+ (*env)->SetIntField(env,statusInRequest, status_src_ID,
+ GET_SRC(status.match_info) );
+ (*env)->SetIntField(env,statusInRequest, status_tag_ID,
+ GET_TAG(status.match_info) );
+ (*env)->SetIntField(env,statusInRequest, countInBytesID,
+ status.msg_length - 8);
+ printf(" length <%d> \n ",status.msg_length) ; fflush(stdout);
+ return javaRequest ;
+ */
+ // .. returnthe address of request struct ..
+ return peekedRequest ;
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: deletePeekedRequest
+ * Signature: (Lxdev/mxdev/MXRequest;J)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_deletePeekedRequest
+ (JNIEnv *env, jclass jthis, jobject peekedRequest, jlong requestStruct) {
+ (*env)->DeleteGlobalRef(env, peekedRequest);
+ //JRequestStruct *jrequest = (JRequestStruct *) requestStruct ;
+ //free(jrequest);
+}
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativePeek
+ * Signature: (Lmpjdev/Status;)V
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativePeek
+ (JNIEnv *env, jobject jthis, jobject requestObject) {
+ printf(" nativePeek \n");
+ mx_request_t request ;
+ mx_return_t rc ;
+ uint32_t result ;
+ rc = mx_peek( local_endpoint, MX_INFINITE, &request, &result);
+ if(rc == MX_SUCCESS) {
+ //printf(" mx_peek successful \n"); fflush(stdout);
+ }
+ if(result) {
+ printf(" a message has been peeked in nativeIwaitany \n"); fflush(stdout);
+ }
+
+ // complete comms ...
+ mx_status_t recv_status ;
+
+ rc = mx_wait( local_endpoint, &request, MX_INFINITE, &recv_status, &result);
+ JRequestStruct *jrequest = (JRequestStruct *) recv_status.context ;
+ jobject javaRequest = jrequest->jrequest ;
+ printf("1 \n"); fflush(stdout);
+
+ jclass req_class = (*env)->GetObjectClass(env, javaRequest );
+
+ //.. get the comms ..
+
+ if(rc != MX_SUCCESS) {
+ printf(" error while calling mx_wait \n");
+ }
+
+ //mx_status_t recv_status;
+ mx_request_t reqhandle ;
+ mx_endpoint_t mlep ;
+ jobject buffer ;
+ uint64_t match_recv;
+ uint64_t match_mask;
+ char * buffer_address;
+ mx_segment_t buffer_desc[1];
+
+ reqhandle = (mx_request_t) ((*env)->GetLongField(env, javaRequest,
+ reqhandleID )) ;
+ mx_request_t dreq ;
+ mlep = (mx_endpoint_t) ((*env)->GetLongField(env, javaRequest,
+ m_local_endpoint ));
+
+ printf("3 \n"); fflush(stdout);
+ match_recv = (uint64_t) ((*env)->GetLongField(env,
+ javaRequest, matchrecvhandleID)) ;
+ match_mask = (uint64_t)
+ ((*env)->GetLongField(env, javaRequest, matchrecvmaskhandleID)) ;
+ buffer_address = (char *) ((*env)->GetLongField(env,
+ javaRequest, bufferaddresshandleID)) ;
+ buffer = ((*env)->GetObjectField(env, javaRequest,
+ bufferhandleID )) ;
+ jclass mpjbuf_class = (*env)->GetObjectClass(env, buffer);
+ jbyteArray darr;
+ jbyte* dBuffer;
+ jboolean isCopy = JNI_TRUE;
+ char encoding = 1;
+ int dbuf_length ;
+ //.. dbuf_length ..
+ encoding = buffer_address[0] ;
+ dbuf_length =
+ (((int)(unsigned char) buffer_address[4]) << 24) |
+ (((int)(unsigned char) buffer_address[5]) << 16) |
+ (((int)(unsigned char) buffer_address[6]) << 8) |
+ (((int)(unsigned char) buffer_address[7]) );
+
+ printf("dbuf_length [after strange] <%d> \n",dbuf_length); fflush(stdout);
+
+ //int dbuf_length = byte22int(buffer_address,0);
+ int sbuf_length = recv_status.msg_length - 8 ; //- offset
+
+ if(dbuf_length > 0) {
+ darr = (*env)->NewByteArray (env, dbuf_length);
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+ buffer_desc[0].segment_ptr = dBuffer;
+ buffer_desc[0].segment_length = dbuf_length;
+ //printf(" calling mx_irecv in nativeIwait \n"); fflush(stdout);
+
+ rc = mx_irecv(mlep, buffer_desc, 1, match_recv, match_mask,
+ NULL, &dreq);
+ if(rc != MX_SUCCESS) {
+ printf(" return code is not successful \n"); fflush(stdout);
+ }
+
+ rc = mx_wait(mlep, & dreq, MX_INFINITE,
+ &recv_status, &result);
+ if(rc != MX_SUCCESS) {
+ printf(" return code is not successful \n"); fflush(stdout);
+ }
+ //printf(" received \n"); fflush(stdout);
+ (*env)->SetByteArrayRegion(env,darr,0,dbuf_length,dBuffer);
+ jmethodID setdbuf = (*env)->GetMethodID(env, mpjbuf_class,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, buffer, setdbuf, darr);
+
+ } else {
+ //printf(" no dynamic message \n") ;
+ }
+
+ jmethodID set_size = (*env)->GetMethodID(env, mpjbuf_class,
+ "setSize", "(I)V");
+ (*env)->CallVoidMethod(env, buffer, set_size, sbuf_length );
+ //printf("recvRequest wait returns \n");
+ (*env)->SetIntField(env,javaRequest, testcalledID, 1);
+ //printf("recv:req calling wait for control message \n"); fflush(stdout);
+ //printf("status.msg_length <%d> \n", recv_status.msg_length );
+ //(*env)->SetIntField(env,status, status_src_ID,
+ // GET_SRC(recv_status.match_info) );
+ //(*env)->SetIntField(env,status, status_tag_ID,
+ // GET_TAG(recv_status.match_info) );
+ //(*env)->SetIntField(env,status, countInBytesID,
+ // recv_status.msg_length - 16);//-16
+
+ //.. extract JRequest ..
+
+ //.. figure out if it is send or recv request ..
+
+ //if(recvrequest) {
+ //.. copy paste code from iwait of recvrequest ..
+ //}
+
+ //if(sendrequest) {
+ //.. copy paste code from iwait of sendrequest ..
+ //}
+}
+*/
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeFinish
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeFinish
+ (JNIEnv *env, jobject obj1) {
+
+ //printf("native:finish process <%d> starting finish \n",myRank );
+ //fflush(stdout);
+ //sleep(5);
+ mx_return_t rc;
+ //printf("native:finish process <%d> will close endpoint \n",myRank );
+ //fflush(stdout);
+ //fflush(stdout);
+ rc = mx_close_endpoint(local_endpoint);
+ if(rc != MX_SUCCESS) {
+ //printf("error in nativeFinish "); fflush(stdout);
+ }
+ //printf("native:finish process <%d> closed endpoint \n",myRank );
+ //fflush(stdout);
+ //fflush(stdout);
+ free(peer_endpoints);
+ peer_endpoints = NULL;
+
+ if(rc == MX_SUCCESS) {
+ //printf("closed endpoint \n");
+ }
+
+ //printf("native:finish process <%d> calling finalize \n",myRank ) ;
+ //fflush(stdout);
+
+ rc = mx_finalize();
+
+ if(rc == MX_SUCCESS) {
+ //printf("native:finish process <%d> called finalize \n", myRank );
+ //fflush(stdout);
+ }
+
+}
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.h b/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.h
new file mode 100644
index 0000000..6250d33
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXDevice.h
@@ -0,0 +1,115 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class xdev_mxdev_MXDevice */
+
+#ifndef _Included_xdev_mxdev_MXDevice
+#define _Included_xdev_mxdev_MXDevice
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef xdev_mxdev_MXDevice_ANY_SOURCE
+#define xdev_mxdev_MXDevice_ANY_SOURCE -2L
+/* Inaccessible static: ANY_SRC */
+#undef xdev_mxdev_MXDevice_ANY_TAG
+#define xdev_mxdev_MXDevice_ANY_TAG -2L
+/* Inaccessible static: requestMap */
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeInit
+ * Signature: ([Ljava/lang/String;I[Ljava/lang/String;[II[Lxdev/mxdev/MXProcessID;JJ)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeInit
+ (JNIEnv *, jobject, jobjectArray, jint, jobjectArray, jintArray, jint, jobjectArray, jlong, jlong);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIsend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIIILxdev/mxdev/MXSendRequest;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIsend
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jint, jint, jobject, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeSend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIII)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeSend
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jint, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIssend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIIILxdev/mxdev/MXSendRequest;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIssend
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jint, jint, jobject);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeSsend
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IIII)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeSsend
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jint, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIrecv
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILmpjdev/Status;Lxdev/mxdev/MXRecvRequest;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeIrecv
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jobject, jobject, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeRecv
+ * Signature: (Lmpjbuf/Buffer;Lxdev/ProcessID;IILmpjdev/Status;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeRecv
+ (JNIEnv *, jobject, jobject, jobject, jint, jint, jobject, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeProbe
+ * Signature: (Lxdev/ProcessID;IILmpjdev/Status;I)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeProbe
+ (JNIEnv *, jobject, jobject, jint, jint, jobject, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeIprobe
+ * Signature: (Lxdev/ProcessID;IILmpjdev/Status;II)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXDevice_nativeIprobe
+ (JNIEnv *, jobject, jobject, jint, jint, jobject, jint, jint);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativePeek
+ * Signature: (Lmpjdev/Status;)J
+ */
+JNIEXPORT jlong JNICALL Java_xdev_mxdev_MXDevice_nativePeek
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: deletePeekedRequest
+ * Signature: (Lxdev/mxdev/MXRequest;J)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_deletePeekedRequest
+ (JNIEnv *, jclass, jobject, jlong);
+
+/*
+ * Class: xdev_mxdev_MXDevice
+ * Method: nativeFinish
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXDevice_nativeFinish
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.c b/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.c
new file mode 100644
index 0000000..5522236
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.c
@@ -0,0 +1,297 @@
+/** The MIT License
+
+Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+*/
+#include <stdio.h>
+#include "jni.h"
+#include "myriexpress.h"
+#include "mxdev_const.h"
+#include "xdev_mxdev_MXRecvRequest.h"
+
+jfieldID reqhandleID;
+jfieldID m_local_endpoint;
+jfieldID bufferhandleID;
+jfieldID matchrecvhandleID;
+jfieldID matchrecvmaskhandleID;
+jfieldID bufferaddresshandleID ;
+jfieldID status_src_ID ;
+jfieldID status_tag_ID ;
+jfieldID testcalledID ;
+jfieldID countInBytesID ;
+jfieldID isPeekedID ;
+
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeIwait
+ * Signature: (Lmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXRecvRequest_nativeIwait
+ (JNIEnv *env, jobject jthis, jobject status) {
+ //printf(" native Iwait (Request) \n"); fflush(stdout);
+ int testCalled = ((*env)->GetIntField(env,jthis,testcalledID)) ;
+ int isPeeked = ((*env)->GetIntField(env,jthis,isPeekedID)) ;
+
+ if(testCalled == 1) {
+ //((*env)->SetIntField(env,jthis,testcalledID,0)) ;
+ return 1;
+ }
+
+ uint32_t result;
+ mx_status_t recv_status;
+ mx_request_t reqhandle ;
+ mx_return_t rc;
+ mx_endpoint_t mlep ;
+ jobject buffer ;
+ uint64_t match_recv;
+ uint64_t match_mask;
+ char * buffer_address;
+ mx_segment_t buffer_desc[1];
+ jclass req_class = (*env)->GetObjectClass(env, jthis);
+ reqhandle = (mx_request_t) ((*env)->GetLongField(env, jthis, reqhandleID )) ;
+ mx_request_t dreq ;
+ mlep = (mx_endpoint_t) ((*env)->GetLongField(env, jthis, m_local_endpoint ));
+ match_recv = (uint64_t) ((*env)->GetLongField(env,
+ jthis, matchrecvhandleID)) ;
+ match_mask = (uint64_t)
+ ((*env)->GetLongField(env, jthis, matchrecvmaskhandleID)) ;
+ buffer_address = (char *) ((*env)->GetLongField(env,
+ jthis, bufferaddresshandleID)) ;
+ buffer = ((*env)->GetObjectField(env, jthis,
+ bufferhandleID )) ;
+ jclass mpjbuf_class = (*env)->GetObjectClass(env, buffer);
+ jbyteArray darr;
+ jbyte* dBuffer;
+ jboolean isCopy = JNI_TRUE;
+ //printf("recv:req calling wait for control message \n"); fflush(stdout);
+ if(!isPeeked) {
+ /* wait for it complete */
+ rc = mx_wait(mlep, & reqhandle, MX_INFINITE,
+ &recv_status, &result);
+ if(rc != MX_SUCCESS) {
+ printf("error in recvRequest"); fflush(stdout);
+ }
+ //printf("status.msg_length <%d> \n", recv_status.msg_length );
+ (*env)->SetIntField(env,status, status_src_ID,
+ GET_SRC(recv_status.match_info) );
+ (*env)->SetIntField(env,status, status_tag_ID,
+ GET_TAG(recv_status.match_info) );
+ (*env)->SetIntField(env,status, countInBytesID,
+ recv_status.msg_length - 16 );//-16
+ }
+
+ //printf("recv:req called wait for control message \n"); fflush(stdout);
+ char encoding = 1;
+ int dbuf_length ;
+ //.. dbuf_length ..
+ encoding = buffer_address[0] ;
+ dbuf_length =
+ (((int)(unsigned char) buffer_address[4]) << 24) |
+ (((int)(unsigned char) buffer_address[5]) << 16) |
+ (((int)(unsigned char) buffer_address[6]) << 8) |
+ (((int)(unsigned char) buffer_address[7]) );
+
+ //printf("dbuf_length [after strange] <%d> \n",dbuf_length);
+ //int dbuf_length = byte22int(buffer_address,0);
+ int sbuf_length = 0;
+
+ if(!isPeeked) {
+ //this should really be - 16 ..8 is sendoverhead and device also
+ //uses the first 8 bytes ..so in all should be 16 ...
+ sbuf_length = recv_status.msg_length - 8 ; //- offset
+ }
+ else {
+ sbuf_length = (*env)->GetIntField(env, status, countInBytesID);
+ }
+
+ if(dbuf_length > 0) {
+ darr = (*env)->NewByteArray (env, dbuf_length);
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+ buffer_desc[0].segment_ptr = dBuffer;
+ buffer_desc[0].segment_length = dbuf_length;
+ //printf(" calling mx_irecv in nativeIwait \n"); fflush(stdout);
+ /* recv the message */
+ rc = mx_irecv(mlep, buffer_desc, 1, match_recv, match_mask,
+ NULL, &dreq);
+ if(rc != MX_SUCCESS) {
+ printf(" return code is not successful \n"); fflush(stdout);
+ }
+ /* wait for it complete */
+ rc = mx_wait(mlep, & dreq, MX_INFINITE,
+ &recv_status, &result);
+ if(rc != MX_SUCCESS) {
+ printf(" return code is not successful \n"); fflush(stdout);
+ }
+ //printf(" received \n"); fflush(stdout);
+ (*env)->SetByteArrayRegion(env,darr,0,dbuf_length,dBuffer);
+ jmethodID setdbuf = (*env)->GetMethodID(env, mpjbuf_class,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, buffer, setdbuf, darr);
+
+ } else {
+ //printf(" no dynamic message \n") ;
+ }
+
+ jmethodID set_size = (*env)->GetMethodID(env, mpjbuf_class,
+ "setSize", "(I)V");
+ (*env)->CallVoidMethod(env, buffer, set_size, sbuf_length );
+ //printf("recvRequest wait returns \n");
+ (*env)->SetIntField(env,jthis, testcalledID, 1);
+
+}
+
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeItest
+ * Signature: (Lmpjdev/Status;)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXRecvRequest_nativeItest
+ (JNIEnv *env, jobject jthis, jobject status) {
+ //printf("recvRequest test called \n"); fflush(stdout);
+ int testCalled = ((*env)->GetIntField(env,jthis,testcalledID)) ;
+ int isPeeked = ((*env)->GetIntField(env,jthis,isPeekedID)) ;
+
+ if(testCalled == 1) {
+ //((*env)->SetIntField(env,jthis,testcalledID,0)) ;
+ return 1;
+ }
+
+ //printf("nativeItest method \n!");
+ mx_status_t recv_status;
+ mx_request_t reqhandle,dreq ;
+ mx_return_t rc;
+ mx_endpoint_t mlep ;
+ jobject buffer ;
+ uint64_t match_recv;
+ uint64_t match_mask;
+ char * buffer_address;
+ mx_segment_t buffer_desc[1];
+ jbyteArray darr;
+ jbyte* dBuffer;
+ jboolean isCopy = JNI_TRUE;
+ char encoding = 1;
+ int dbuf_length ;
+ uint32_t result = UINT64_C(0x00000000) ;
+
+ jclass req_class = (*env)->GetObjectClass(env, jthis);
+ reqhandle = (mx_request_t) ((*env)->GetLongField(env, jthis, reqhandleID )) ;
+ mlep = (mx_endpoint_t) ((*env)->GetLongField(env, jthis, m_local_endpoint ));
+ match_recv = (uint64_t) ((*env)->GetLongField(env,
+ jthis, matchrecvhandleID)) ;
+ match_mask = (uint64_t)
+ ((*env)->GetLongField(env, jthis, matchrecvmaskhandleID)) ;
+ buffer_address = (char *) ((*env)->GetLongField(env,
+ jthis, bufferaddresshandleID)) ;
+ buffer = ((*env)->GetObjectField(env, jthis,
+ bufferhandleID )) ;
+ jclass mpjbuf_class = (*env)->GetObjectClass(env, buffer);
+
+ /* wait for it complete */
+ if(!isPeeked) {
+ rc = mx_test(mlep, &reqhandle, &recv_status, &result);
+ }
+
+ if(result || isPeeked) {
+ if(!isPeeked) {
+ (*env)->SetIntField(env,status, status_src_ID,
+ GET_SRC(recv_status.match_info) );
+ (*env)->SetIntField(env,status, status_tag_ID,
+ GET_TAG(recv_status.match_info) );
+ (*env)->SetIntField(env,status, countInBytesID,
+ recv_status.msg_length - 16);//-16
+ }
+ //.. dbuf_length ..
+ encoding = buffer_address[0] ;
+ dbuf_length =
+ (((int)(unsigned char) buffer_address[4]) << 24) |
+ (((int)(unsigned char) buffer_address[5]) << 16) |
+ (((int)(unsigned char) buffer_address[6]) << 8) |
+ (((int)(unsigned char) buffer_address[7]) );
+ //printf("dbuf_length [after strange] <%d> \n",dbuf_length);
+ //int dbuf_length = byte22int(buffer_address,0);
+ int sbuf_length = 0;
+ if(!isPeeked) {
+ sbuf_length = recv_status.msg_length - 8 ; //- offset
+ }
+ else {
+ sbuf_length = (*env)->GetIntField(env, status, countInBytesID);
+ }
+
+ //printf("status.msg_length <%d> \n", recv_status.msg_length );
+ if(dbuf_length > 0) {
+ darr = (*env)->NewByteArray (env, dbuf_length);
+ dBuffer = (*env)->GetByteArrayElements(env, darr, &isCopy);
+ buffer_desc[0].segment_ptr = dBuffer;
+ buffer_desc[0].segment_length = dbuf_length;
+ //printf(" receiving \n"); fflush(stdout);
+ //printf("receivng dbuf message \n"); fflush(stdout);
+ /* recv the message */
+ rc = mx_irecv(mlep, buffer_desc, 1, match_recv, match_mask,
+ NULL, &dreq);
+
+ /* wait for it complete */
+ rc = mx_wait(mlep, & dreq, MX_INFINITE,
+ &recv_status, &result);
+ //printf("received dbuf message \n"); fflush(stdout);
+ //printf(" received \n"); fflush(stdout);
+
+ (*env)->SetByteArrayRegion(env,darr,0,dbuf_length,dBuffer);
+ jmethodID setdbuf = (*env)->GetMethodID(env, mpjbuf_class,
+ "setDynamicBuffer", "([B)V");
+ (*env)->CallVoidMethod(env, buffer, setdbuf, darr);
+
+ } else {
+ //printf(" no dynamic message \n") ;
+ }
+
+ jmethodID set_size = (*env)->GetMethodID(env, mpjbuf_class,
+ "setSize", "(I)V");
+ (*env)->CallVoidMethod(env, buffer, set_size, sbuf_length );
+ (*env)->SetIntField(env,jthis, testcalledID, 1);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeRequestInit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXRecvRequest_nativeRequestInit
+ (JNIEnv *env, jclass recvRequest) {
+ reqhandleID = (*env)->GetFieldID(env, recvRequest, "handle", "J");
+ testcalledID = (*env)->GetFieldID(env, recvRequest, "testCalled", "I");
+ //ctrlmsghandleID = (*env)->GetFieldID(env, recvRequest, "ctrlMsgHandle", "J");
+ matchrecvhandleID = (*env)->GetFieldID(env, recvRequest,
+ "matchRecvHandle", "J");
+ matchrecvmaskhandleID =
+ (*env)->GetFieldID(env, recvRequest,
+ "matchRecvMaskHandle", "J");
+ //sbuflengthhandleID = (*env)->GetFieldID(env, recvRequest,
+// "sBufLengthHandle", "J");
+ //dbuflengthhandleID = (*env)->GetFieldID(env, recvRequest,
+// "dBufLengthHandle", "J");
+ bufferaddresshandleID = (*env)->GetFieldID(env, recvRequest,
+ "bufferAddressHandle", "J");
+ m_local_endpoint = (*env)->GetFieldID(env, recvRequest,
+ "localEndpointHandle", "J");
+ bufferhandleID = (*env)->GetFieldID(env, recvRequest,
+ "bufferHandle", "Lmpjbuf/Buffer;");
+ jclass CL_mpjdev_Status = (*env)->FindClass(env,"mpjdev/Status");
+ status_src_ID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "source", "I");
+ status_tag_ID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "tag", "I");
+ countInBytesID = (*env)->GetFieldID(env, CL_mpjdev_Status,
+ "countInBytes", "I");
+ isPeekedID = (*env)->GetFieldID(env,
+ recvRequest, "isPeeked", "I");
+}
+
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.h b/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.h
new file mode 100644
index 0000000..a1c4a20
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXRecvRequest.h
@@ -0,0 +1,38 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class xdev_mxdev_MXRecvRequest */
+
+#ifndef _Included_xdev_mxdev_MXRecvRequest
+#define _Included_xdev_mxdev_MXRecvRequest
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Inaccessible static: waitanyQue */
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeIwait
+ * Signature: (Lmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXRecvRequest_nativeIwait
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeItest
+ * Signature: (Lmpjdev/Status;)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXRecvRequest_nativeItest
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: xdev_mxdev_MXRecvRequest
+ * Method: nativeRequestInit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXRecvRequest_nativeRequestInit
+ (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.c b/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.c
new file mode 100644
index 0000000..fff2aad
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.c
@@ -0,0 +1,206 @@
+/** The MIT License
+
+Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+*/
+#include <stdio.h>
+#include "jni.h"
+#include "myriexpress.h"
+#include "xdev_mxdev_MXSendRequest.h"
+
+jfieldID reqhandleID;
+jfieldID dbuflenID ;
+jfieldID dbufreqhandleID ;
+jfieldID m_local_endpoint;
+jfieldID bufferhandleID;
+jfieldID testcalledID ;
+jfieldID isPeekedID ;
+//jfieldID r_endpoint_handleID ;
+//jfieldID d_msg_tag_handleID ;
+
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeIwait
+ * Signature: (Lmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXSendRequest_nativeIwait
+ (JNIEnv *env, jobject jthis, jobject status) {
+ //printf("sendRequest wait called \n"); fflush(stdout);
+ mx_return_t rc ;
+ int testCalled = ((*env)->GetIntField(env,jthis,testcalledID)) ;
+ int isPeeked = ((*env)->GetIntField(env,jthis,isPeekedID)) ;
+
+ if(testCalled == 1) {
+ //((*env)->SetIntField(env,jthis,testcalledID,0)) ;
+ return ;
+ }
+
+ //printf("native:recvrequest \n");
+ uint32_t result;
+ mx_status_t send_status;
+ mx_request_t reqhandle ;
+ mx_status_t send_status1;
+ uint32_t result1;
+ //mx_request_t reqhandle ;
+ mx_request_t dbufreqhandle ;
+ mx_endpoint_t mlep ;
+ jobject buffer ;
+ int dbuf_length ;
+
+ jclass req_class = (*env)->GetObjectClass(env, jthis);
+
+ reqhandle = (mx_request_t) ((*env)->GetLongField(env, jthis, reqhandleID )) ;
+ dbuf_length = ((*env)->GetIntField(env, jthis, dbuflenID )) ;
+ dbufreqhandle = (mx_request_t)
+ ((*env)->GetLongField(env, jthis, dbufreqhandleID )) ;
+ mlep = (mx_endpoint_t) ((*env)->GetLongField(env, jthis, m_local_endpoint )) ;
+ buffer = ((*env)->GetObjectField(env, jthis,
+ bufferhandleID )) ;
+
+ if( dbuf_length > 0) {
+ //printf("sendreq calling mx_wait 1 \n"); fflush(stdout);
+ /* this is for dbuf message */
+ mx_wait(mlep, &dbufreqhandle, MX_INFINITE,
+ &send_status1, &result1);
+ }
+
+ if(!isPeeked) {
+ rc = mx_wait(mlep, &reqhandle, MX_INFINITE,
+ &send_status, &result);
+ if(rc != MX_SUCCESS) {
+ printf("error in isend"); fflush(stdout);
+ }
+ }
+ //printf("sendreq calling mx_wait 2 \n"); fflush(stdout);
+ /* this is for static buffer message */
+ //printf("sendreq called two mx_waits \n"); fflush(stdout);
+ /*
+ jclass mpjbuf_class = (*env)->GetObjectClass(env, buffer);
+ jmethodID set_size = (*env)->GetMethodID(env, mpjbuf_class,
+ "setSize", "(I)V");
+ (*env)->CallVoidMethod(env, buffer, set_size, send_status.msg_length);
+ */
+ //printf("native:receiver printing the status information \n");
+ //printf("native:receiver xfer_length <%d> \n", send_status.xfer_length );
+ //printf("native:receiver buffer capacity <%d>", capacity );
+ //printf("native:receiver msg_length <%d> \n", send_status.msg_length );
+ //printf("native:receiver recv method ends \n");
+ (*env)->SetIntField(env,jthis, testcalledID, 1);
+}
+
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeItest
+ * Signature: (Lmpjdev/Status;)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXSendRequest_nativeItest
+ (JNIEnv *env, jobject jthis, jobject status) {
+ //printf("native itest method \n");
+ int testCalled = ((*env)->GetIntField(env,jthis,testcalledID)) ;
+ int isPeeked = ((*env)->GetIntField(env,jthis,isPeekedID)) ;
+
+ //printf("sendRequest test called \n"); fflush(stdout);
+ if(testCalled == 1) {
+ printf(" no need to call test after test (sendRequest) \n");
+ fflush(stdout);
+ //((*env)->SetIntField(env,jthis,testcalledID,0)) ;
+ return 1 ;
+ }
+ uint32_t result = 0x00000000 ;
+ mx_status_t send_status;
+ mx_request_t reqhandle ;
+ mx_status_t send_status1;
+ uint32_t result1 = 0x00000000 ;
+ //mx_request_t reqhandle ;
+ mx_request_t dbufreqhandle ;
+ mx_endpoint_t mlep ;
+ jobject buffer ;
+ int dbuf_length ;
+
+ jclass req_class = (*env)->GetObjectClass(env, jthis);
+
+ reqhandle = (mx_request_t) ((*env)->GetLongField(env, jthis, reqhandleID )) ;
+ dbuf_length = ((*env)->GetIntField(env, jthis, dbuflenID )) ;
+ dbufreqhandle = (mx_request_t)
+ ((*env)->GetLongField(env, jthis, dbufreqhandleID )) ;
+ mlep = (mx_endpoint_t) ((*env)->GetLongField(env, jthis, m_local_endpoint )) ;
+ buffer = ((*env)->GetObjectField(env, jthis,
+ bufferhandleID )) ;
+
+ if( dbuf_length > 0) {
+ //printf("sendreq calling mx_wait 1 \n"); fflush(stdout);
+ /* this is for dbuf message */
+ mx_test(mlep, &dbufreqhandle,
+ &send_status1, &result1);
+ if(!result1) {
+ return 0;
+ }
+ }
+
+ //printf("sendreq calling mx_wait 2 \n"); fflush(stdout);
+ /* this is for static buffer message */
+ if(!isPeeked) {
+ mx_test(mlep, &reqhandle,
+ &send_status, &result);
+ }
+
+ /* if there is only static section ...then this means stuff is completed */
+ if(dbuf_length <= 0 && result) {
+ (*env)->SetIntField(env,jthis, testcalledID, 1);
+ return 1;
+ }
+
+ /* in case we have primary and secondary section */
+ if(result && result1) {
+ //printf("test completed the comms (sendRequest) \n"); fflush(stdout);
+ //we are not checking if its been completed or not ...
+ (*env)->SetIntField(env,jthis, testcalledID, 1);
+ return 1;
+ }
+
+ if(result && !result1) {
+ printf("1. one of the request is tested -- not possible \n ");
+ fflush(stdout);
+ }
+
+ if(!result && result1) {
+ printf("2. one of the request is tested -- not possible \n ");
+ fflush(stdout);
+ }
+
+ if(!result && !result1) {
+ printf(" (sendRequest) both requests are not completed (unusual) \n");
+ }
+
+ return 0;
+
+}
+
+
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeRequestInit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXSendRequest_nativeRequestInit
+ (JNIEnv *env, jclass sendRequest) {
+ reqhandleID = (*env)->GetFieldID(env, sendRequest , "handle", "J");
+ dbuflenID = (*env)->GetFieldID(env, sendRequest , "dbuflen", "I");
+ dbufreqhandleID =
+ (*env)->GetFieldID(env, sendRequest , "dbufHandle", "J");
+ m_local_endpoint = (*env)->GetFieldID(env, sendRequest,
+ "localEndpointHandle", "J");
+ bufferhandleID = (*env)->GetFieldID(env, sendRequest,
+ "bufferHandle", "Lmpjbuf/Buffer;");
+ testcalledID = (*env)->GetFieldID(env, sendRequest, "testCalled", "I");
+ isPeekedID = (*env)->GetFieldID(env,
+ sendRequest, "isPeeked", "I");
+ //r_endpoint_handleID = (*env)->GetFieldID(env, sendRequest,
+// "remoteEndpointHandle", "J");
+ //d_msg_tag_handleID = (*env)->GetFieldID(env, sendRequest,
+// "dynamicMsgTagHandle", "J");
+}
+
diff --git a/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.h b/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.h
new file mode 100644
index 0000000..aab97e2
--- /dev/null
+++ b/src/xdev/mxdev/lib/xdev_mxdev_MXSendRequest.h
@@ -0,0 +1,38 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class xdev_mxdev_MXSendRequest */
+
+#ifndef _Included_xdev_mxdev_MXSendRequest
+#define _Included_xdev_mxdev_MXSendRequest
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* Inaccessible static: waitanyQue */
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeIwait
+ * Signature: (Lmpjdev/Status;)V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXSendRequest_nativeIwait
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeItest
+ * Signature: (Lmpjdev/Status;)I
+ */
+JNIEXPORT jint JNICALL Java_xdev_mxdev_MXSendRequest_nativeItest
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: xdev_mxdev_MXSendRequest
+ * Method: nativeRequestInit
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_xdev_mxdev_MXSendRequest_nativeRequestInit
+ (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/xdev/niodev/ConfigReader.java b/src/xdev/niodev/ConfigReader.java
new file mode 100755
index 0000000..82412e9
--- /dev/null
+++ b/src/xdev/niodev/ConfigReader.java
@@ -0,0 +1,243 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : ConfigReader.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2005/07/31 15:14:15 $
+ *
+ */
+
+package xdev.niodev ;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+
+/**
+ * <p>This class is a utiliy class that is used to read the start-up information from a configuration file. The users
+ * of the mpjdev do not have to deal with this file. </p>
+ */
+
+public class ConfigReader {
+ private BufferedReader bufferedReader = null;
+ URL aURL = null;
+ InputStream in = null;
+
+ private String delimiter = null;
+ private int numberOfHosts = 0;
+ int count = 1;
+ String fileName = null;
+ /**
+ * Constructor of this utility class
+ * @param fileName String The name of the configuration file. This can be on the local file system or
+ * on some server accessible via http.
+ * @throws IOException If some I/O error happens.
+ * @throws FileNotFoundException If the file is not found.
+ * @throws MalformedURLException If the http URL is malformed.
+ */
+ public ConfigReader(String fileName) throws IOException,
+ FileNotFoundException, MalformedURLException {
+ this.fileName = fileName;
+
+ if (fileName.startsWith("http://")) {
+
+ try {
+ aURL = new URL(new String(fileName));
+ }
+ catch (MalformedURLException mue) {
+ mue.printStackTrace();
+ System.exit(0);
+ }
+
+ try {
+ in = aURL.openStream();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ System.exit(0);
+ }
+
+ bufferedReader = new BufferedReader(new InputStreamReader(in));
+ //this is the http URL now !!!!
+ }
+ else {
+ try {
+ bufferedReader = new BufferedReader(new FileReader(this.fileName));
+ }
+ catch (FileNotFoundException fnfe) {
+ System.out.println("File Not Found Exception" + this.fileName);
+ System.out.println("Please locate and Make sure that the appropriate configuration file is lying in " +
+ "the appropriate directory .....");
+ System.exit(0);
+ }
+ }
+ } //end ConfigReader constructor !
+
+ /**
+ * Read the number of processes mentioned in the configuration file.
+ * @throws IOException If some I/O error occurs
+ * @return String The number of total processes
+ */
+ public String readNoOfProc() throws IOException {
+ String temp = null;
+ boolean loop = true;
+ while (loop) {
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("Problem reading the config file" + this.fileName);
+ System.exit(0);
+ }
+
+ if (temp == null || temp.equals("")) {
+ continue;
+ }
+
+ if (temp.startsWith("#")) {
+ continue;
+ }
+ temp = temp.trim();
+ numberOfHosts = (new Integer(temp)).intValue();
+ loop = false;
+ }
+ return temp;
+ }
+
+ /**
+ * Reads integer as a string
+ * @throws IOException
+ * @return String
+ */
+ public String readIntAsString() throws IOException {
+ String temp = null;
+ boolean loop = true;
+ while (loop) {
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("Problem reading the config file" + this.fileName);
+ System.exit(0);
+ }
+
+ if (temp == null || temp.equals("")) {
+ continue;
+ }
+
+ if (temp.startsWith("#")) {
+ continue;
+ }
+ temp = temp.trim();
+ loop = false;
+ }
+ return temp;
+ }
+
+ /**
+ * Reads line from the configuration file.
+ * @throws IOException
+ * @return String
+ */
+ public String readLine() throws IOException {
+ if (count > numberOfHosts) {
+ return null;
+ }
+ String temp;
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("IOException");
+ ioe.printStackTrace();
+ return null;
+ }
+
+ if (temp == null || temp.equals("")) {
+ System.out.println("empty or whitespace");
+ return "empty";
+ }
+
+ if (temp.startsWith("#")) {
+ //System.out.println("#");
+ return "#";
+ }
+
+ //return if we have read whatever the user has asked for, we dont want to
+ //read more than what is required ...
+
+ //System.out.println("Before trmming in readLine"+temp);
+ temp = temp.trim();
+ count++;
+ return temp;
+ }
+
+ /**
+ * Close all the streams.
+ */
+ public void close() {
+ try {
+ bufferedReader.close();
+ in.close();
+ }
+ catch (Exception ioe) {
+ }
+ finally {
+ bufferedReader = null;
+ aURL = null;
+ in = null;
+ }
+ } //end close()
+
+ /** Just for testing this class ! ! ! **/
+ public static void main(String args[]) throws Exception {
+
+ String CONFIGURATION_FILE = new String("mpjdev.conf");
+ int NUMBER_OF_HOSTS = 0;
+ ConfigReader reader = new ConfigReader(CONFIGURATION_FILE);
+ NUMBER_OF_HOSTS = (new Integer(reader.readNoOfProc())).intValue();
+ System.out.println("NUMBER_OF_HOSTS " + NUMBER_OF_HOSTS);
+ //this would get the total hosts
+
+ String line = null;
+ while ( (line = reader.readLine()) != null) {
+ if (line.equals("empty") || line.equals("#")) {
+ continue;
+ }
+ line = line.trim();
+ StringTokenizer tokenizer = new StringTokenizer(line, "@");
+ System.out.println("Node<" + tokenizer.nextToken() + ">");
+ System.out.println("Num<" + tokenizer.nextToken() + ">"); //this gets you names of individual machines,
+ }
+ reader.close();
+ } //end static void main()
+}
diff --git a/src/xdev/niodev/NIODevice.java b/src/xdev/niodev/NIODevice.java
new file mode 100644
index 0000000..d063b3e
--- /dev/null
+++ b/src/xdev/niodev/NIODevice.java
@@ -0,0 +1,4091 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : NIODevice.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.29 $
+ * Updated : $Date: 2013/12/17 17:24:47 $
+ *
+ */
+
+package xdev.niodev;
+
+import java.nio.channels.*;
+import java.nio.*;
+import java.net.*;
+import java.util.*;
+import mpjbuf.*;
+import mpjdev.*;
+import java.util.concurrent.Semaphore;
+import xdev.*;
+import java.io.IOException;
+import java.io.File;
+
+import org.apache.log4j.Logger;
+
+/**
+ * <p>
+ * This class is implementation of <i>xdev</i> based on the Java New I/O
+ * package.
+ * </p>
+ *
+ * <h3>Overview</h3>
+ * <p>
+ * Java New I/O adds non-blocking I/O to the Java language, which is extensively
+ * used in this device, to provide MPI functionality. Instead of directly using
+ * {@link java.net.Socket java.net.Socket}, niodev uses
+ * {@link java.nio.channels.SocketChannel java.nio.channels.SocketChannel}. This
+ * device alongwith the request classes like {@link xdev.niodev.NIORequest
+ * xdev.niodev.NIORequest}, {@link xdev.niodev.NIOSendRequest
+ * xdev.niodev.NIOSendRequest}, and {@link xdev.niodev.NIORecvRequest
+ * xdev.niodev.NIORecvRequest} forms the basis of communication functionality.
+ * </p>
+ *
+ * <h3>Initialization</h3>
+ * <p>
+ * 'niodev' reads a configuration file which could be placed in the local/shared
+ * file system, or is accessbile through http server. The device reads this
+ * configuration file, and tries to find the IP at PORT@RANK entry. The basis for
+ * this search is the rank provided to the device by the runtime infrastructure.
+ * Once this entry is located , the device knows which ports to start the
+ * {@link ServerSocketChannel ServerSocketChannel} on. Once the server socket
+ * channels are started at this port and port+1, these are registered with the
+ * selector to accept connections. Every time a client socket connects to this
+ * server socket channel, an OP_ACCEPT event is generated. After starting these
+ * server sockets, a process connects to the process with rank lesser than its
+ * own. This essentially means that if there are four processes, then Process 0
+ * will start two server sockets, Process 1 will start two server socket, and
+ * then try to connect to server sockets of Process 0. Similarly after starting
+ * two server sockets, Process 2 and 3 will connect to Processes 0&1, and
+ * Processes 0&1&2 respectively.
+ * </p>
+ * <p>
+ * Every time, niodev accepts or connects, it puts the
+ * {@link java.nio.channels.SocketChannel java.nio.channels.SocketChannel} into
+ * an instance of {@link java.util.Vector java.util.Vector} writableChannels
+ * (for writing messages) or readableChannels (for reading messages), depending
+ * on the serverSocketPort. Note that accepting client request is done in the
+ * selector thread, and connecting to server socket is done in the user-thread.
+ * This may result in concurrent access to writableChannels and
+ * readableChannels, and thus access to these should be synchronized. Once
+ * alltoall connectivity has been acheived, which means [writableChannels.size()
+ * == N-1] and [readableChannels.size() == N-1], then each process need to send
+ * information like its rank and UUID to every other process. These rank are the
+ * ones read from the configuration file provided by the MPJ runtime
+ * infrastructure. Once all the processes have exchanged this information,
+ * niodev has worldWritableTable and worldReadableTable, which are instances of
+ * {@link java.util.Hashtable java.util.Hashtable}. These two hashtables contain
+ * UUID as keys, and SocketChannels as values. Note that the channels in
+ * 'worldWritableTable' are in blocking mode and are only used for writing
+ * messages. For 'niodev', we have decided to keep different channels for
+ * reading and writing. The reason is that we want to use non-blocking reads and
+ * blocking writes. Non-blocking writes could hurt 'thread-safety' of niodev, or
+ * result in very complex code. These hashtables would be later used in
+ * send/recv method to obtain the reference of SocketChannel while providing key
+ * as the UUID of each process. These UUID, are contained within the
+ * {@link xdev.ProcessID xdev.ProcessID} objects. Again, while exchanging
+ * information, access to worldWriteTable, and worldReadableTable should be
+ * synchronized. Normally, the user thread sends all the information, and then
+ * waits to selector thread to receive similar messages from all the other
+ * processes. When the selector thread reads a message, it first looks at the
+ * first four bytes, and after looking at the header information, adds the
+ * information received appropriately to one of the hashtables. The value of
+ * headers could be INIT_MSG_HEADER_DATA_CHANNEL, and
+ * INIT_MSG_HEADER_CONTROL_CHANNEL. Once all of this is done, niodev has been
+ * initialized.
+ * </p>
+ *
+ * <h3>Modes of Send</h3>
+ * <p>
+ * <a href="http://www.mpi-forum.org"> MPI specifications </a> defines four
+ * modes of send operation. These are: standard mode of send, buffered mode of
+ * send, ready mode of send, and synchronous mode of send. <i> xdev </i>
+ * supports two modes of send -- standard and synchronous send. Ready send is
+ * similar to standard mode of send, and buffered mode is supported at the
+ * higher level alongwith the MPJ buffering API.
+ * </p>
+ * <h4>Standard Mode of Send</h4>
+ * <p>
+ * The standard mode of send uses two communication protocols. The first is
+ * 'Eager-Send Protocol' and the second is 'Rendezvous Protocol'.
+ * </p>
+ * <h5>EagerSend Protocol</h5>
+ * <p>
+ * niodev uses eager send protocol to communicate small messages. The rationale
+ * behind using this communication protcol is to minimize the latency for small
+ * messages. This protocol assumes that the receiver has buffer space to store
+ * the messages in case the matching recv is not posted. Eager-send protocol is
+ * used for messages of size less than and equal to 128K bytes.
+ * </p>
+ * <img src="../../res/eagersend.png"/> <h5>Rendezvous Protocol</h5>
+ * <p>
+ * niodev uses rendezvous protocol to communicate large messages. Before
+ * communicating large messages, there is an exchange of control messages to
+ * make sure that a matching recv is posted. This is necessary to avoid
+ * additional copying to temporary xdev buffer.
+ * </p>
+ * <img src="../../res/rendezvous.png"/> <h4>Synchronous Mode of Send</h4>
+ * <p>
+ * The synchronous mode of send uses rendezvous protocol described above for
+ * communication.
+ * </p>
+ * <img src="../../res/syncmode.png" /> <h3>User and Selector Threads</h3>
+ * <p>
+ * During the initialization of xdev, xdev.NIODevice.init( ...) creates a
+ * selector thread which is used to first accept connections. Once all-to-all
+ * connectivity has been acheived, then the channels (both control and data)
+ * register with the selectors for READ_EVENT. This essentially means that
+ * whenever a channel receives some data, it generates OP_READ event, which
+ * basically informs that there is some data to read on this channel. Thus, the
+ * selector-thread is used normally for reading data from the channels. Also,
+ * when there is a short write -- suppose a thread is trying to write 10K
+ * message and only succeeds to write 5K bytes, then the channel register with
+ * the selector for OP_WRITE event, and comes back to complete writing the
+ * message into the SocketChannel.
+ * </p>
+ * <p>
+ * The user thread is basically invoked when isend/issend/send/ssend/ recv/irecv
+ * methods are called. <i> xdev </i> also attempts to provide multiple thread
+ * functionality, which basically means there could be multiple user-threads and
+ * trying to make calls to these (non) blocking send/recv methods.
+ * </p>
+ * <p>
+ * This poses a great programming challenge, because user threads and selector
+ * threads should synchronize before accessing send/recv queues that contain
+ * pending messages that are waiting for the data to be written or read from the
+ * channel
+ * </p>
+ * <h3>Send and Recv Queues</h3>
+ * <p>
+ * </p>
+ * <h3>Same Process Communications</h3>
+ * <p>
+ * There is special case, when a process is trying to send and recv a message to
+ * itself. In this case, the message is just copied from the sender buffer into
+ * the receiver buffer. The complexity comes in when wild-card like ANY_SOURCE
+ * are used.
+ * </p>
+ */
+public class NIODevice implements Device {
+
+ int index, root, extent, places;
+
+ ProcTree procTree;
+
+ long nextSequenceNum = 1L;
+
+ /*
+ * This semaphore is used to hold lock on send communication-sets
+ */
+ CustomSemaphore sLock = new CustomSemaphore(1);
+
+ /*
+ * This semaphore is used to hold lock while reading data from the
+ * SocketChannel
+ */
+ CustomSemaphore sem = new CustomSemaphore(1);
+
+ /*
+ * For rendezvous protocol, selector thread receives the ACK messages and a
+ * new thread is started that actually sends the messages. Selector thread
+ * receives the message in a ByteBuffer which is read by rendezSend thread.
+ * This semaphore is used to synchronize access to the buffer
+ */
+ CustomSemaphore buffer_sem = new CustomSemaphore(1);
+
+ static Logger logger = Logger.getLogger("mpj");
+
+ Vector<SocketChannel> writableChannels = new Vector<SocketChannel>();
+
+ Vector<SocketChannel> readableChannels = new Vector<SocketChannel>();
+
+ Hashtable<UUID, SocketChannel> worldWritableTable = new Hashtable<UUID, SocketChannel>();
+
+ Hashtable<UUID, SocketChannel> worldReadableTable = new Hashtable<UUID, SocketChannel>();
+
+ Hashtable<SocketChannel, CustomSemaphore> writeLockTable = new Hashtable<SocketChannel, CustomSemaphore>();
+
+ // private static final boolean DEBUG = false ;
+ // static final boolean DEBUG = true ;
+
+ InetAddress localaddr = null;
+
+ Selector selector = null;
+
+ volatile boolean selectorFlag = true;
+
+ private HashMap<Integer, NIOSendRequest> sendMap = new HashMap<Integer, NIOSendRequest>();
+
+ private int sendCounter = 0;
+
+ private int recvCounter = 0;
+
+ HashMap<Integer, NIORecvRequest> recvMap = new HashMap<Integer, NIORecvRequest>();
+
+ class RecvQueue {
+
+ private HashMap<Key, NIORecvRequest> map = new HashMap<Key, NIORecvRequest>();
+
+ private NIORecvRequest get(Key key) {
+ return map.get(key);
+ }
+
+ private void add(Key key, NIORecvRequest recv) {
+ NIORecvRequest head = map.get(key);
+
+ if (head == null) {
+ recv.recvNext = recv;
+ recv.recvPrev = recv;
+ map.put(key, recv);
+ } else {
+ NIORecvRequest last = head.recvPrev;
+
+ last.recvNext = recv;
+ head.recvPrev = recv;
+
+ recv.recvPrev = last;
+ recv.recvNext = head;
+ }
+ }
+
+ private void rem(Key key, NIORecvRequest recv) {
+ NIORecvRequest head = map.get(key);
+
+ if (recv == head) {
+ if (recv.recvNext == recv) {
+ map.remove(key);
+ } else {
+ NIORecvRequest next = recv.recvNext;
+ NIORecvRequest last = recv.recvPrev;
+
+ last.recvNext = next;
+ next.recvPrev = last;
+
+ map.put(key, next);
+ }
+ } else {
+ NIORecvRequest next = recv.recvNext;
+ NIORecvRequest prev = recv.recvPrev;
+
+ prev.recvNext = next;
+ next.recvPrev = prev;
+ }
+ }
+
+ void add(NIORecvRequest request) {
+ /*
+ * Checking if Hybrid device is enabled then source and destination of
+ * message in key should be Hybrid source and destination, not those of
+ * Network source and destination
+ */
+ if (isHybrid) {
+ request.recvKey = new NIODevice.Key(request.context,
+ request.dstHybUUID, request.srcHybUUID, request.tag);
+
+ } else {
+ request.recvKey = new NIODevice.Key(request.context, request.dstUUID,
+ request.srcUUID, request.tag);
+ }
+
+ add(request.recvKey, request);
+ }
+
+ NIORecvRequest rem(int context, UUID dstUUID, UUID srcUUID, int tag) {
+
+ Key[] keys = new NIODevice.Key[] {
+ new NIODevice.Key(context, dstUUID, srcUUID, tag),
+ new NIODevice.Key(context, dstUUID, srcUUID, xdev.Device.ANY_TAG),
+ new NIODevice.Key(context, dstUUID, xdev.Device.ANY_SRC.uuid(), tag),
+ new NIODevice.Key(context, dstUUID, xdev.Device.ANY_SRC.uuid(),
+ xdev.Device.ANY_TAG) };
+
+ NIORecvRequest matchingRecv = null;
+
+ long minSequenceNum = Long.MAX_VALUE;
+
+ for (int i = 0; i < keys.length; i++) {
+ NIORecvRequest recv = get(keys[i]);
+
+ if (recv != null && recv.sequenceNum < minSequenceNum) {
+ minSequenceNum = recv.sequenceNum;
+ matchingRecv = recv;
+ }
+ }
+
+ if (matchingRecv != null) {
+ rem(matchingRecv.recvKey, matchingRecv);
+ }
+
+ return matchingRecv;
+ }
+
+ }
+
+ RecvQueue recvQueue = new RecvQueue();
+
+ class ArrvQueue {
+
+ private HashMap<Key, NIORecvRequest> map = new HashMap<Key, NIORecvRequest>();
+
+ NIORecvRequest rem(int context, UUID dstUUID, UUID srcUUID, int tag) {
+
+ Key key = new Key(context, dstUUID, srcUUID, tag);
+ NIORecvRequest matchingSend = get(key);
+
+ if (matchingSend != null) {
+ Key[] keys = matchingSend.arrKeys;
+ for (int i = 0; i < keys.length; i++) {
+ rem(i, keys[i], matchingSend);
+ }
+ }
+
+ return matchingSend;
+ }
+
+ NIORecvRequest remForIprobeAndFetch(int context, UUID dstUUID,
+ UUID srcUUID, int tag) {
+
+ Key key = new Key(context, dstUUID, srcUUID, tag);
+ NIORecvRequest request = get(key);
+
+ if (request != null) {
+
+ if (((request.sBufSize + request.dBufSize) <= psl)
+ && request.commMode == STD_COMM_MODE) {
+
+ Key[] keys = request.arrKeys;
+ for (int i = 0; i < keys.length; i++) {
+ rem(i, keys[i], request);
+ }
+ request.notifyMe();
+ return request;
+ } else if ((((request.sBufSize + request.dBufSize) > psl) && request.commMode == STD_COMM_MODE)
+ || (request.commMode == SYNC_COMM_MODE)) {
+ return request;
+ }
+ }
+
+ return request;
+ }
+
+ private NIORecvRequest get(Key key) {
+ return map.get(key);
+ }
+
+ private void add(int i, Key key, NIORecvRequest send) {
+ NIORecvRequest head = map.get(key);
+
+ if (head == null) {
+ send.arrNext[i] = send;
+ send.arrPrev[i] = send;
+ map.put(key, send);
+ } else {
+ NIORecvRequest last = head.arrPrev[i];
+ last.arrNext[i] = send;
+ head.arrPrev[i] = send;
+
+ send.arrPrev[i] = last;
+ send.arrNext[i] = head;
+ }
+ }
+
+ private void rem(int i, Key key, NIORecvRequest send) {
+
+ NIORecvRequest head = map.get(key);
+
+ if (send == head) {
+ if (send.arrNext[i] == send) {
+ map.remove(key);
+ } else {
+ NIORecvRequest next = send.arrNext[i];
+ NIORecvRequest last = send.arrPrev[i];
+ last.arrNext[i] = next;
+ next.arrPrev[i] = last;
+ map.put(key, next);
+ }
+ } else {
+ NIORecvRequest next = send.arrNext[i];
+ NIORecvRequest prev = send.arrPrev[i];
+
+ prev.arrNext[i] = next;
+ next.arrPrev[i] = prev;
+ }
+ }
+
+ NIORecvRequest check(int context, UUID dstUUID, UUID srcUUID, int tag) {
+ Key key = new Key(context, dstUUID, srcUUID, tag);
+ return get(key);
+ }
+
+ void add(NIORecvRequest request) {
+
+ /*
+ * Checking if Hybrid device is enabled then source and destination of
+ * message in key should be Hybrid source and destination, not those of
+ * Network souruce and destination. 50 context is reserved for finish
+ * method message so that message should always be treat as NIO message,
+ * as it is used to finshi NIO device.
+ */
+
+ if (isHybrid && (request.context != 50)) {
+ request.arrKeys = new NIODevice.Key[] {
+ new NIODevice.Key(request.context, request.dstHybUUID,
+ request.srcHybUUID, request.tag),
+ new NIODevice.Key(request.context, request.dstHybUUID,
+ request.srcHybUUID, xdev.Device.ANY_TAG),
+ new NIODevice.Key(request.context, request.dstHybUUID,
+ xdev.Device.ANY_SRC.uuid(), request.tag),
+ new NIODevice.Key(request.context, request.dstHybUUID,
+ xdev.Device.ANY_SRC.uuid(), xdev.Device.ANY_TAG) };
+ // System.out.println(" ArrQue.add() => HYB Src:"+request.srcHybUUID+" HYB Dst:"+request.dstHybUUID
+ // +
+ // " tag:"+request.tag+" Context:"+request.context+" isHybrid:"+isHybrid)
+ // ;
+ } else {
+
+ request.arrKeys = new NIODevice.Key[] {
+ new NIODevice.Key(request.context, request.dstUUID,
+ request.srcUUID, request.tag),
+ new NIODevice.Key(request.context, request.dstUUID,
+ request.srcUUID, xdev.Device.ANY_TAG),
+ new NIODevice.Key(request.context, request.dstUUID,
+ xdev.Device.ANY_SRC.uuid(), request.tag),
+ new NIODevice.Key(request.context, request.dstUUID,
+ xdev.Device.ANY_SRC.uuid(), xdev.Device.ANY_TAG) };
+
+ }
+ for (int i = 0; i < request.arrKeys.length; i++) {
+ add(i, request.arrKeys[i], request);
+ }
+ }
+
+ }
+
+ class Key {
+ /*
+ * key is updated to have four tuples, as in Hybrid communication source,
+ * destination, tag and context are minimum requirements to uniqely identify
+ * the message. So key mechanism of NIODevice is updated to meet
+ * requirements. All addition and removal from the message queues is based
+ * on the 4-tuple key
+ */
+
+ private int context, tag;
+
+ private UUID srcUUID;
+ private UUID dstUUID;
+
+ Key(int context, UUID dstUUID, UUID srcUUID, int tag) {
+ this.context = context;
+ this.dstUUID = dstUUID;
+ this.srcUUID = srcUUID;
+ this.tag = tag;
+ }
+
+ public int hashCode() {
+ return tag + context * 5 + srcUUID.hashCode() * 17 + dstUUID.hashCode()
+ * 19;
+ }
+
+ public boolean equals(Object obj) {
+
+ if (obj instanceof Key) {
+ Key other = (Key) obj;
+ return (other.context == context) && (dstUUID.equals(other.dstUUID))
+ && (srcUUID.equals(other.srcUUID)) && (other.tag == tag);
+ }
+
+ return false;
+
+ }
+ }
+
+ ArrvQueue arrQue = new ArrvQueue();
+
+ /*
+ * Name of machine where this xdev process is running
+ */
+ String localHostName = null;
+ /*
+ * isHybrid switch is useful for using NIODevice within Hybrid Device. It is
+ * set to true at the end of Hybrid Device init mehtod. isHybird switch is
+ * checked before adding and removing any message in the Arrive Queueu and
+ * Recv Queue. If isHybrid switch is ON then in the message key Hybrid Source
+ * and Destination are used else NIO Source and destination are used.
+ */
+ public static boolean isHybrid = false;
+
+ /* Server Socket Channel */
+ ServerSocketChannel writableServerChannel = null;
+
+ ServerSocketChannel readableServerChannel = null;
+
+ /*
+ * Initially CTRL_MSG_LENGTH was set to 45, to use NIODevice within Hybird
+ * device its CTRL_MSG_LENGTH is increased by 32, so it is 77 now. Hybrid
+ * Source and Destination is added in the message that means two UUID values
+ * so 32 bytes are required. NIODevice works fine on CTRL_MSG_LENGTH=77 as
+ * well, first 45 bytes will be used and rest of the 32 bytes will be null.
+ */
+ public static int CTRL_MSG_LENGTH = 77;
+
+ ByteBuffer rcb = ByteBuffer.allocate(CTRL_MSG_LENGTH);
+
+ ByteBuffer rendezBuffer = ByteBuffer.allocate(8);
+
+ ByteBuffer rendez_send_buffer = ByteBuffer.allocate(17);
+
+ ByteBuffer wcb = ByteBuffer.allocate(49);
+
+ ByteBuffer e_wcb = ByteBuffer.allocate(49);
+
+ static ByteBuffer _wcb = ByteBuffer.allocate(21); // eendezCtrlMsgR2S ...
+
+ ByteBuffer s_wcb = ByteBuffer.allocate(20); // rendezCtrlMsgR2S ...
+
+ /* Threads for two selectors */
+ Thread selectorThreadStarter = null;
+
+ int psl = 0, nprocs = 0, rank = 0, size = 0, my_server_port = 0;
+
+ ProcessID[] pids = null;
+
+ ProcessID id = null;
+
+ /*
+ * This integer is used as the header to send initial control messages
+ */
+ private final int INIT_MSG_HEADER_DATA_CHANNEL = -21;
+
+ private final int INIT_MSG_HEADER_CTRL_CHANNEL = -20;
+
+ private final int RENDEZ_CTRL_MSG_LENGTH = 4;
+
+ private final int ACK_LENGTH = 17;
+
+ // private final int CTRL_MSG_LENGTH = 45;
+
+ int SEND_OVERHEAD = CTRL_MSG_LENGTH + 4;
+
+ int RECV_OVERHEAD = 0;
+
+ private final int STD_COMM_MODE = 3;
+
+ private final int SYNC_COMM_MODE = 2;
+
+ private final boolean NO_ACK_RECEIVED = false;
+
+ private final boolean REQ_NOT_COMPLETED = false;
+
+ private final boolean RECV_POSTED = true;
+
+ private final int READY_TO_SEND = -24;
+
+ private static final int ACK_HEADER = -23;
+
+ private final int RENDEZ_HEADER = -22;
+
+ private final int SEND_ACK_TO_SENDER = -80;
+
+ private final int RECV_IN_USER_MEMORY = -81;
+
+ private final int RECV_IN_DEV_MEMORY = -82;
+
+ private final int MORE_TO_WRITE = -83;
+
+ private final int MORE_TO_READ = -84;
+
+ private String mpjHomeDir = null;
+
+ SocketChannel msgReceivedFrom; // what is this doing here?
+
+ boolean finished = false;
+
+ public NIODevice() {
+ // this.deviceName = "niodev";
+ }
+
+ /**
+ * Initializes niodev.
+ *
+ * @param args
+ * Arguments to NIODevice.
+ * @return ProcessID[] An array of ProcessIDs.
+ */
+ public ProcessID[] init(String args[]) throws XDevException {
+
+ /*
+ *
+ * The init method reads names/ports/ranks from a config file. It finds its
+ * own entry in the config file (by comparing ranks), and creates a server
+ * socket at the port specified for that entry. Also, it creates another
+ * server socket at (portspecified+1). It connects to server sockets (not
+ * one, two server sockets) of processes with rank higher than its own.
+ *
+ * At the end of this process, each process is connected to every other
+ * process with two socketChannels. The reason for two channels is that
+ * every process has writable and reable channel. The writable channel is in
+ * blocking mode, whereas, the readable channel is in non-blocking mode. In
+ * terms of datastructures, 'writableChannels' (Vector) contains all
+ * writable channels, and 'readableChannels' (Vector) contains all readable
+ * channels for every process. The next step is that each process send its
+ * own rank, ProcessID to all the other processes. At the end of this, each
+ * process knows about all the peers and have ProcessID (key), SocketChannel
+ * (val) in 'worldWritableTable' and 'worldReadableTable'.
+ *
+ * As the name suggests, worldWritableTable is used for writing messages
+ * into channels, and worldReadableTable is used for receiving. The
+ * selector-thread would generate events for worldReadableTable
+ * SocketChannels whereas, the ones (SocketChannels) in worldWritableTable
+ * have nothing to do with selector thread as they are in blocking mode.
+ */
+
+ if (args.length < 3) {
+
+ throw new XDevException("Usage: "
+ + "java NIODevice <myrank> <conf_file> <device_name>"
+ + "conf_file can be, ../conf/xdev.conf <Local>"
+ + "OR http://holly.dsg.port.ac.uk:15000/xdev.conf <Remote>");
+
+ }
+
+ rank = Integer.parseInt(args[0]);
+ UUID myuuid = UUID.randomUUID();
+ id = new ProcessID(myuuid); // , rank);
+ Map<String, String> map = System.getenv();
+ mpjHomeDir = map.get("MPJ_HOME");
+
+ try {
+
+ localaddr = InetAddress.getLocalHost();
+ localHostName = localaddr.getHostName();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("--init method of niodev is called--");
+ logger.info("Address: " + localaddr);
+ logger.info("Name :" + localHostName);
+ logger.info("rank :" + rank);
+ }
+
+ }
+ catch (UnknownHostException unkhe) {
+ throw new XDevException(unkhe);
+ }
+
+ ConfigReader reader = null;
+
+ try {
+ reader = new ConfigReader(args[1]);
+ nprocs = (new Integer(reader.readNoOfProc())).intValue();
+ psl = (new Integer(reader.readIntAsString())).intValue();
+ if (psl < 12) {
+ logger.debug("lowest possible psl is 12 bytes");
+ psl = 12;
+ }
+ }
+ catch (Exception config_error) {
+ throw new XDevException(config_error);
+ }
+
+ pids = new ProcessID[nprocs];
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("total processes:<" + nprocs);
+ logger.info("protocolSwitchLimit :<" + psl);
+ }
+
+ String[] nodeList = new String[nprocs];
+ int[] rPortList = new int[nprocs];
+ int[] wPortList = new int[nprocs];
+ int[] rankList = new int[nprocs];
+ int count = 0;
+
+ while (count < nprocs) {
+
+ String line = null;
+
+ try {
+ line = reader.readLine();
+ }
+ catch (IOException ioe) {
+ throw new XDevException(ioe);
+ }
+
+ if (line == null || line.equals("") || line.equals("#")) {
+ continue;
+ }
+
+ line = line.trim();
+ StringTokenizer tokenizer = new StringTokenizer(line, "@");
+ nodeList[count] = tokenizer.nextToken();
+ wPortList[count] = (new Integer(tokenizer.nextToken())).intValue();
+ rPortList[count] = (new Integer(tokenizer.nextToken())).intValue();
+ rankList[count] = (new Integer(tokenizer.nextToken())).intValue();
+ count++;
+
+ }
+
+ reader.close();
+
+ /* Open the selector */
+ try {
+ selector = Selector.open();
+ }
+ catch (IOException ioe) {
+ throw new XDevException(ioe);
+ }
+
+ /* Create server socket */
+ SocketChannel[] rChannels = new SocketChannel[nodeList.length - 1];
+ /* Create control server socket */
+ SocketChannel[] wChannels = new SocketChannel[nodeList.length - 1];
+
+ /*
+ * Checking for the java.net.BindException. This Exception is thrown when
+ * the port on which we want to bind is already in use
+ */
+ boolean isOK = false;
+ boolean isError = false;
+
+ while (isOK != true) {
+
+ isOK = false;
+ isError = false;
+
+ try {
+ writableServerChannel = ServerSocketChannel.open();
+ writableServerChannel.configureBlocking(false);
+ writableServerChannel.socket().bind(
+ new InetSocketAddress(wPortList[rank]));
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("created writableServerChannel on port "
+ + wPortList[rank]);
+ }
+ writableServerChannel.register(selector, SelectionKey.OP_ACCEPT);
+
+ my_server_port = wPortList[rank];
+
+ readableServerChannel = ServerSocketChannel.open();
+ readableServerChannel.configureBlocking(false);
+ readableServerChannel.socket().bind(
+ new InetSocketAddress(rPortList[rank]));
+ readableServerChannel.register(selector, SelectionKey.OP_ACCEPT);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("created readableServerChannel on port "
+ + rPortList[rank]);
+ }
+
+ }
+ catch (IOException ioe) {
+ isError = true;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("NIODevice threw an exception "
+ + "while starting the server on ports " + wPortList[rank]
+ + " or " + (rPortList[rank])
+ + ". We'll try starting servers on next two consecutive ports");
+ }
+ try {
+ Thread.sleep(500);
+ }
+ catch (Exception e) {
+ }
+ }
+ finally {
+ if (isError == true)
+ isOK = false;
+ else if (isError == false)
+ isOK = true;
+ }
+ }
+
+ /* This is connection-code for data-channels. */
+ boolean connected = false;
+ int temp = 0, index = 0;
+ /*
+ * This while loop is connecting to server sockets of other peers. If there
+ * are 4 processes, process 0 will not connect to any process, process 1
+ * will connect to process 0, process 2 will connect to pro 0&1, and process
+ * 3 will connect to pro 0&1&2
+ */
+
+ while (temp < nprocs - 1) {
+
+ if (rank == rankList[temp]) {
+ temp++;
+ continue;
+ }
+
+ if (rankList[temp] < rank) {
+
+ while (!connected) {
+
+ try {
+ rChannels[index] = SocketChannel.open();
+ rChannels[index].configureBlocking(true);
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Connecting to " + nodeList[temp] + "@"
+ + wPortList[temp]);
+ }
+
+ try {
+ connected = rChannels[index].connect(new InetSocketAddress(
+ nodeList[temp], wPortList[temp]));
+ }
+ catch (AlreadyConnectedException ace) {
+ throw new XDevException(ace);
+ }
+ catch (ConnectionPendingException cpe) {
+ throw new XDevException(cpe);
+ }
+ catch (ClosedChannelException cce) {
+ throw new XDevException(cce);
+ }
+ catch (UnresolvedAddressException uae) {
+ throw new XDevException(uae);
+ }
+ catch (UnsupportedAddressTypeException uate) {
+ throw new XDevException(uate);
+ }
+ catch (SecurityException se) {
+ throw new XDevException(se);
+ }
+ catch (IOException ioe) {
+ // this is continuing coz process 1 alwayz connect to
+ // process 0
+ // server socket. If process 0 is not up, then this
+ // exception
+ connected = false;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("connecting error ->" + ioe.getMessage());
+ }
+
+ continue;
+ }
+
+ try {
+ rChannels[index].configureBlocking(false);
+ rChannels[index].register(selector, SelectionKey.OP_READ);
+ rChannels[index].socket().setTcpNoDelay(true);
+ // these are useful if running MPJ on gigabit ethernet.
+ rChannels[index].socket().setSendBufferSize(524288);
+ rChannels[index].socket().setReceiveBufferSize(524288);
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ synchronized (readableChannels) {
+ readableChannels.add(rChannels[index]);
+ if (readableChannels.size() == nprocs - 1) {
+ readableChannels.notify();
+ }
+ } // end synch
+
+ connected = true;
+ } // end while
+
+ connected = false;
+ } // end if
+
+ index++;
+ temp++;
+
+ } // end while
+
+ /* This is connection-code for control-channels. */
+ connected = false;
+ temp = 0;
+ index = 0;
+
+ /*
+ * This while loop is connecting to server sockets of other peers. If there
+ * are 4 processes, process 0 will not connect to any process, process 1
+ * will connect to process 0, process 2 will connect to pro 0&1, and process
+ * 3 will connect to pro 0&1&2
+ */
+
+ while (temp < nprocs - 1) {
+
+ if (rank == rankList[temp]) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Dont connect to itself, so contine;");
+ }
+
+ temp++;
+ continue;
+ }
+
+ if (rankList[temp] < rank) {
+
+ while (!connected) {
+
+ try {
+ wChannels[index] = SocketChannel.open();
+ wChannels[index].configureBlocking(true);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Connecting to " + nodeList[temp] + "@"
+ + rPortList[temp]);
+ }
+
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ try {
+
+ connected = wChannels[index].connect(new InetSocketAddress(
+ nodeList[temp], rPortList[temp]));
+
+ }
+ catch (AlreadyConnectedException ace) {
+ throw new XDevException(ace);
+ }
+ catch (ConnectionPendingException cpe) {
+ throw new XDevException(cpe);
+ }
+ catch (ClosedChannelException cce) {
+ throw new XDevException(cce);
+ }
+ catch (UnresolvedAddressException uae) {
+ throw new XDevException(uae);
+ }
+ catch (UnsupportedAddressTypeException uate) {
+ throw new XDevException(uate);
+ }
+ catch (SecurityException se) {
+ throw new XDevException(se);
+ }
+ catch (IOException ioe) {
+ // this is continuing coz process 1 alwayz connect to
+ // process 0
+ // server socket. If process 0 is not up, then this
+ // exception
+ connected = false;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("connecting error ->" + ioe.getMessage());
+ }
+
+ continue;
+ }
+
+ try {
+ wChannels[index].configureBlocking(true);
+ wChannels[index].socket().setTcpNoDelay(true);
+ // these are useful if running MPJ on gigabit ethernet
+ wChannels[index].socket().setSendBufferSize(524288);
+ wChannels[index].socket().setReceiveBufferSize(524288);
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ synchronized (writableChannels) {
+
+ writableChannels.add(wChannels[index]);
+
+ if (writableChannels.size() == nprocs - 1) {
+ writableChannels.notify();
+ }
+
+ } // end synch
+
+ connected = true;
+ } // end while
+
+ connected = false;
+ } // end if
+
+ index++;
+ temp++;
+
+ } // end while
+
+ index = rank;
+ root = 0;
+ procTree = new ProcTree();
+ extent = nprocs;
+ places = ProcTree.PROCTREE_A * index;
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ ch %= extent;
+
+ if (places < extent) {
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ }
+ }
+
+ if (index == root) {
+ procTree.isRoot = true;
+ } else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ }
+
+ procTree.root = root;
+
+ selectorThreadStarter = new Thread(selectorThread);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Starting the selector thread ");
+ }
+
+ selectorThreadStarter.start();
+
+ // addShutdownHook();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("testing if all peers are connected?");
+ }
+
+ count = 0;
+
+ /*
+ * doAccept() and/or while loop above adds SocketChannels to
+ * writableChannels so access to writableChannels should be synchronized.
+ */
+ synchronized (writableChannels) {
+
+ if (writableChannels.size() != nprocs - 1) {
+ try {
+ writableChannels.wait();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+
+ } // end sync.
+
+ /* This is for control-channels. */
+ synchronized (readableChannels) {
+
+ if (readableChannels.size() != nprocs - 1) {
+ try {
+ readableChannels.wait();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+
+ } // end sync.
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info(" Yes all nodes are connected to each other ");
+ }
+
+ /*
+ * At this point, all-to-all connectivity has been acheived. Each process
+ * has all SocketChannels (for peers) in writableChannels (Vector object).
+ * Now each process will send rank(this rank is the one read from
+ * config-file), msb (most significant bits), lsb(least significant bits) to
+ * all the other processes. After receiving this info, all processes will
+ * have constructed worldTable (Hashtable object), which contains <k,v>,
+ * where k=UUID of a process, and v=SocketChannel object. This worldTable is
+ * used extensively throughout the niodev.
+ */
+
+ SocketChannel socketChannel = null;
+ ByteBuffer initMsgBuffer = ByteBuffer.allocate(24);
+ long msb = myuuid.getMostSignificantBits();
+ long lsb = myuuid.getLeastSignificantBits();
+ initMsgBuffer.putInt(INIT_MSG_HEADER_DATA_CHANNEL);
+ initMsgBuffer.putInt(rank);
+ initMsgBuffer.putLong(msb);
+ initMsgBuffer.putLong(lsb);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("rank<" + rank
+ + ">is sending its rank,msb,lsb, to all data channels");
+ }
+
+ /* Writing stuff into writable-channels */
+ for (int i = 0; i < writableChannels.size(); i++) {
+ socketChannel = writableChannels.get(i);
+ initMsgBuffer.flip();
+
+ /* Do we need to iterate here? */
+ while (initMsgBuffer.hasRemaining()) {
+ try {
+ if (socketChannel.write(initMsgBuffer) == -1) {
+ throw new XDevException(new ClosedChannelException());
+ }
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ } // end while.
+ _wcb.clear();
+ } // end for.
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("rank<" + rank + "> testing if everything is received? ");
+ }
+
+ /*
+ * worldTable is accessed from doBarrierRead or here, so their access should
+ * be synchronized
+ */
+ synchronized (worldReadableTable) {
+ if ((worldReadableTable.size() != nprocs - 1)) {
+ try {
+ worldReadableTable.wait();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+ } // end sync
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("worldReadableTable is filled ");
+ }
+
+ /* Writing stuff into readable-channels */
+ for (int i = 0; i < readableChannels.size(); i++) {
+ socketChannel = readableChannels.get(i);
+ initMsgBuffer.flip();
+
+ /* Do we need to iterate here? */
+ while (initMsgBuffer.hasRemaining()) {
+ try {
+ if (socketChannel.write(initMsgBuffer) == -1) {
+ throw new XDevException(new ClosedChannelException());
+ }
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ } // end while.
+ } // end for.
+
+ /*
+ * Do blocking-reads, is this correct? will work but wont scale i think.
+ */
+ for (int i = 0; i < writableChannels.size(); i++) {
+ socketChannel = writableChannels.get(i);
+ try {
+ doBarrierRead(socketChannel, worldWritableTable, true);
+ }
+ catch (XDevException xde) {
+ throw xde;
+ }
+ }
+
+ synchronized (worldWritableTable) {
+ if ((worldWritableTable.size() != nprocs - 1)) {
+ try {
+ worldWritableTable.wait();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+ } // end sync
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("worldWritable is filled ");
+ }
+
+ // writableServerChannel.close();
+ // readableServerChannel.close();
+ pids[rank] = id;
+
+ for (int k = 0; k < writableChannels.size(); k++) {
+ writeLockTable.put(writableChannels.elementAt(k), new CustomSemaphore(1));
+ }
+
+ try {
+ writableServerChannel.close();
+ readableServerChannel.close();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return pids;
+
+ } // end init
+
+ /**
+ * Returns the id of this process.
+ *
+ * @return ProcessID An object containing UUID of the process
+ */
+ public ProcessID id() {
+ return id;
+ }
+
+ public int getSendOverhead() {
+ return SEND_OVERHEAD;
+ }
+
+ public int getRecvOverhead() {
+ return RECV_OVERHEAD;
+ }
+
+ /**
+ * Non-Blocking probe method.
+ *
+ * @param srcID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobe(ProcessID srcID, int tag, int context)
+ throws XDevException {
+
+ UUID dstUUID = id.uuid(), srcUUID = srcID.uuid();
+ mpjdev.Status status = null;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---iprobe---");
+ logger.debug("srcUUID:" + srcUUID + "tag:" + tag);
+ logger.debug("id.uuid():" + id.uuid());
+ // logger.debug("srcID.rank():" + srcID.rank());
+ logger.debug("ANY_SOURCE:" + ANY_SOURCE);
+ logger.debug("Looking whether this req has been posted or not");
+ }
+
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ NIORecvRequest request = arrQue.check(context, dstUUID, srcUUID, tag);
+
+ if (request != null) {
+ // now this is a tricky one ...
+ status = new mpjdev.Status(request.srcUUID, // srcID.rank(),
+ request.tag, -1, request.type, request.numEls);
+ }
+ sem.signal();
+ return status;
+ }
+
+ /**
+ * Non-Blocking iprobeAndFetch method.
+ *
+ * @param srcID
+ * @param dstID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID,
+ int tag, int context, mpjbuf.Buffer buf) throws XDevException {
+
+ UUID dstUUID = dstID.uuid(), srcUUID = srcID.uuid();
+
+ mpjdev.Status status = null;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---iprobe---");
+ logger.debug("srcUUID:" + srcUUID + "tag:" + tag);
+ logger.debug("id.uuid():" + id.uuid());
+ logger.debug("ANY_SOURCE:" + ANY_SOURCE);
+ logger.debug("Looking whether this req has been posted or not");
+ }
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ NIORecvRequest request = arrQue.remForIprobeAndFetch(context, dstUUID,
+ srcUUID, tag);
+
+ if (request != null) {
+ status = new mpjdev.Status(request.srcHybUUID, request.tag, -1,
+ request.type, request.numEls);
+
+ request.status = status;
+
+ if (((request.sBufSize + request.dBufSize) <= psl)
+ && request.commMode == STD_COMM_MODE) {
+ sem.signal();
+ if (request.sBufSize > 0) {
+ request.staticBuffer = ((NIOBuffer) buf.getStaticBuffer())
+ .getBuffer();
+ ByteBuffer eagerBuffer = ((NIOBuffer) request.eagerBuffer)
+ .getBuffer();
+ request.staticBuffer.position(0);
+ request.staticBuffer.limit(request.sBufSize);
+ eagerBuffer.limit(request.sBufSize);
+ eagerBuffer.position(0);
+ request.staticBuffer.put(eagerBuffer);
+ BufferFactory.destroy(request.eagerBuffer);
+ } // end if
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting the buf size " + request.sBufSize);
+ }
+
+ buf.setSize(request.sBufSize);
+
+ if (request.dBufSize > 0) {
+ buf.setDynamicBuffer(request.dynamicBuffer);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("removed ");
+ }
+ return status;
+ } else if ((((request.sBufSize + request.dBufSize) > psl) && request.commMode == STD_COMM_MODE)
+ || (request.commMode == SYNC_COMM_MODE)) {
+ sem.signal();
+ mpjdev.Request req = irecv(buf, new ProcessID(request.srcUUID), tag,
+ context, status);
+
+ return req.iwait();
+ }
+ }
+ // System.out.println
+ // (" niodev: incomplete Request, releasing lock in Fetch ");
+ sem.signal();
+ return status;
+
+ }
+
+ /**
+ * Non-Blocking overloaded probe method.
+ *
+ * @param srcID
+ * @param dstID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+
+ public mpjdev.Status iprobe(ProcessID srcID, ProcessID dstID, int tag,
+ int context) throws XDevException {
+
+ UUID dstUUID = dstID.uuid(), srcUUID = srcID.uuid();
+
+ mpjdev.Status status = null;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---iprobe---");
+ logger.debug("srcUUID:" + srcUUID + "tag:" + tag);
+ logger.debug("id.uuid():" + id.uuid());
+ logger.debug("ANY_SOURCE:" + ANY_SOURCE);
+ logger.debug("Looking whether this req has been posted or not");
+ }
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ NIORecvRequest request = arrQue.check(context, dstUUID, srcUUID, tag);
+
+ if (request != null) {
+ // now this is a tricky one ...
+ status = new mpjdev.Status(request.srcHybUUID, // srcID.rank(),
+ request.tag, -1, request.type, request.numEls);
+ }
+
+ sem.signal();
+
+ return status;
+ }
+
+ /**
+ * Blocking probe method
+ *
+ * @param srcID
+ * The sourceID of the sender
+ * @param tag
+ * The tag of the message
+ * @param context
+ * The integer specifying the context
+ * @return mpjdev.Status The status object
+ */
+ public mpjdev.Status probe(ProcessID srcID, int tag, int context)
+ throws XDevException {
+
+ mpjdev.Status status = null;
+ boolean comp = false;
+
+ while (!comp) {
+ status = this.iprobe(srcID, tag, context);
+ if (status != null) {
+ comp = true;
+ }
+ }
+
+ return status;
+ }
+
+ private synchronized int sendCounter() {
+ return ++sendCounter;
+ }
+
+ private synchronized int recvCounter() {
+ return ++recvCounter;
+ }
+
+ private synchronized int hashCode(int tag, int context, int srcHash,
+ int dstHash) {
+ return tag + context * 5 + dstHash * 11 + srcHash * 17 + dstHash * 19;
+ }
+
+ /**
+ * Non-blocking send method
+ *
+ * @param buf
+ * The mpjbuf.Buffer object containing the data.
+ * @param dstID
+ * ProcessID of the destination process.
+ * @param tag
+ * The unique identifier of the message.
+ * @param context
+ * An integer providing "safe universe" for messages.
+ * @return mpjdev.Request The Request object, which is later used to check the
+ * status of the message.
+ */
+ public mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context) throws XDevException {
+
+ UUID dstUUID = dstID.uuid();
+
+ UUID srcUUID = id.uuid();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---isend---<" + tag + ">");
+ logger.debug("sender :" + id.uuid());
+ logger.debug("receiver :" + dstUUID);
+ logger.debug("tag :" + tag);
+ // logger.debug("staticBufferSize :" + req.sBufSize );
+ // logger.debug("dynamicBufferSize :" + req.dBufSize );
+ // logger.debug("req.sendCounter :" + req.sendCounter );
+ }
+
+ if (dstUUID.equals(srcUUID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("sender and receiver are same process ");
+ }
+
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ NIORecvRequest recvRequest = recvQueue
+ .rem(context, dstUUID, srcUUID, tag);
+
+ NIOSendRequest sendRequest = new NIOSendRequest(tag, // NO_ACK_RECEIVED,
+ id(), dstID, buf, context, STD_COMM_MODE, -1);
+
+ if (recvRequest != null) {
+
+ sem.signal();
+ recvRequest.type = sendRequest.type;
+ recvRequest.numEls = sendRequest.numEls;
+ recvRequest.buffer.setSize(sendRequest.sBufSize);
+ recvRequest.sBufSize = sendRequest.sBufSize;
+ recvRequest.dBufSize = sendRequest.dBufSize;
+
+ /* copy the dynamic portion */
+ recvRequest.buffer.setDynamicBuffer(sendRequest.dynamicBuffer);
+
+ /* copy the static portion */
+ recvRequest.staticBuffer.limit(recvRequest.sBufSize);
+ recvRequest.staticBuffer.position(0);
+ sendRequest.staticBuffer.limit(recvRequest.sBufSize
+ + sendRequest.bufoffset);
+ sendRequest.staticBuffer.position(sendRequest.bufoffset);
+ recvRequest.staticBuffer.put(sendRequest.staticBuffer);
+
+ recvRequest.staticBuffer.flip();
+
+ /* comms complete */
+ // completedList.add(sendRequest);
+ // completedList.add(recvRequest);
+ recvRequest.setCompleted(true);
+ sendRequest.setCompleted(true);
+
+ return sendRequest;
+ } else {
+
+ recvRequest = new NIORecvRequest(id.uuid(), tag, false, context,
+ sendRequest.sBufSize, sendRequest.dBufSize, sendRequest.commMode,
+ null // (socketChannel)
+ , sendRequest.numEls, sendRequest.type, -1, -1, srcUUID);
+
+ recvRequest.sendRequest = sendRequest;
+ arrQue.add(recvRequest);
+ sem.signal();
+ return sendRequest;
+ }
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("isend with remote process connections");
+ }
+
+ NIOSendRequest req = new NIOSendRequest(tag, id(), dstID, buf, context,
+ STD_COMM_MODE, sendCounter());
+
+ SocketChannel channel = worldWritableTable.get(dstUUID);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("channel :" + channel);
+ }
+
+ if ((req.sBufSize + req.dBufSize) <= psl) {
+
+ /* Eager-Send Procotol */
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("get writeLock for this channel");
+ }
+
+ CustomSemaphore wLock = writeLockTable.get(channel);
+
+ try {
+ wLock.acquire();
+ eagerSend(req, channel);
+ wLock.signal();
+ // completedList.add( req );
+ req.notifyMe();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ }
+ /* Rendezvous Protocol */
+ else if ((req.sBufSize + req.dBufSize) > psl) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("rendezvous protocol.");
+ logger.debug(" get send-comms set lock ");
+ }
+
+ try {
+ sLock.acquire();
+ }
+ catch (Exception e) {
+ }
+
+ sendMap.put(new Integer(req.sendCounter), req);
+ sLock.signal();
+ CustomSemaphore wLock = writeLockTable.get(channel);
+
+ try {
+ wLock.acquire();
+ rendezCtrlMsgSend(req, channel);
+ wLock.signal();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---isend ends---<" + tag + ">");
+ }
+
+ return req;
+
+ } // end isend.
+
+ /**
+ * Non-blocking synchronous send.
+ */
+ public mpjdev.Request issend(mpjbuf.Buffer buf, ProcessID dstID, int tag,
+ int context) throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---issend---");
+ }
+
+ NIOSendRequest req = null;
+ SocketChannel channel = null;
+ UUID dstUUID = dstID.uuid();
+ UUID srcUUID = id.uuid();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---isend---<" + tag + ">");
+ logger.debug("sender :" + id.uuid());
+ logger.debug("receiver :" + dstUUID);
+ logger.debug("tag :" + tag);
+ // logger.debug("staticBufferSize :" + req.sBufSize );
+ // logger.debug("dynamicBufferSize :" + req.dBufSize );
+ // logger.debug("req.sendCounter :" + req.sendCounter );
+ }
+
+ if (dstUUID.equals(srcUUID)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("sender and receiver are same process ");
+ }
+
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ }
+
+ NIORecvRequest recvRequest = recvQueue
+ .rem(context, dstUUID, srcUUID, tag);
+
+ NIOSendRequest sendRequest = new NIOSendRequest(tag, id(), dstID, buf,
+ context, SYNC_COMM_MODE, -1);
+
+ if (recvRequest != null) {
+
+ sem.signal();
+ recvRequest.type = sendRequest.type;
+ recvRequest.numEls = sendRequest.numEls;
+ recvRequest.buffer.setSize(sendRequest.sBufSize);
+ recvRequest.sBufSize = sendRequest.sBufSize;
+ recvRequest.dBufSize = sendRequest.dBufSize;
+
+ /* copy the dynamic portion */
+ recvRequest.buffer.setDynamicBuffer(sendRequest.dynamicBuffer);
+
+ /* copy the static portion */
+ recvRequest.staticBuffer.limit(recvRequest.sBufSize);
+ recvRequest.staticBuffer.position(0);
+ sendRequest.staticBuffer.limit(recvRequest.sBufSize
+ + sendRequest.bufoffset);
+ sendRequest.staticBuffer.position(sendRequest.bufoffset);
+ recvRequest.staticBuffer.put(sendRequest.staticBuffer);
+
+ recvRequest.staticBuffer.flip();
+
+ /* comms complete */
+ // completedList.add(sendRequest);
+ // completedList.add(recvRequest);
+ recvRequest.setCompleted(true);
+ sendRequest.setCompleted(true);
+
+ return sendRequest;
+ } else {
+
+ recvRequest = new NIORecvRequest(id.uuid(), tag, false, context,
+ sendRequest.sBufSize, sendRequest.dBufSize, sendRequest.commMode,
+ null // (socketChannel)
+ , sendRequest.numEls, sendRequest.type, -1, -1, srcUUID);
+
+ recvRequest.sendRequest = sendRequest;
+ arrQue.add(recvRequest);
+ sem.signal();
+ return sendRequest;
+ }
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("isend with remote process connections");
+ }
+
+ req = new NIOSendRequest(tag, id(), dstID, buf, context, SYNC_COMM_MODE,
+ sendCounter());
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("sender :" + id.uuid());
+ logger.debug("receiver :" + dstUUID);
+ logger.debug("tag :" + tag);
+ logger.debug("staticBufferSize :" + req.sBufSize);
+ logger.debug("dynamicBufferSize :" + req.dBufSize);
+ logger.debug("buffset :" + 0);
+ logger.debug("Rendezous(isend), calling rendezCtrlMsgSend");
+ }
+
+ channel = worldWritableTable.get(dstUUID);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("channel (can never be null) " + channel);
+ }
+
+ try {
+ sLock.acquire();
+ }
+ catch (Exception e) {
+ }
+
+ sendMap.put(new Integer(req.sendCounter), req);
+ sLock.signal();
+ CustomSemaphore wLock = writeLockTable.get(channel);
+
+ try {
+ wLock.acquire();
+ rendezCtrlMsgSend(req, channel);
+ wLock.signal();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---issend ends---<" + tag + ">");
+ }
+
+ return req;
+
+ } // end issend
+
+ /**
+ * Blocking send method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer object containing the data.
+ * @param dstID
+ * ProcessID of the destination
+ * @param tag
+ * The unique identifier of the message
+ * @param context
+ * An integer providing "safe universe" for messages.
+ * @throws MPJException
+ * If the buffer is null, dest process ID is insane.
+ * @throws java.nio.BufferOverflowException
+ * @throws ReadOnlyBufferException
+ * @throws IOException
+ * If some I/O error occurs
+ */
+ public void send(mpjbuf.Buffer buf, ProcessID dstID, int tag, int context)
+ throws XDevException {
+
+ Request request = isend(buf, dstID, tag, context);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Calling request.iwait() in send method, it may not return");
+ }
+
+ request.iwait();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Called request.iwait() in sng this, means it returned");
+ }
+
+ }
+
+ /**
+ * Blocking synchronous send
+ */
+ public void ssend(mpjbuf.Buffer buf, ProcessID dstID, int tag, int context)
+ throws XDevException {
+
+ Request request = issend(buf, dstID, tag, context);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Calling request.iwait() in send method, it may not return");
+ }
+
+ request.iwait();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Called request.iwait()eeing this, means it returned");
+ }
+
+ }
+
+ /**
+ * This method is used by the sender to send the control message to the
+ * receiver
+ */
+ private void rendezCtrlMsgSend(NIOSendRequest request,
+ SocketChannel socketChannel) throws Exception {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---rendezCtrlMsgSend---");
+ logger.debug(" request.tag " + request.tag);
+ }
+
+ request.staticBuffer.limit(request.bufoffset);
+ request.staticBuffer.position(0);
+
+ request.staticBuffer.putInt(READY_TO_SEND);
+ request.staticBuffer.putLong(id().uuid().getMostSignificantBits());
+ request.staticBuffer.putLong(id().uuid().getLeastSignificantBits());
+ request.staticBuffer.putInt(request.tag);
+ request.staticBuffer.putInt(request.sBufSize);
+ request.staticBuffer.putInt(request.dBufSize);
+ request.staticBuffer.putInt(request.commMode);
+ request.staticBuffer.putInt(request.context);
+ request.staticBuffer.putInt(request.numEls);
+ request.staticBuffer.putInt(request.sendCounter);
+ request.staticBuffer.put((byte) request.type.getCode());
+ /*
+ * Checking if Hybrid device is enabled then source and destination of
+ * message should be Hybrid source and destination, not those of Network
+ * souruce and destination. So UUIDs of Hybrid source and destination should
+ * be sent in the Ctrl message.
+ */
+ if (isHybrid) {
+ request.staticBuffer.putLong(request.srcHybUUID.getMostSignificantBits());
+ request.staticBuffer
+ .putLong(request.srcHybUUID.getLeastSignificantBits());
+ request.staticBuffer.putLong(request.dstHybUUID.getMostSignificantBits());
+ request.staticBuffer
+ .putLong(request.dstHybUUID.getLeastSignificantBits());
+ }
+
+ request.staticBuffer.limit(request.bufoffset);
+ request.staticBuffer.position(0);
+
+ int w = 0;
+ int ww = 0;
+
+ while (request.staticBuffer.hasRemaining()) {
+ if ((w = socketChannel.write(request.staticBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+ ww += w;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---rendezCtrlMsgSend ENDS ---");
+ }
+ } // end rendezCtrlMsgSend
+
+ private void eagerSend(NIOSendRequest request, SocketChannel socketChannel)
+ throws Exception {
+
+ // long strt = System.nanoTime() ;
+ // long stop = 0L, intv = 0L;
+
+ int w = 0, ww = 0;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---eagerSend---");
+ logger.debug(" request.bufoffset " + request.bufoffset);
+ }
+
+ request.staticBuffer.limit(request.bufoffset);
+ request.staticBuffer.position(0);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("sendBuffer " + request.staticBuffer);
+ }
+
+ request.staticBuffer.putInt(READY_TO_SEND);
+ request.staticBuffer.putLong(id().uuid().getMostSignificantBits());
+ request.staticBuffer.putLong(id().uuid().getLeastSignificantBits());
+ request.staticBuffer.putInt(request.tag);
+ request.staticBuffer.putInt(request.sBufSize);
+ request.staticBuffer.putInt(request.dBufSize);
+ request.staticBuffer.putInt(request.commMode);
+ request.staticBuffer.putInt(request.context);
+ request.staticBuffer.putInt(request.numEls);
+ request.staticBuffer.putInt(request.sendCounter);
+ request.staticBuffer.put((byte) request.type.getCode());
+
+ /*
+ * Checking if Hybrid device is enabled then source and destination of
+ * message should be Hybrid source and destination, not those of Network
+ * souruce and destination. So UUIDs of Hybrid source and destination should
+ * be sent in the eager message.
+ */
+ if (isHybrid) {
+ request.staticBuffer.putLong(request.srcHybUUID.getMostSignificantBits());
+ request.staticBuffer
+ .putLong(request.srcHybUUID.getLeastSignificantBits());
+ request.staticBuffer.putLong(request.dstHybUUID.getMostSignificantBits());
+ request.staticBuffer
+ .putLong(request.dstHybUUID.getLeastSignificantBits());
+ }
+
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("isend_packing_time_route1 <"+intv/1000);
+
+ /* Writing the static section of the buffer */
+ if (request.sBufSize > 0) {
+
+ request.staticBuffer.limit(request.sBufSize + request.bufoffset);
+ request.staticBuffer.position(0);
+ w = 0;
+ ww = 0;
+
+ while (request.staticBuffer.hasRemaining()) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.staticBuffer (1)<" + request.staticBuffer
+ + "> w=" + w);
+ }
+
+ if ((w = socketChannel.write(request.staticBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ ww += w;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.staticBuffer (2)<" + request.staticBuffer
+ + "> w=" + w);
+ }
+
+ /* Some error conditions */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+
+ if (ww > (request.sBufSize + request.bufoffset)) {
+ logger.fatal(" Fatal-Bug (1) <" + request.tag + ">");
+ logger.fatal("request.staticBuffer " + request.staticBuffer);
+ System.exit(1);
+ }
+
+ if (request.staticBuffer.hasRemaining()) {
+ logger.fatal(" Bug (1) <" + request.tag + ">");
+ logger.fatal("request.staticBuffer " + request.staticBuffer);
+ System.exit(1);
+ }
+
+ if (request.staticBuffer.position() != (request.sBufSize + request.bufoffset)) {
+ logger.fatal(" Bug (2) <" + request.tag + ">");
+ logger.fatal("request.staticBuffer " + request.staticBuffer);
+ System.exit(1);
+ }
+
+ if (request.staticBuffer.position() != request.staticBuffer.limit()) {
+ logger.fatal(" Bug (3) <" + request.tag + ">");
+ logger.fatal("request.staticBuffer " + request.staticBuffer);
+ System.exit(1);
+ }
+ } // error condition
+ }// end while writing.
+
+ } // end writing static section.
+
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("isend_packing_time_route1 <"+intv/1000);
+ // strt = System.nanoTime() - strt ;
+ // logger.debug("isend_writing_time <"+intv/1000);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.dBufSize <" + request.dBufSize + ">");
+ }
+
+ /* Writing the dynamic section of the buffer */
+ if (request.dynamicBuffer != null && request.dBufSize > 0) {
+ RawBuffer rawBuffer = BufferFactory.create(request.dBufSize);
+ ByteBuffer buffer = ((NIOBuffer) rawBuffer).getBuffer();
+ buffer.position(0);
+ buffer.limit(request.dBufSize);
+
+ buffer.put(request.dynamicBuffer, 0, request.dBufSize);
+ buffer.flip();
+ ww = 0;
+ w = 0;
+
+ while (buffer.hasRemaining()) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buffer (1)<" + buffer + ">");
+ }
+
+ if ((w = socketChannel.write(buffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+ ww += w;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buffer (2)<" + buffer + ">");
+ }
+
+ } // end while.
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ if (buffer.hasRemaining()) {
+ logger.fatal(" Bug (4) <" + request.tag + ">");
+ logger.fatal("buffer " + buffer);
+ System.exit(1);
+ }
+
+ if (buffer.position() != (request.dBufSize)) {
+ logger.fatal("Bug (5) <" + request.tag + ">");
+ logger.fatal("buffer " + buffer);
+ System.exit(1);
+ }
+
+ if (buffer.position() != buffer.limit()) {
+ logger.fatal("Bug (6) <" + request.tag + ">");
+ logger.fatal("buffer " + buffer);
+ System.exit(1);
+ }
+
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("written down bytes " + buffer.position());
+ }
+
+ BufferFactory.destroy(rawBuffer);
+
+ } // end writing dynamic section
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--eagerSend finishes--");
+ }
+
+ } // end eagerSend
+
+ public mpjdev.Request peek() throws XDevException {
+ return completedList.remove();
+ }
+
+ static CompletedList completedList = new CompletedList();
+
+ static class CompletedList {
+
+ NIORequest front, back;
+ int size;
+
+ /**
+ * Remove request from any position in the completedList
+ */
+ synchronized void remove(NIORequest request) {
+ if (request.inCompletedList) {
+ if (front == back) {
+ front = null;
+ back = null;
+ } else if (front == request) {
+ front.prevCompleted.nextCompleted = front.nextCompleted;
+ front.nextCompleted.prevCompleted = front.prevCompleted;
+ front = front.prevCompleted;
+ } else if (back == request) {
+ back.prevCompleted.nextCompleted = back.nextCompleted;
+ back.nextCompleted.prevCompleted = back.prevCompleted;
+ back = back.nextCompleted;
+ } else {
+ request.prevCompleted.nextCompleted = request.nextCompleted;
+ request.nextCompleted.prevCompleted = request.prevCompleted;
+ }
+
+ request.inCompletedList = false;
+ size--;
+ // System.out.println(" size "+size);
+ }
+ }
+
+ /**
+ * Remove request from the front of completedList Wait until a request is
+ * found
+ */
+ synchronized NIORequest remove() {
+
+ while (listEmpty()) {
+ try {
+ wait();
+ }
+ catch (Exception e) {
+ }
+ }
+
+ NIORequest oldFront = null;
+ oldFront = front;
+ if (front == back) {
+ front = null;
+ back = null;
+ } else {
+ front.prevCompleted.nextCompleted = front.nextCompleted;
+ front.nextCompleted.prevCompleted = front.prevCompleted;
+ front = front.prevCompleted;
+ }
+
+ oldFront.inCompletedList = false;
+ size--;
+ // System.out.println(" size "+size);
+
+ return oldFront;
+ }
+
+ /**
+ * Add request at the front of completedList
+ */
+ synchronized void add(NIORequest request) {
+ if (listEmpty()) {
+ front = request;
+ back = request;
+ request.nextCompleted = request;
+ request.prevCompleted = request;
+ } else {
+ front.nextCompleted.prevCompleted = request;
+ request.nextCompleted = front.nextCompleted;
+ front.nextCompleted = request;
+ request.prevCompleted = front;
+ back = request;
+ }
+ size++;
+ // System.out.println(" size "+size);
+ request.inCompletedList = true;
+ notify();
+ }
+
+ boolean listEmpty() {
+ return (front == null && back == null);
+ }
+
+ }
+
+ /**
+ * iwaitany
+ *
+ * public static mpjdev.Status iwaitany(mpjdev.Request[] requests) { boolean
+ * found = false; boolean inActive = true ; mpjdev.Status completedStatus =
+ * null ;
+ *
+ * // check if there is a valid request which could be peeked
+ *
+ * for(int i=0 ; i< requests.length ; i++) { if(requests[i] != null) {
+ * inActive = false; } }
+ *
+ * if(inActive) { return null; }
+ *
+ * do { for(int j=0 ; j <requests.length ; j++) {
+ *
+ * if(requests[j] == null) { continue; }
+ *
+ * completedStatus = requests[j].itest() ;
+ *
+ * if(completedStatus == null) { continue; }
+ *
+ * completedStatus = requests[j].iwait() ; completedStatus.index = j; found =
+ * true ; break ;
+ *
+ * } } while(!found);
+ *
+ * return completedStatus ; }
+ */
+
+ /**
+ * This method is the non-blocking recv method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer object where the user wishes to receive the
+ * actual message
+ * @param srcID
+ * The process id of the sending process
+ * @param tag
+ * The unique identifier of the message
+ * @return Status The status object containing the details of recv
+ * @throws MPJException
+ * If the buffer is null or the src is insane
+ * @throws IOException
+ * If some I/O error occurs
+ * @throws java.lang.IllegalArgumentException
+ */
+ public mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context) throws XDevException {
+
+ mpjdev.Status status = new mpjdev.Status(srcID.uuid(), tag, -1);
+ Request request = irecv(buf, srcID, tag, context, status);
+
+ return request.iwait();
+
+ }
+
+ /**
+ * Blocking receive method.
+ *
+ * @param buf
+ * The mpjbuf.Buffer objereceive the actual message
+ * @param srcID
+ * The process id of the sending process
+ * @param tag
+ * The unique identifier of the message
+ * @param context
+ * An integer that provides "safe communication" universe
+ * @return mpjdev.Status The status object containing the details of recv
+ */
+ public Request irecv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context, mpjdev.Status status) throws XDevException {
+
+ UUID dstUUID = id.uuid();
+ UUID srcUUID = srcID.uuid();
+ UUID srcHybUUID = null, dstHybUUID = null;
+
+ if (isHybrid) {
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(0);
+ long msb = 0L, lsb = 0L;
+ msb = ((NIOBuffer) buf.getStaticBuffer()).getBuffer().getLong();
+ lsb = ((NIOBuffer) buf.getStaticBuffer()).getBuffer().getLong();
+ srcHybUUID = new UUID(msb, lsb);
+ msb = ((NIOBuffer) buf.getStaticBuffer()).getBuffer().getLong();
+ lsb = ((NIOBuffer) buf.getStaticBuffer()).getBuffer().getLong();
+ dstHybUUID = new UUID(msb, lsb);
+
+ try {
+ buf.clear();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---irecv---<" + tag + ">");
+ logger.debug("Looking whether this req has been posted or not");
+ }
+
+ // long strt = System.nanoTime() ;
+ // long stop = 0L, intv = 0L;
+ try {
+ sem.acquire();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ NIORecvRequest request = null;
+
+ try {
+ /*
+ * Checking if Hybrid device is enabled then source and destination of
+ * message should be Hybrid source and destination, not those of Network
+ * souruce and destination. Key of message will be Hybrid Source and
+ * Destination.
+ */
+ if (isHybrid) {
+ request = arrQue.rem(context, dstHybUUID, srcHybUUID, tag);
+ } else {
+ request = arrQue.rem(context, dstUUID, srcUUID, tag);
+ }
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ if (request != null) {
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_determing_its_posted <"+intv/1000);
+
+ /*
+ * some stuff is only known when the recv is posted ...so setting that
+ * kinda stuff in the next few lines
+ */
+ request.staticBuffer = ((NIOBuffer) buf.getStaticBuffer()).getBuffer();
+ request.status = status;
+ // request.rank_source = srcID.rank();
+
+ if (request.srcUUID.equals(dstUUID)) {
+ sem.signal();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" request.sendRequest.staticBuffer "
+ + request.sendRequest.staticBuffer);
+ logger.debug(" request.sendRequest.bufoffset "
+ + request.sendRequest.bufoffset);
+ logger.debug(" request.sBufSize " + request.sBufSize);
+ }
+
+ buf.copy(request.sendRequest.staticBuffer,
+ request.sendRequest.bufoffset, request.sBufSize, 0,
+ request.sendRequest.dynamicBuffer, request.dBufSize);
+
+ // completedList.add(request);
+ // completedList.add(request.sendRequest);
+ request.setCompleted(true);
+ request.sendRequest.setCompleted(true);
+ return request;
+
+ }
+
+ else if (((request.sBufSize + request.dBufSize) <= psl)
+ && request.commMode == STD_COMM_MODE) {
+
+ /*
+ * (Eager-Send), The message has already been copied to xdev buffad so
+ * we just need to copy it from the xdevBuffer to the user buffer
+ */
+
+ if (request.sBufSize > 0) {
+ ByteBuffer eagerBuffer = ((NIOBuffer) request.eagerBuffer)
+ .getBuffer();
+ request.staticBuffer.position(0);
+ request.staticBuffer.limit(request.sBufSize);
+ eagerBuffer.limit(request.sBufSize);
+ eagerBuffer.position(0);
+ request.staticBuffer.put(eagerBuffer);
+ BufferFactory.destroy(request.eagerBuffer);
+ } // end if
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting the buf size " + request.sBufSize);
+ }
+
+ buf.setSize(request.sBufSize);
+
+ if (request.dBufSize > 0) {
+ buf.setDynamicBuffer(request.dynamicBuffer);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("removed ");
+ }
+
+ // completedList.add( request );
+ request.notifyMe();
+ sem.signal();
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_copying_from_devM <"+intv/1000);
+ return request;
+
+ } // end eager-send looop.
+
+ else if ((((request.sBufSize + request.dBufSize) > psl) && request.commMode == STD_COMM_MODE)
+ || (request.commMode == SYNC_COMM_MODE)) {
+
+ /*
+ * (Rendezous), writing the ctrl msg back, because (1) we have received
+ * the control message from the sender, (2)a matching receive is also
+ * posted
+ */
+
+ request.buffer = buf;
+ SocketChannel tc = worldReadableTable.get(request.srcUUID);
+ SocketChannel c = worldWritableTable.get(request.srcUUID);
+ recvMap.put(new Integer(request.recvCounter), request);
+ sem.signal();
+ CustomSemaphore wLock = writeLockTable.get(c);
+
+ try {
+ wLock.acquire();
+ }
+ catch (Exception e) {
+ }
+
+ rendezCtrlMsgR2S(c, request);
+ wLock.signal();
+ return request;
+
+ }
+
+ }
+
+ /*
+ * There is no matching receive method posted, so we post it here in the
+ * user thread and when the selector thread will be posting some thing,
+ * it'll check it first in the recvQue.
+ */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("No Matching req, so posting ourselves");
+ }
+
+ request = new NIORecvRequest(srcID, null, null, id(), tag,
+ REQ_NOT_COMPLETED, buf, context, status, ++recvCounter,
+ nextSequenceNum++);
+
+ /*
+ * If Hybrid device is being used then Initialize Hybrid Souce and
+ * Destination fields in Request object.
+ */
+ if (isHybrid) {
+ request.srcHybUUID = srcHybUUID;
+ request.dstHybUUID = dstHybUUID;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.staticBuffer (in recv) " + request.staticBuffer);
+ }
+
+ recvQueue.add(request);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Added request in irecv ");
+ }
+
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_posting_and_adding_to_queue <"+intv/1000);
+ sem.signal();
+ return request;
+
+ } // end irecv()
+
+ void addShutdownHook() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ logger.debug("shutdownHook thread");
+ try {
+ selector.wakeup();
+ selectorFlag = false;
+ try {
+ // serverChannel.close();
+ SocketChannel peerChannel = null;
+ SocketChannel controlChannel = null;
+
+ for (int i = 0; i < writableChannels.size(); i++) {
+ peerChannel = writableChannels.get(i);
+ peerChannel.close();
+ }
+
+ peerChannel = null;
+ selector.close();
+
+ }
+ catch (IOException e) {
+ // System.exit(0);
+ }
+ }
+ catch (Throwable e) {
+ // System.exit(0);
+ }
+ }
+ });
+ }
+
+ private void realFinish() throws XDevException {
+ selectorFlag = false;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---finish---");
+ logger.debug("Waking up the selector");
+ }
+ try {
+ selector.wakeup();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Closed the two selectors");
+ }
+
+ try {
+ selector.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ SocketChannel peerChannel = null;
+ SocketChannel peerCtrlChannel = null;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("peerChannelSize " + writableChannels.size());
+ logger.debug("peerCtrlChannelSize " + readableChannels.size());
+ }
+
+ for (int i = 0; i < writableChannels.size(); i++) {
+
+ peerChannel = writableChannels.get(i);
+ peerCtrlChannel = readableChannels.get(i);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("closing data-channel " + peerChannel);
+ }
+
+ try {
+
+ if (peerChannel.isOpen()) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("the channel was open, so closing it");
+ }
+ peerChannel.close();
+ }
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("closing control-channel " + peerCtrlChannel);
+ }
+
+ try {
+
+ if (peerCtrlChannel.isOpen()) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("the channel was open, so closing it");
+ }
+ peerCtrlChannel.close();
+ }
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("closed all the channels");
+ }
+
+ synchronized (finishLock) {
+ finished = true;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("selector thread notifying the user thread");
+ }
+ finishLock.notify();
+ }
+
+ }
+
+ Object finishLock = new Object();
+
+ static final int SHUTDOWN_SIGNAL = -13;
+ static final int END_OF_STREAM = -14;
+
+ /**
+ * This method shuts down the device.
+ *
+ * @throws MPJException
+ * @throws IOException
+ * If some I/O error occurs
+ */
+ public synchronized void finish() throws XDevException {
+ /*
+ * Calling NIO device finish method. in NIO finish method all the
+ * communication is purely for NIO device. No messages of Hybrid device is
+ * expected, setting the switch to false.
+ */
+
+ isHybrid = false;
+
+ synchronized (finishLock) {
+ if (finished) {
+ return;
+ }
+ }
+
+ // do this fanning bit ..
+ int offset = 0;
+ int[] data = new int[1];
+ int count = 1;
+ int btag = -994576;
+ int context = 50;
+ mpjbuf.Buffer sbuf = new mpjbuf.Buffer(
+ BufferFactory.create(23 + SEND_OVERHEAD), SEND_OVERHEAD,
+ 23 + SEND_OVERHEAD);
+ mpjbuf.Buffer rbuf = new mpjbuf.Buffer(BufferFactory.create(16), 0, 16);
+
+ if (procTree.numChildren == -1 || !procTree.isRoot) {
+ try {
+ sbuf.putSectionHeader(Type.INT);
+ sbuf.write(data, offset, count);
+ sbuf.commit();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (procTree.isRoot) {
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1) {
+ recv(rbuf, pids[procTree.child[i]], btag, context);
+ try {
+ rbuf.clear();
+ }
+ catch (Exception e) {
+ }
+ }
+ }
+ } else {
+ if (procTree.parent == -1) {
+ // System.out.println("non root's node parent doesn't exist");
+ }
+
+ for (int i = 0; i < procTree.child.length; i++) {
+ if (procTree.child[i] != -1) {
+ recv(rbuf, pids[procTree.child[i]], btag, context);
+ try {
+ rbuf.clear();
+ }
+ catch (Exception e) {
+ }
+ }
+ }
+
+ send(sbuf, pids[procTree.parent], btag, context);
+ }
+
+ if (procTree.isRoot) {
+ realFinish();
+ }
+
+ synchronized (finishLock) {
+
+ while (!finished) {
+ try {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("user thread going to sleep");
+ }
+ finishLock.wait();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ BufferFactory.destroy(sbuf.getStaticBuffer());
+ BufferFactory.destroy(rbuf.getStaticBuffer());
+
+ // System.out.println(" finish "+rank);
+
+ }
+
+ /*
+ * This method is used during initialization.
+ */
+ void doBarrierRead(SocketChannel socketChannel, Hashtable table,
+ boolean ignoreFirstFourBytes) throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---barrierRead---");
+ }
+ long lsb, msb;
+ int read = 0, tempRead = 0, rank;
+ UUID ruid = null;
+ ByteBuffer barrBuffer = ByteBuffer.allocate(24); // changeallocate
+
+ if (ignoreFirstFourBytes) {
+ barrBuffer.limit(24);
+ } else {
+ barrBuffer.limit(20);
+ }
+
+ while (barrBuffer.hasRemaining()) {
+ try {
+ if (socketChannel.read(barrBuffer) == -1) {
+ throw new XDevException(new ClosedChannelException());
+ }
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+
+ barrBuffer.flip();
+
+ if (ignoreFirstFourBytes) {
+ barrBuffer.getInt();
+ }
+
+ rank = barrBuffer.getInt();
+ msb = barrBuffer.getLong();
+ lsb = barrBuffer.getLong();
+ barrBuffer.clear();
+ ruid = new UUID(msb, lsb);
+ pids[rank] = new ProcessID(ruid); // , rank);
+ size = nprocs;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("(after ck) trying to add rank " + rank + "into table "
+ + table);
+ }
+
+ synchronized (table) {
+ table.put(ruid, socketChannel);
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Adding rank " + rank + "into table " + table);
+ }
+
+ if ((table.size() == nprocs - 1)) {
+ try {
+ table.notify();
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+
+ }
+
+ }
+
+ /* called from the selector thread, and accept the connections */
+ boolean doAccept(SelectableChannel keyChannel, Vector channelCollection,
+ boolean blocking) throws Exception {
+ SocketChannel peerChannel = null;
+
+ synchronized (channelCollection) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---doAccept---");
+ }
+
+ if (keyChannel.isOpen()) {
+ peerChannel = ((ServerSocketChannel) keyChannel).accept();
+ } else {
+ return false;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Added channel " + peerChannel);
+ }
+ channelCollection.add(peerChannel);
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Now the size is <" + channelCollection.size() + ">");
+ }
+
+ if (blocking == false) {
+ peerChannel.configureBlocking(blocking);
+ peerChannel.register(selector, SelectionKey.OP_READ
+ | SelectionKey.OP_WRITE);
+ } else {
+ peerChannel.configureBlocking(blocking);
+ }
+
+ peerChannel.socket().setTcpNoDelay(true);
+
+ peerChannel.socket().setSendBufferSize(524288);
+ peerChannel.socket().setReceiveBufferSize(524288);
+
+ if (channelCollection.size() == nprocs - 1) {
+ channelCollection.notify();
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" notifying and returning true");
+ }
+ return true;
+ }
+
+ } // end sync.
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--doAccept ends--");
+ }
+ peerChannel = null;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" returning false");
+ }
+ return false;
+ }
+
+ /*
+ * This method receives the message into the user specified memory. This is
+ * the case, when the receiver has received the message from the sender, and a
+ * matching recv has also been found.
+ */
+ private void eagerRecv2UserMem(NIORecvRequest request,
+ SocketChannel socketChannel) throws Exception {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---eagerRecv2UserMem---");
+ logger.debug("request.sBufSize (is it zero?) " + request.sBufSize);
+ }
+
+ if (request.sBufSize > 0) {
+ request.staticBuffer.limit(request.sBufSize);
+ request.staticBuffer.position(0);
+
+ while (request.staticBuffer.hasRemaining()) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("b(1) " + request.staticBuffer);
+ }
+
+ if (socketChannel.read(request.staticBuffer) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("b(2) " + request.staticBuffer);
+ }
+
+ }
+
+ request.buffer.setSize(request.sBufSize);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.dBufSize " + request.dBufSize);
+ }
+
+ if (request.dBufSize > 0) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("reading the dynamic buffer bytes");
+ }
+
+ RawBuffer rawBuffer = BufferFactory.create(request.dBufSize);
+ ByteBuffer tmpBuffer = ((NIOBuffer) rawBuffer).getBuffer();
+ tmpBuffer.position(0);
+ tmpBuffer.limit(request.dBufSize);
+
+ byte[] tmpArray = new byte[request.dBufSize];
+
+ while (tmpBuffer.hasRemaining()) {
+
+ if (socketChannel.read(tmpBuffer) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ }
+
+ tmpBuffer.flip();
+ tmpBuffer.get(tmpArray, 0, tmpArray.length);
+ request.dynamicBuffer = tmpArray;
+ request.buffer.setDynamicBuffer(tmpArray);
+ BufferFactory.destroy(rawBuffer);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--eagerRecv2UserMem ends--");
+ }
+
+ }
+
+ /*
+ * This method receives the message into the xdev memory. This is the case,
+ * when the receiver has received the message from the sender, but no matching
+ * recv is posted. We have to save the message at some place.
+ */
+ private void eagerRecv2mpjMem(NIORecvRequest request,
+ SocketChannel socketChannel) throws Exception {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---eagerRecv2mpjMem_" + request.tag);
+ }
+
+ if (request.sBufSize > 0) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("static section ...");
+ logger.debug(" creating eager buffer ");
+ }
+
+ request.eagerBuffer = BufferFactory.create(request.sBufSize);
+
+ ByteBuffer eagerBuffer = ((NIOBuffer) request.eagerBuffer).getBuffer();
+ eagerBuffer.limit(request.sBufSize);
+ eagerBuffer.position(0);
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" creating eager buffer" + eagerBuffer);
+ }
+
+ while (eagerBuffer.hasRemaining()) {
+
+ if (socketChannel.read(eagerBuffer) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ }
+
+ // eagerBuffer.flip(); should have no effect ..
+ }
+
+ if (request.dBufSize > 0) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("reading dynamic buffer bytes");
+ }
+
+ RawBuffer rawBuffer = BufferFactory.create(request.dBufSize);
+ ByteBuffer tmpBuffer = ((NIOBuffer) rawBuffer).getBuffer();
+ tmpBuffer.position(0);
+ tmpBuffer.limit(request.dBufSize);
+
+ byte[] tmpArray = new byte[request.dBufSize];
+
+ while (tmpBuffer.hasRemaining()) {
+ if (socketChannel.read(tmpBuffer) == -1) {
+ throw new ClosedChannelException();
+ }
+ }
+
+ tmpBuffer.flip();
+ tmpBuffer.get(tmpArray, 0, tmpArray.length);
+ tmpBuffer.clear();
+ BufferFactory.destroy(rawBuffer);
+ request.dynamicBuffer = tmpArray;
+ }
+
+ }
+
+ /*
+ * Sender will complete communication.
+ */
+ void doRendezSendCompletion(SocketChannel socketChannel, SelectionKey key)
+ throws Exception {
+
+ synchronized (rendez_send_buffer) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---doRendezSendCompletion---");
+ }
+
+ rendez_send_buffer.position(0);
+ rendez_send_buffer.limit(ACK_LENGTH);
+
+ while (rendez_send_buffer.hasRemaining()) {
+ if (socketChannel.read(rendez_send_buffer) == -1) {
+ throw new ClosedChannelException();
+ }
+ }
+
+ rendez_send_buffer.flip();
+ msgReceivedFrom = socketChannel;
+
+ }
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("rendezCtrlPart followed by a send ....(release rLock)");
+ }
+ } // end doRendezSendCompletion.
+
+ /*
+ * This method is called from the selector thread and it receives the message
+ * for eager-send, control message for rendezous
+ */
+ private NIORecvRequest recvCtrlMsgFromSender(SocketChannel socketChannel,
+ SelectionKey skey) throws Exception {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("-- recvCtrlMsgFromSender ---");
+ }
+
+ rcb.clear();
+ rcb.limit(CTRL_MSG_LENGTH);
+
+ while (rcb.hasRemaining()) {
+ if (socketChannel.read(rcb) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ } // end while.
+
+ rcb.flip();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Receiver getting the control message");
+ logger.debug("Could be rend, eager, posted b4 or not");
+ }
+ long msb = rcb.getLong();
+ long lsb = rcb.getLong();
+ int tag = rcb.getInt();
+ int staBufferSize = rcb.getInt();
+ int dynaBufferSize = rcb.getInt();
+ int commMode = rcb.getInt();
+ int context = rcb.getInt();
+ int numEls = rcb.getInt();
+ int sendCounter = rcb.getInt();
+ byte t = rcb.get();
+ mpjbuf.Type type = mpjbuf.Type.getType(t);
+ UUID srcUUID = new UUID(msb, lsb);
+ UUID srcHybUUID = null, dstHybUUID = null;
+
+ // for Hybrid device
+ if (isHybrid) {
+ msb = rcb.getLong();
+ lsb = rcb.getLong();
+ srcHybUUID = new UUID(msb, lsb);
+ msb = rcb.getLong();
+ lsb = rcb.getLong();
+ dstHybUUID = new UUID(msb, lsb);
+ }
+
+ rcb.clear();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("msb :" + msb);
+ logger.debug("lsb :" + lsb);
+ logger.debug("sendCounter :" + sendCounter);
+ logger.debug("tag :" + tag);
+ logger.debug("staBufferSize :" + staBufferSize);
+ logger.debug("dynaBufferSize :" + dynaBufferSize);
+ logger.debug("context :" + context);
+ logger.debug("commMode :" + commMode);
+ logger.debug("type :" + type);
+ logger.debug("sendCounter :" + sendCounter);
+ logger.debug("numEls :" + numEls);
+ }
+
+ sem.acquire();
+
+ NIORecvRequest request = null;
+
+ if (isHybrid) {
+ request = recvQueue.rem(context, dstHybUUID, srcHybUUID, tag);
+
+ } else {
+ request = recvQueue.rem(context, id().uuid(), srcUUID, tag);
+ }
+
+ if (request != null) {
+
+ /*
+ * Rendezous, recv posted, message arrived, would write control message
+ * back
+ */
+ if (isHybrid) {
+ // TODO check if this is already populated
+ request.srcHybUUID = srcHybUUID;
+ request.dstHybUUID = dstHybUUID;
+ }
+
+ request.srcUUID = srcUUID;
+ request.dstUUID = id().uuid();
+ request.tag = tag;
+ request.numEls = numEls;
+ request.type = type;
+
+ // std. mode AND using rendezvous protocol OR sync. mode.
+ if ((((staBufferSize + dynaBufferSize) > psl) && commMode == STD_COMM_MODE)
+ || (commMode == SYNC_COMM_MODE)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("receiver receving the ctrl, sending back to sender");
+ }
+ request.sBufSize = staBufferSize;
+ request.dBufSize = dynaBufferSize;
+ request.sendCounter = sendCounter;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting readPending to true " + request);
+ }
+ recvMap.put(new Integer(request.recvCounter), request);
+ sem.signal();
+ request.code = SEND_ACK_TO_SENDER;
+ return request;
+ } else {
+ request.sBufSize = staBufferSize;
+ request.dBufSize = dynaBufferSize;
+ sem.signal();
+ request.code = RECV_IN_USER_MEMORY;
+ return request;
+ }
+
+ } // end for
+
+ request = new NIORecvRequest(id.uuid(), tag, false, context, staBufferSize,
+ dynaBufferSize, commMode, socketChannel, numEls, type, sendCounter,
+ ++recvCounter, srcUUID);
+
+ // for Hybrid Device
+ if (isHybrid) {
+ request.srcHybUUID = srcHybUUID;
+ request.dstHybUUID = dstHybUUID;
+ }
+
+ if ((((staBufferSize + dynaBufferSize) <= psl) && commMode == STD_COMM_MODE)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting the request.code to RECV_IN_DEV_MEMORY");
+ }
+
+ request.code = RECV_IN_DEV_MEMORY;
+
+ }
+
+ else if ((((staBufferSize + dynaBufferSize) > psl) && commMode == 3)
+ || (commMode == 2)) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting the request.code to NOTHING ");
+ }
+
+ /* For Rendezous, do nothing? */
+ arrQue.add(request);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Adding the request");
+ }
+
+ sem.signal();
+ return request;
+ }
+
+ return request;
+ } // end recvMsgFromSender
+
+ synchronized void rendezSendCtrlMsg(SocketChannel socketChannel,
+ NIOSendRequest request) throws Exception {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("rendezBuffer " + rendezBuffer + "me" + rank);
+ }
+ try {
+ rendezBuffer.putInt(RENDEZ_HEADER);
+ rendezBuffer.putInt(request.recvCounter);
+ }
+ catch (Exception e) {
+ throw e;
+ }
+ rendezBuffer.flip();
+
+ while (rendezBuffer.hasRemaining()) {
+ if (socketChannel.write(rendezBuffer) == -1) {
+ throw new ClosedChannelException();
+ }
+ }
+
+ rendezBuffer.clear();
+ }
+
+ // -83 => more to write ...
+ // 0 => nothing to write
+ // 2 => no matching request.
+ // -1 => error.
+
+ int rendezSendData(SocketChannel socketChannel, NIOSendRequest request)
+ throws Exception {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---rendezSendData ---");
+ logger.debug("socketChannel " + socketChannel);
+ logger.debug("request.tag " + request.tag);
+ }
+
+ /* writing the static buffer contents */
+ int wrote = request.bufoffset;
+ int tempWrote = 0;
+ int ww = request.bufoffset;
+ int w = 0;
+
+ if (request.sBufSize > 0 && request.sSection) {
+
+ request.staticBuffer.limit(request.sBufSize + request.bufoffset);
+ request.staticBuffer.position(request.bufoffset);
+
+ while (request.staticBuffer.hasRemaining()) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buf(first)" + request.staticBuffer + "w" + wrote);
+ }
+
+ request.staticBuffer.position(wrote);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("buf(second)" + request.staticBuffer + "w" + wrote);
+ }
+
+ if ((tempWrote = socketChannel.write(request.staticBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ wrote += tempWrote;
+ w = tempWrote;
+ ww += w;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+
+ if (request.staticBuffer.hasRemaining()) {
+ System.out.println("Bug (7) <" + request.tag + ">");
+ logger.debug("Bug (7) <" + request.tag + ">");
+ System.out.println("request.staticBuffer " + request.staticBuffer);
+ // System.out.println("buf " + buf);
+ System.out.println("wrote " + wrote);
+ System.exit(1);
+ }
+
+ if (request.staticBuffer.position() != (request.sBufSize + request.bufoffset)) {
+ System.out.println("Bug (8) <" + request.tag + ">" + rank);
+ logger.debug("Bug (8) <" + request.tag + ">");
+ System.out.println("request.staticBuffer " + request.staticBuffer);
+ // System.out.println("buf " + buf);
+ System.out.println("wrote " + wrote);
+ System.exit(1);
+ }
+
+ if (request.staticBuffer.position() != request.staticBuffer.limit()) {
+
+ System.out.println("Bug (9) <" + request.tag + ">");
+ logger.debug("Bug (9) <" + request.tag + ">");
+ System.out.println("request.staticBuffer " + request.staticBuffer);
+ // System.out.println("buf " + buf);
+ System.out.println("wrote " + wrote);
+ System.exit(1);
+ }
+
+ /*
+ * assuming when this happens, then no byte is actually written into
+ * the channel
+ */
+
+ if (wrote != request.staticBuffer.position()) {
+ System.out.println("send:staticSend:insane");
+ logger.debug("insane (rendezSend--staticBuffer) ");
+ logger.debug("request.staticBuffer [2-3] " + request.staticBuffer);
+
+ if (wrote > request.staticBuffer.limit()) {
+ System.out.println("cant even recover from this");
+ }
+
+ System.exit(1);
+ }
+
+ logger.debug("buf(third)" + request.staticBuffer);
+ // logger.debug("buf(third)" + buf );
+ logger.debug("tempWrote " + tempWrote);
+ logger.debug("wrote " + wrote);
+ }
+
+ } // end while.
+
+ request.sSection = false;
+ request.bytesWritten = 0;
+ // buf = null;
+ } // end if
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Sending dynamic portion <" + request.dBufSize);
+ logger.debug("request.dBufSize" + request.dBufSize);
+ logger.debug("request.dSection" + request.dSection);
+ }
+
+ wrote = 0;
+ tempWrote = 0;
+ ww = 0;
+ w = 0;
+
+ if (request.dBufSize > 0 && request.dSection) {
+
+ if (request.dBuffer == null) {
+
+ // get bytebuffer from bufferFactory ...
+ request.eagerBuffer = BufferFactory.create(request.dBufSize);
+ request.dBuffer = ((NIOBuffer) request.eagerBuffer).getBuffer();
+ request.dBuffer.position(0);
+ request.dBuffer.limit(request.dBufSize);
+ request.dBuffer.put(request.dynamicBuffer, 0, request.dBufSize);
+ request.dBuffer.flip();
+ request.bytesWritten = 0;
+
+ }
+
+ request.dBuffer.position(request.bytesWritten);
+ wrote = request.bytesWritten;
+
+ // while(request.dBuffer.hasRemaining()) {
+ while (ww != request.dBufSize) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("ww " + ww);
+ logger.debug("request.dBuffer(1) " + request.dBuffer);
+ }
+ request.dBuffer.position(wrote);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.dBuffer (2)" + request.dBuffer);
+ }
+
+ if ((tempWrote = socketChannel.write(request.dBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.dBuffer (3)" + request.dBuffer);
+ }
+ wrote += tempWrote;
+ w = tempWrote;
+ ww += w;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ if (request.dBuffer.hasRemaining()) {
+ System.out.println("Bug (10) <" + request.tag + ">");
+ logger.debug("Bug (10) <" + request.tag + ">");
+ System.out.println("request.dBuffer " + request.dBuffer);
+ System.exit(1);
+ }
+
+ if (request.dBuffer.position() != (request.dBufSize)) {
+ System.out.println("Bug (11) <" + request.tag + ">");
+ logger.debug("Bug (11) <" + request.tag + ">");
+ System.out.println("request.dBuffer " + request.dBuffer);
+ System.exit(1);
+ }
+
+ if (request.dBuffer.position() != request.dBuffer.limit()) {
+ System.out.println("Bug (12) <" + request.tag + ">");
+ logger.debug("Bug (12) <" + request.tag + ">");
+ System.out.println("request.dBuffer " + request.dBuffer);
+ System.exit(1);
+ }
+
+ if (wrote != request.dBuffer.position()) {
+ System.out.println("dynamic: insane");
+ System.exit(1);
+ }
+
+ logger.debug("request.dBuffer(4) " + request.dBuffer);
+ }
+
+ } // end while.
+
+ request.dSection = false;
+ BufferFactory.destroy(request.eagerBuffer);
+
+ return 0;
+ } // if ends
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--rendez Send Data Ends--");
+ }
+ return 2;
+ }
+
+ private int rendezRecvData(SocketChannel socketChannel, int datum,
+ NIORecvRequest request) throws Exception {
+
+ int read = 0, tempRead = 0;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--rendezRecvData--");
+ logger.debug("request.tag " + request.tag);
+ logger.debug("request.sBufSize " + request.sBufSize);
+ logger.debug("request.dBufSize " + request.dBufSize);
+ logger.debug("request.bytesRead " + request.bytesRead);
+ logger.debug("datum <" + datum + ">");
+ }
+
+ if (request.sBufSize > 0 && request.sSection) {
+
+ request.staticBuffer.limit(request.sBufSize);
+ request.staticBuffer.position(request.bytesRead);
+
+ if (datum != RENDEZ_HEADER) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Putting it on buffer because its not header data ");
+ }
+ request.staticBuffer.putInt(datum);
+ request.bytesRead = request.bytesRead + 4;
+ request.staticBuffer.position(request.bytesRead);
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("request.staticBuffer " + request.staticBuffer);
+ }
+ datum = RENDEZ_HEADER;
+ } else if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("static-section:rendezRecvData called for the first time");
+ }
+
+ read = request.bytesRead;
+
+ while (request.staticBuffer.hasRemaining()) {
+
+ // logger.debug("request.staticBuffer(1st) "+request.staticBuffer);
+ request.staticBuffer.position(read);
+ // logger.debug("request.staticBuffer(2nd) "+request.staticBuffer);
+
+ if ((tempRead = socketChannel.read(request.staticBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ read += tempRead;
+ // logger.debug("request.staticBuffer (3) "+request.staticBuffer);
+ // logger.debug("read "+read);
+
+ if (request.staticBuffer.remaining() > 3) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("got a short tempRead <" + tempRead);
+ }
+ request.bytesRead = read;
+ return MORE_TO_READ;
+ }
+
+ } // end while.
+
+ request.sSection = false;
+ request.bytesRead = 0;
+
+ } // end static buffer reading.
+
+ read = 0;
+ tempRead = 0;
+
+ if (request.dBufSize > 0 && request.dSection) {
+
+ if (request.dBuffer == null) {
+
+ // get bytebuffer from bufferFactory ...
+ request.dBuffer = ByteBuffer.allocate(request.dBufSize);
+ request.bytes = new byte[request.dBufSize];
+ request.bytesRead = 0;
+
+ }
+
+ if (datum != RENDEZ_HEADER) {
+ request.dBuffer.putInt(datum);
+ request.bytesRead = request.bytesRead + 4;
+ request.dBuffer.position(request.bytesRead);
+ datum = RENDEZ_HEADER;
+ } else {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("dynamic section: rendezRecvData called");
+ logger.debug("for the first time");
+ }
+ }
+
+ read = request.bytesRead;
+ request.dBuffer.limit(request.dBufSize);
+ request.dBuffer.position(request.bytesRead);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("initial read" + read);
+ logger.debug("reading the dynamic portion");
+ }
+
+ while (request.dBuffer.hasRemaining()) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("dBuffer (1)" + request.dBuffer);
+ }
+ request.dBuffer.position(read);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("dBuffer (2)" + request.dBuffer);
+ }
+ if ((tempRead = socketChannel.read(request.dBuffer)) == -1) {
+ throw new ClosedChannelException();
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("dBuffer (3)" + request.dBuffer);
+ }
+ read = read + tempRead;
+
+ if (request.dBuffer.remaining() > 3) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("got a short read <" + read);
+ logger.debug("dBuffer (3.5)" + request.dBuffer);
+ }
+ request.bytesRead = read;
+ return MORE_TO_READ;
+ // continue;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("dBuffer (4)" + request.dBuffer);
+ }
+ } // end reading dynamic section
+
+ request.dSection = false;
+ request.dBuffer.flip();
+ request.dBuffer.get(request.bytes, 0, request.bytes.length);
+ request.dynamicBuffer = request.bytes;
+ request.buffer.setDynamicBuffer(request.bytes);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("setting the size to " + request.sBufSize);
+ logger.debug("request.buffer " + request.buffer);
+ }
+ request.buffer.setSize(request.sBufSize);
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("--rendez Recv Ends--");
+ }
+ return -1;
+
+ } // end rendezRecvData ...
+
+ /**
+ * why is this method static synchronized??? i think there is no need for it
+ * to be ... This method is used by the receiver to send the acknowledgement
+ * of the control message. Used in Rendezous Protocol, at the receiver side
+ * only (1) sender sends the control message to the receiver (2) receiver send
+ * the control message acknowledgement back to the sender (this method) (3)
+ * once the sender receives the acknowledgement, it sends the actual data (4)
+ * it uses and clears _wcb buffer ...we dont want buffer clashes as they may
+ * corrupt the message ... (5) it doesn't have to be static sync. as write
+ * lock for this channel is first acquired, but just being on the paranoid
+ * side. :-)
+ */
+ static synchronized void rendezCtrlMsgR2S(SocketChannel socketChannel,
+ NIORecvRequest request) throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("---rendezCtrlMsgR2S---");
+ logger.debug("request.tag :" + request.tag);
+ logger.debug("request.sendCounter :" + request.sendCounter);
+ }
+ _wcb.putInt(ACK_HEADER);
+ _wcb.put(((byte) 0));
+ _wcb.putInt(request.tag);
+ _wcb.putInt(request.context);
+ _wcb.putInt(request.sendCounter);
+ _wcb.putInt(request.recvCounter);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("tag " + request.tag);
+ }
+ _wcb.flip();
+
+ int ww = 0;
+ int w = 0;
+
+ while (_wcb.hasRemaining()) {
+ // while (ww != 21) {
+ try {
+ if ((w = socketChannel.write(_wcb)) == -1) {
+ throw new XDevException(new ClosedChannelException());
+ }
+ }
+ catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ ww += w;
+
+ if (_wcb.hasRemaining()) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.fatal("Bug (13) <" + request.tag + ">");
+ logger.fatal("_wcb" + _wcb);
+ System.out.println(" eixting ");
+ System.exit(1);
+ }
+ }
+
+ if (_wcb.position() != _wcb.limit()) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.fatal("Bug (14) <" + request.tag + ">");
+ logger.fatal("_wcb" + _wcb);
+ }
+ System.out.println(" eixting ");
+ System.exit(1);
+ }
+
+ if (_wcb.position() != 21) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.fatal("Bug (15) <" + request.tag + ">");
+ logger.fatal("_wcb" + _wcb);
+ }
+ System.out.println(" eixting ");
+ System.exit(1);
+ }
+ } // end while.
+
+ _wcb.clear();
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("rendezCtrlMsgR2S --FINISHED");
+ }
+
+ } // end rendezCtrlMsgSend
+
+ /*
+ * Static anonymous inner class that is basically the selector thread
+ */
+ Runnable selectorThread = new Runnable() {
+
+ /* This is selector thread */
+ public void run() {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.info("selector Thread started ");
+ }
+ Set readyKeys = null;
+ long t_start = 0l, t_end = 0l;
+ long diff_start = 0l, diff_end = 0l;
+ long stop_ready_sendrecv = 0l, start_ready_sendrecv = 0l;
+ Iterator<SelectionKey> readyItor = null;
+ SelectionKey key = null;
+ SelectableChannel keyChannel = null;
+ SocketChannel socketChannel = null;
+ ByteBuffer lilBuffer = ByteBuffer.allocate(4);
+ int tempRead = 0, read = 0, shutdownCounter = 0;
+ NIOSendRequest sendRequest = null;
+ NIORecvRequest recvRequest = null;
+ SocketChannel pendingReadChannel = null;
+ int header = 0;
+ // long strt = 0L, stop = 0L, intv = 0L ;
+
+ try {
+ while (selectorFlag && selector.select() > -1) {
+
+ // strt = System.nanoTime() ;
+
+ readyKeys = selector.selectedKeys();
+ readyItor = readyKeys.iterator();
+
+ while (readyItor.hasNext()) {
+
+ key = readyItor.next();
+ readyItor.remove();
+ keyChannel = (SelectableChannel) key.channel();
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---selector EVENT---");
+ }
+
+ if (key.isValid() && key.isAcceptable()) {
+
+ ServerSocketChannel sChannel = (ServerSocketChannel) keyChannel;
+ if (sChannel.socket().getLocalPort() == my_server_port) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("selector calling doAccept (data-channel) ");
+ }
+ doAccept(keyChannel, writableChannels, true);
+ } else {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("selector calling doAccept (ctrl-channel) ");
+ }
+ doAccept(keyChannel, readableChannels, false);
+ }
+
+ } else if (key.isValid() && key.isReadable()) {
+
+ socketChannel = (SocketChannel) keyChannel;
+
+ if (key.attachment() == null) {
+
+ /* Read the first 4 bytes */
+ lilBuffer.clear();
+ header = 0;
+
+ while (lilBuffer.hasRemaining()) {
+ if ((header = socketChannel.read(lilBuffer)) == -1) {
+ // throw new ClosedChannelException();
+ break;
+ }
+ }
+
+ if (header != -1) {
+ lilBuffer.flip();
+ header = lilBuffer.getInt();
+ lilBuffer.clear();
+ } else {
+ header = END_OF_STREAM;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("---READ_EVENT---" + header);
+ }
+
+ /**
+ * It could be (1) control message at receiver side OR (2)
+ * control message response at the sender
+ *
+ * if(1) { This means, it's receiver getting the control message
+ * from the sender. The receiver at this time doesn't know if it
+ * is Eager, or Rendezous, so first the receiver checks if it is
+ * Eager-Send or Rendezous, If it's Eager-Send, read the control
+ * message and the actual data, and if it's Rendezous, read the
+ * control-message ONLY, and write the response back to the
+ * sender. } else if (2) { If its sender getting the
+ * acknowledgement back, then write the actual data }
+ */
+ switch (header) {
+
+ /* Receiver got a control-message from sender */
+ case READY_TO_SEND:
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_end = System.nanoTime();
+ start_ready_sendrecv = System.nanoTime();
+ }
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" received READY_TO_SEND or "
+ + " READY_TO_RECV");
+ }
+
+ recvRequest = recvCtrlMsgFromSender(socketChannel, key);
+
+ /* Receiver will send ACK to sender */
+ if (recvRequest.code == SEND_ACK_TO_SENDER) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("calling r2s " + socketChannel);
+ }
+
+ SocketChannel c = worldWritableTable
+ .get(recvRequest.srcUUID);
+ CustomSemaphore wLock = writeLockTable.get(c);
+ long acq = System.nanoTime();
+ wLock.acquire();
+ long rel = System.nanoTime();
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("lock=<" + (rel - acq) / (1000000000.0));
+ }
+ rendezCtrlMsgR2S(c, recvRequest);
+ wLock.signal();
+
+ /*
+ * Receiver will recv message in user memory This
+ * essentially means that recv is posted
+ */
+ } else if (recvRequest.code == RECV_IN_USER_MEMORY) {
+
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("isend_packing_time_route1 <"+intv/1000);
+ // strt = System.nanoTime() - strt ;
+ // logger.debug("irecv_determing_its_userM <"+intv/1000);
+ eagerRecv2UserMem(recvRequest, socketChannel);
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_receiving_in_userM <"+intv/1000);
+ // completedList.add( recvRequest );
+ recvRequest.notifyMe();
+
+ /*
+ * Receiver will recv message in device memory. This means
+ * that recv is not posted, and eager protocol is being
+ * used.
+ */
+
+ } else if (recvRequest.code == RECV_IN_DEV_MEMORY) {
+ /* has rLock, and getting readLock */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Calling eagerRecv2mpjMem");
+ }
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_determing_its_devM <"+intv/1000);
+ eagerRecv2mpjMem(recvRequest, socketChannel);
+
+ arrQue.add(recvRequest);
+ // stop = System.nanoTime() ;
+ // intv = stop - strt ;
+ // strt = stop;
+ // logger.debug("irecv_receiving_in_devM <"+intv/1000);
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Adding the request");
+ }
+
+ sem.signal();
+
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_start = System.nanoTime();
+ stop_ready_sendrecv = System.nanoTime();
+ logger
+ .debug("time_ready_sendrecv="
+ + ((stop_ready_sendrecv - start_ready_sendrecv) / 1000000000.0));
+ }
+
+ break;
+
+ /* Sender is receving ACK back from Receiver */
+ case ACK_HEADER:
+
+ /* Recv ACK from Receiver */
+ buffer_sem.acquire();
+ doRendezSendCompletion(socketChannel, key);
+ (new Thread(rendezSenderThread)).start();
+ break;
+
+ /*
+ * Receiver will be receiving data (rendezvous protocol)
+ */
+ case RENDEZ_HEADER:
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" RENDEZ_HEADER ");
+ }
+
+ rcb.limit(RENDEZ_CTRL_MSG_LENGTH);
+ rcb.position(0);
+
+ while (rcb.hasRemaining()) {
+ if (socketChannel.read(rcb) == -1) {
+ throw new ClosedChannelException();
+ }
+ }
+
+ rcb.flip();
+
+ int recvCounter = rcb.getInt();
+
+ /* Find the matching request */
+ sem.acquire();
+ recvRequest = recvMap.remove(new Integer(recvCounter));
+ sem.signal();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("recvCounter " + recvCounter);
+ logger.debug("recvRequest " + recvRequest);
+ }
+
+ if (recvRequest == null) {
+ continue;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_end = System.nanoTime();
+ }
+
+ header = RENDEZ_HEADER;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ t_start = System.nanoTime();
+ }
+
+ int code2 = rendezRecvData(socketChannel, header, recvRequest);
+
+ if (code2 != MORE_TO_READ) {
+
+ /*
+ * If all data is received, notify User Thread, and remove
+ * this request from recvQue
+ */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("notified that recvData is complete ");
+ }
+ // completedList.add(recvRequest);
+ recvRequest.notifyMe();
+ key.attach(null);
+ recvRequest = null;
+
+ } else {
+ key.attach(recvRequest);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("last statement in RENDEZ_HEADER");
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_start = System.nanoTime();
+ }
+ break;
+
+ case INIT_MSG_HEADER_DATA_CHANNEL:
+ doBarrierRead(((SocketChannel) keyChannel),
+ worldReadableTable, false);
+ break;
+
+ case INIT_MSG_HEADER_CTRL_CHANNEL:
+ doBarrierRead(((SocketChannel) keyChannel),
+ worldReadableTable, false);
+ break;
+
+ case END_OF_STREAM:
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("END OF STREAM ");
+ logger.debug("leaf is -1" + procTree.numChildren);
+ }
+
+ realFinish();
+
+ break;
+
+ default:
+
+ System.out.println(" impossible ");
+ break;
+
+ } // end switch-case
+
+ } // end if key.attachment == null
+
+ else {
+ recvRequest = (NIORecvRequest) key.attachment();
+
+ /* Receiver whatever data you can */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("recvRequest " + recvRequest);
+ }
+
+ if (recvRequest == null) {
+ System.out.println("recvRequest cannot be null");
+ continue;
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_end = System.nanoTime();
+ logger.debug("time_diff=<"
+ + ((diff_end - diff_start) / 1000000000.0) + ">");
+ }
+
+ header = RENDEZ_HEADER;
+ int code4 = rendezRecvData(socketChannel, header, recvRequest);
+
+ if (code4 != MORE_TO_READ) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ t_end = System.nanoTime();
+ }
+
+ /*
+ * If all data is received, notify User Thread, and remove
+ * this request from recvQueue
+ */
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("notified that recvData is complete ");
+ logger.debug("time=" + ((t_end - t_start) / 1000000000.0));
+ }
+ // completedList.add(recvRequest);
+ recvRequest.notifyMe();
+ key.attach(null);
+ }
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ diff_start = System.nanoTime();
+ }
+ }
+ } else if (key.isValid() && key.isWritable()) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("WRITE_EVENT (should not see it)");
+ logger.debug("In, WRITABLE, changing"
+ + " interestOps to READ_ONLY");
+ }
+ key.interestOps(SelectionKey.OP_READ);
+
+ } // end else writable.
+
+ } // end while iterator
+ } // end while
+ }
+ catch (Exception ioe1) {
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" error in selector thread " + ioe1.getMessage());
+ }
+ // ioe1.printStackTrace() ;
+ } // end catch(Exception e) ...
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" last statement in selector thread");
+ }
+
+ } // end run()
+
+ }; // end selectorThread which is an inner class
+
+ Runnable rendezSenderThread = new Runnable() {
+
+ public void run() {
+
+ SocketChannel channel;
+ // synchronized (rendez_send_buffer) {
+ // }
+
+ try {
+ byte goAhead = 0;
+ int tag = 0;
+ int context = 0;
+ int sendCounter = 0;
+ int recvCounter = 0;
+
+ /* Read what the receiver just sent */
+ synchronized (rendez_send_buffer) {
+ channel = msgReceivedFrom;
+ goAhead = rendez_send_buffer.get();
+ tag = rendez_send_buffer.getInt();
+ context = rendez_send_buffer.getInt();
+ sendCounter = rendez_send_buffer.getInt();
+ recvCounter = rendez_send_buffer.getInt();
+ rendez_send_buffer.clear();
+ }
+
+ buffer_sem.signal();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" Started rendezSenderThread " + tag);
+ }
+
+ /* Manipulate send comms-set */
+ sLock.acquire();
+
+ NIOSendRequest sendRequest = sendMap.remove(new Integer(sendCounter));
+ sendRequest.recvCounter = recvCounter;
+
+ s_wcb.clear();
+ sLock.signal();
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("sendRequest " + sendRequest);
+ logger.debug("sendCounter " + sendCounter);
+ logger.debug("recvCounter " + recvCounter);
+ logger.debug("tag " + tag);
+ }
+
+ SocketChannel ch = worldWritableTable.get(sendRequest.dstUUID);
+ CustomSemaphore wLock = writeLockTable.get(ch);
+ wLock.acquire();
+
+ if (sendRequest == null) {
+ System.out.println("Calling rendezSendData (WRITE_EVENT)");
+ System.out.println("Problem ");
+ System.exit(0);
+ }
+
+ rendezSendCtrlMsg(ch, sendRequest);
+ int code = rendezSendData(ch, sendRequest);
+
+ if (code != MORE_TO_WRITE) {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("writing complete for <" + sendRequest.tag + ">");
+ logger.debug("notifying " + sendRequest);
+ }
+ // completedList.add(sendRequest);
+ sendRequest.notifyMe();
+
+ } else {
+
+ System.out.println(" The channel is in blocking mode ");
+ System.out.println(" This shouldn't happen ");
+ System.exit(0);
+
+ }
+
+ wLock.signal();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ class CustomSemaphore {
+
+ private int s;
+
+ public CustomSemaphore(int s) {
+ this.s = s;
+ }
+
+ public synchronized void acquire() throws InterruptedException {
+ while (s == 0)
+ wait(0);
+ s--;
+ }
+
+ public synchronized void signal() {
+ s++;
+ notify();
+ }
+ }
+
+}
diff --git a/src/xdev/niodev/NIORecvRequest.java b/src/xdev/niodev/NIORecvRequest.java
new file mode 100644
index 0000000..fe09ef2
--- /dev/null
+++ b/src/xdev/niodev/NIORecvRequest.java
@@ -0,0 +1,168 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : NIORecvRequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.10 $
+ * Updated : $Date: 2005/12/21 13:18:18 $
+ *
+ */
+
+package xdev.niodev;
+
+import java.util.UUID;
+import java.nio.channels.*;
+import java.nio.*;
+import mpjdev.*;
+import mpjbuf.NIOBuffer ;
+import xdev.*;
+
+public class NIORecvRequest
+ extends NIORequest {
+ long sequenceNum ;
+
+ // 4 hash table keys for queues in which send request may be placed,
+ // or in which matching receive requests may be found.
+ NIODevice.Key [] arrKeys ;
+
+ // Link fields for 4 queues in which request may be placed.
+ // Next entry in queue.
+ NIORecvRequest arrNext [] ;
+
+ // Previous entry in queue, (or final entry in queue, if this request
+ // is at front of queue).
+ NIORecvRequest arrPrev [] ;
+
+ // Hash table key for queue in which receive request may be placed,
+ // or in which matching send request may be found.
+ NIODevice.Key recvKey ;
+
+ // Link fields for queue in which request may be placed.
+ // Next entry in queue.
+ NIORecvRequest recvNext ;
+
+ // Previous entry in queue, (or final entry in queue, if this request
+ // is at front of queue).
+ NIORecvRequest recvPrev ;
+
+ int code = -1;
+ boolean readPending = false;
+ int bytesRead = 0;
+ NIOSendRequest sendRequest ;
+
+ /* if the events are to be posted by user thread */
+ NIORecvRequest(ProcessID srcID, String src, String dst, ProcessID dstID,
+ int tag, boolean completed,
+ mpjbuf.Buffer buf, int context,
+ mpjdev.Status status, int recvCounter ,
+ long nextSequenceNum ) {
+
+ this.srcUUID = srcID.uuid() ;
+ this.dstUUID = dstID.uuid() ;
+
+ this.tag = tag;
+ this.completed = completed;
+ this.staticBuffer = ((NIOBuffer)buf.getStaticBuffer()).getBuffer() ;
+ this.buffer = buf;
+ this.dynamicBuffer = buf.getDynamicBuffer();
+ this.context = context;
+ //this.rank_source = srcID.rank() ;
+ this.status = status;
+ this.recvCounter = recvCounter ;
+
+ synchronized(NIORecvRequest.class) {
+ sequenceNum = nextSequenceNum ;
+ }
+ }
+
+ /* if the events are to be posted by selector thread */
+ NIORecvRequest(UUID dstUUID, int tag, boolean completed,
+ int context, int sBufSize, int dBufSize, int commMode,
+ SocketChannel channel, int numEls, mpjbuf.Type type,
+ int sendCounter, int recvCounter , UUID srcUUID ) {
+
+ this.arrNext = new NIORecvRequest [4] ;
+ this.arrPrev = new NIORecvRequest [4] ;
+
+ this.dstUUID = dstUUID;
+ this.tag = tag;
+ this.completed = completed;
+ this.context = context;
+ this.sBufSize = sBufSize;
+ this.dBufSize = dBufSize;
+ this.commMode = commMode;
+ this.channel = channel;
+ this.numEls = numEls;
+ this.type = type;
+ this.sendCounter = sendCounter ;
+ this.recvCounter = recvCounter ;
+ this.srcUUID = srcUUID ;
+ }
+
+ SocketChannel channel = null;
+ int commMode = 0;
+
+ int getCommMode() {
+ return commMode;
+ }
+
+ void setCommMode(int commMode) {
+ this.commMode = commMode;
+ }
+
+ public Status iwait() {
+ if(alreadyCompleted) {
+ if (NIODevice.isHybrid) {
+ status.srcID = this.srcHybUUID;
+ }
+ return status ;
+ }
+
+ this.waitMe();
+
+ /* this should be probably be done somewhere at the start of irecv
+ * method */
+ status.tag = this.tag;
+ //status.source = this.rank_source; [ we dont know rank at this level]
+ status.numEls = this.numEls;
+ status.type = this.type;
+
+ if (NIODevice.isHybrid) {
+ status.srcID = this.srcHybUUID;
+ }else{
+ status.srcID = this.srcUUID;
+ }
+
+ complete(status);
+ this.alreadyCompleted = true ;
+ return status;
+ }
+
+}
diff --git a/src/xdev/niodev/NIORequest.java b/src/xdev/niodev/NIORequest.java
new file mode 100644
index 0000000..38be0de
--- /dev/null
+++ b/src/xdev/niodev/NIORequest.java
@@ -0,0 +1,162 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : NIORequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.11 $
+ * Updated : $Date: 2006/04/25 19:26:15 $
+ *
+ */
+
+package xdev.niodev;
+
+import java.util.UUID;
+import java.nio.*;
+import mpjdev.*;
+import xdev.*;
+
+import mpjbuf.RawBuffer ;
+
+public abstract class NIORequest
+ extends Request {
+
+ NIORequest nextCompleted, prevCompleted ;
+ boolean inCompletedList ;
+
+ NIODevice device ;
+
+ /* buffers for storing static/dynamic sections of the buffer */
+ ByteBuffer dBuffer = null;
+ RawBuffer eagerBuffer = null;
+ byte[] dynamicBuffer = null;
+ ByteBuffer staticBuffer;
+ byte[] bytes = null;
+ boolean alreadyCompleted = false ;
+
+
+ boolean dSection = true, sSection = true;
+ int context=-1, tag, commMode, rank_source=0, sBufSize=0, dBufSize=0 ;
+ int sendCounter, recvCounter,numEls=-1 ;
+
+ UUID dstUUID, srcUUID, dstHybUUID=null, srcHybUUID=null;
+ mpjdev.Status status = null;
+ mpjbuf.Buffer buffer = null;
+ mpjbuf.Type type = null;
+
+ volatile boolean completed = false;
+
+ public boolean cancel() {
+ /* First start considering the sender side
+ * a) Send. --> For eager-send, its not possible.
+ * --> For rendezvous, yeah, can be cancelled.
+ * Isend --> Eager-send, not possible.
+ * --> For rendezvous, not possible.
+ * b) Same for Ready/Send
+ * c) Bsend --> Not possible at all.
+ * d) Ssend --> Possible.
+ * e) Recv --> Eager-send, not possible.
+ * --> Rendezvous-protocol.*/
+
+ return false;
+ }
+
+ synchronized void setCompleted(boolean completed) {
+ this.completed = completed;
+ }
+
+ synchronized boolean isCompleted() {
+ return completed;
+ }
+
+ public static Status iwaitany(NIORequest [] requests) {
+ System.out.println(" NIORequest.iwaitany( .. )");
+ return null;
+ }
+
+ /**
+ */
+ public abstract Status iwait();
+
+ /**
+ * Method used by iwait() to actually wait for the communication to finish.
+ */
+ synchronized void waitMe() {
+ while (!completed) {
+ try {
+ this.wait();
+ }
+ catch (Exception e) {
+ e.printStackTrace() ;
+ }
+ }
+
+ //device.completedList.remove(this);
+ // .. remove from completedList ..
+ }
+
+ /**
+ * Method used to notify that the communication operation has finished.
+ */
+ synchronized void notifyMe() {
+ this.completed = true;
+
+ try {
+ this.notify();
+ }
+ catch (Exception e) {
+ e.printStackTrace() ;
+ }
+ }
+
+ /** this method returns Status object if the communication is completed,
+ * and if its not completed, it returns zero.
+ */
+ public Status itest() {
+ if(alreadyCompleted) {
+ return null;
+ }
+ synchronized (this) {
+ if (this.isCompleted()) {
+ return new mpjdev.Status(rank_source, tag, -1); //what is index ?
+ }
+ else {
+ return null; //change this to something understand at higher levels ...
+ }
+ }
+ }
+
+ public void free() {
+ }
+
+ public boolean isnull() {
+ return false;
+ }
+}
diff --git a/src/xdev/niodev/NIOSendRequest.java b/src/xdev/niodev/NIOSendRequest.java
new file mode 100644
index 0000000..3329f9f
--- /dev/null
+++ b/src/xdev/niodev/NIOSendRequest.java
@@ -0,0 +1,117 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2008)
+ 3. Bryan Carpenter (2005 - 2008)
+ 4. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * File : NIOSendRequest.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.8 $
+ * Updated : $Date: 2005/12/21 13:18:18 $
+ *
+ */
+
+package xdev.niodev;
+
+import java.util.UUID;
+import java.nio.*;
+import mpjdev.Status;
+import mpjbuf.NIOBuffer ;
+import xdev.*;
+
+public class NIOSendRequest
+ extends NIORequest {
+
+ int bytesWritten = 0;
+ int bufoffset = 0;
+ int defaultNioOffset = 49;
+
+ NIOSendRequest(int tag, ProcessID srcID,ProcessID dstID, mpjbuf.Buffer buf,
+ int context, int commMode, int sendCounter )
+ throws XDevException {
+
+ try {
+ buf.commit() ;
+ this.type = buf.getSectionHeader ();
+ this.numEls = buf.getSectionSize ();
+ }
+ catch(Exception e) {
+ throw new XDevException(e);
+ }
+
+ this.tag = tag;
+ this.buffer = buf ;
+ this.srcUUID = srcID.uuid();
+ this.dstUUID = dstID.uuid() ;
+ this.sBufSize = buf.getSize() ;
+ this.staticBuffer = ((NIOBuffer) buf.getStaticBuffer()).getBuffer() ;
+ this.context = context;
+ this.commMode = commMode;
+ this.sendCounter = sendCounter ;
+ //this.rank_source = dstID.rank() ; //shouldn't this be srcID.rank()?
+ this.bufoffset = buf.offset();
+
+
+ /*if NIODevice is being used in Hybrid device then add Hybrid Source
+ * and Destination
+ */
+ if (NIODevice.isHybrid) {
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position( defaultNioOffset ) ;
+ long longUuids [] = new long [4];
+ for (int i=0;i<4;i++){
+ longUuids [i]= ((NIOBuffer) buf.getStaticBuffer()).getBuffer().getLong();
+ }
+ this.srcHybUUID = new UUID (longUuids[0], longUuids[1]) ;
+ this.dstHybUUID = new UUID (longUuids[2], longUuids[3]) ;
+
+ }
+ //System.out.println(" SendRequest=> NIO Src:"+srcUUID+" NIO Dst:"+dstUUID+" tag:"+tag+
+ //" Context:"+context+" HYB Src:"+srcHybUUID+" HYB Dst:"+dstHybUUID) ;
+
+ if(buf.getDynamicBuffer() != null && buf.getDynamicBuffer().length > 0) {
+ this.dynamicBuffer = buf.getDynamicBuffer() ;
+ this.dBufSize = buf.getDynamicBuffer().length ;
+ }
+
+ }
+
+ public Status iwait() {
+ if(alreadyCompleted) {
+ return new Status(rank_source, tag, -1) ;
+ }
+ synchronized (this) {
+ if (!this.isCompleted()) {
+ this.waitMe();
+ }
+ }
+ Status status = new Status(rank_source, tag, -1);
+ complete(status);
+ this.alreadyCompleted = true ;
+ return status;
+ }
+
+}
diff --git a/src/xdev/niodev/ProcTree.java b/src/xdev/niodev/ProcTree.java
new file mode 100644
index 0000000..f4345f3
--- /dev/null
+++ b/src/xdev/niodev/ProcTree.java
@@ -0,0 +1,115 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2008
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2005)
+ 3. Aamir Shafi (2005 - 2008)
+ 4. Bryan Carpenter (2005 - 2008)
+ 5. Mark Baker (2005 - 2008)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : ProcTree.java
+ * Author : Sang Lim, Bryan Carpenter
+ * Created : Thu Dec 20 16:39:43 BST 2001
+ * Revision : $Revision: 1.6 $
+ * Updated : $Date: 2005/08/06 15:21:36 $
+ */
+
+package xdev.niodev;
+
+public class ProcTree {
+
+ public static final int PROCTREE_A = 4;
+ public int numChildren;
+ public int[] child = new int[PROCTREE_A];
+ public int parent;
+ public int root;
+ public boolean isRoot;
+
+ public ProcTree() {
+ isRoot = false; //it was set to true ...
+ numChildren = -1;
+ for (int i = 0; i < child.length; i++) {
+ child[i] = -1;
+ }
+ root = -1;
+ parent = -1;
+ }
+
+ public static void main(String args[]) {
+ //ProcTree main method ...
+ ProcTree procTree = null;
+
+ if (args.length < 3) {
+ System.out.println("three arguments ...");
+ System.out.println("rank, size, root");
+ return;
+ }
+
+ int index = Integer.parseInt(args[0]);
+ int extent = Integer.parseInt(args[1]);
+ int root = Integer.parseInt(args[2]);
+ procTree = new ProcTree();
+ int places = ProcTree.PROCTREE_A * index;
+
+ for (int i = 1; i <= ProcTree.PROCTREE_A; i++) {
+ ++places;
+ int ch = (ProcTree.PROCTREE_A * index) + i + root;
+ System.out.println("places " + places);
+ ch %= extent;
+
+ if (places < extent) {
+ System.out.println("ch <" + i + ">" + "=<" + ch + ">");
+ System.out.println("adding to the tree at index <" + (i - 1) + ">\n\n");
+ procTree.child[i - 1] = ch;
+ procTree.numChildren++;
+ }
+ else {
+ System.out.println("not adding to the tree");
+ }
+
+ //places = index*ProcTree.PROCTREE_A +i;
+ }
+
+ System.out.println("procTree.numChildren <" + procTree.numChildren + ">");
+
+ if (index == root)
+ procTree.isRoot = true;
+ else {
+ procTree.isRoot = false;
+ int pr = (index - 1) / ProcTree.PROCTREE_A;
+ procTree.parent = pr;
+ }
+
+ procTree.root = root;
+
+ for (int i = 0; i < procTree.PROCTREE_A; i++) {
+ System.out.print(" child[" + i + "]=>" + procTree.child[i]);
+ }
+
+ System.out.println(" ------- End --------");
+ //ProcTree main method ...
+ }
+
+}
diff --git a/src/xdev/smpdev/ConfigReader.java b/src/xdev/smpdev/ConfigReader.java
new file mode 100644
index 0000000..af3a200
--- /dev/null
+++ b/src/xdev/smpdev/ConfigReader.java
@@ -0,0 +1,244 @@
+/*
+ The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : ConfigReader.java
+ * Author : Aamir Shafi, Bryan Carpenter
+ * Created : Thu Apr 9 12:22:15 BST 2004
+ * Revision : $Revision: 1.1 $
+ * Updated : $Date: 2005/07/31 15:14:15 $
+ *
+ */
+
+package xdev.smpdev ;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+
+/**
+ * <p>This class is a utiliy class that is used to read the start-up information from a configuration file. The users
+ * of the mpjdev do not have to deal with this file. </p>
+ */
+
+public class ConfigReader {
+ private BufferedReader bufferedReader = null;
+ URL aURL = null;
+ InputStream in = null;
+
+ private String delimiter = null;
+ private int numberOfHosts = 0;
+ int count = 1;
+ String fileName = null;
+ /**
+ * Constructor of this utility class
+ * @param fileName String The name of the configuration file. This can be on the local file system or
+ * on some server accessible via http.
+ * @throws IOException If some I/O error happens.
+ * @throws FileNotFoundException If the file is not found.
+ * @throws MalformedURLException If the http URL is malformed.
+ */
+ public ConfigReader(String fileName) throws IOException,
+ FileNotFoundException, MalformedURLException {
+
+ this.fileName = fileName;
+
+ if (fileName.startsWith("http://")) {
+
+ try {
+ aURL = new URL(new String(fileName));
+ }
+ catch (MalformedURLException mue) {
+ mue.printStackTrace();
+ System.exit(0);
+ }
+
+ try {
+ in = aURL.openStream();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ System.exit(0);
+ }
+
+ bufferedReader = new BufferedReader(new InputStreamReader(in));
+ //this is the http URL now !!!!
+ }
+ else {
+ try {
+ bufferedReader = new BufferedReader(new FileReader(this.fileName));
+ }
+ catch (FileNotFoundException fnfe) {
+ System.out.println("File Not Found Exception" + this.fileName);
+ System.out.println("Please locate and Make sure that the appropriate configuration file is lying in " +
+ "the appropriate directory .....");
+ System.exit(0);
+ }
+ }
+ } //end ConfigReader constructor !
+
+ /**
+ * Read the number of processes mentioned in the configuration file.
+ * @throws IOException If some I/O error occurs
+ * @return String The number of total processes
+ */
+ public String readNoOfProc() throws IOException {
+ String temp = null;
+ boolean loop = true;
+ while (loop) {
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("Problem reading the config file" + this.fileName);
+ System.exit(0);
+ }
+
+ if (temp == null || temp.equals("")) {
+ continue;
+ }
+
+ if (temp.startsWith("#")) {
+ continue;
+ }
+ temp = temp.trim();
+ numberOfHosts = (new Integer(temp)).intValue();
+ loop = false;
+ }
+ return temp;
+ }
+
+ /**
+ * Reads integer as a string
+ * @throws IOException
+ * @return String
+ */
+ public String readIntAsString() throws IOException {
+ String temp = null;
+ boolean loop = true;
+ while (loop) {
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("Problem reading the config file" + this.fileName);
+ System.exit(0);
+ }
+
+ if (temp == null || temp.equals("")) {
+ continue;
+ }
+
+ if (temp.startsWith("#")) {
+ continue;
+ }
+ temp = temp.trim();
+ loop = false;
+ }
+ return temp;
+ }
+
+ /**
+ * Reads line from the configuration file.
+ * @throws IOException
+ * @return String
+ */
+ public String readLine() throws IOException {
+ if (count > numberOfHosts) {
+ return null;
+ }
+ String temp;
+ try {
+ temp = bufferedReader.readLine();
+ }
+ catch (IOException ioe) {
+ System.out.println("IOException");
+ ioe.printStackTrace();
+ return null;
+ }
+
+ if (temp == null || temp.equals("")) {
+ System.out.println("empty or whitespace");
+ return "empty";
+ }
+
+ if (temp.startsWith("#")) {
+ //System.out.println("#");
+ return "#";
+ }
+
+ //return if we have read whatever the user has asked for, we dont want to
+ //read more than what is required ...
+
+ //System.out.println("Before trmming in readLine"+temp);
+ temp = temp.trim();
+ count++;
+ return temp;
+ }
+
+ /**
+ * Close all the streams.
+ */
+ public void close() {
+ try {
+ bufferedReader.close();
+ in.close();
+ }
+ catch (Exception ioe) {
+ }
+ finally {
+ bufferedReader = null;
+ aURL = null;
+ in = null;
+ }
+ } //end close()
+
+ /** Just for testing this class ! ! ! **/
+ public static void main(String args[]) throws Exception {
+
+ String CONFIGURATION_FILE = new String("mpjdev.conf");
+ int NUMBER_OF_HOSTS = 0;
+ ConfigReader reader = new ConfigReader(CONFIGURATION_FILE);
+ NUMBER_OF_HOSTS = (new Integer(reader.readNoOfProc())).intValue();
+ System.out.println("NUMBER_OF_HOSTS " + NUMBER_OF_HOSTS);
+ //this would get the total hosts
+
+ String line = null;
+ while ( (line = reader.readLine()) != null) {
+ if (line.equals("empty") || line.equals("#")) {
+ continue;
+ }
+ line = line.trim();
+ StringTokenizer tokenizer = new StringTokenizer(line, "@");
+ System.out.println("Node<" + tokenizer.nextToken() + ">");
+ System.out.println("Num<" + tokenizer.nextToken() + ">"); //this gets you names of individual machines,
+ }
+ reader.close();
+ } //end static void main()
+}
diff --git a/src/xdev/smpdev/SMPDevProcess.java b/src/xdev/smpdev/SMPDevProcess.java
new file mode 100644
index 0000000..e9f154c
--- /dev/null
+++ b/src/xdev/smpdev/SMPDevProcess.java
@@ -0,0 +1,59 @@
+/*
+ The MIT License
+
+ Copyright (c) 2010
+ 1. Bryan Carpenter (2010)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SMPDevProcess.java
+ * Author : Kamran Hameed, Bryan Carpenter
+ * Created : Thu Dec 24 10:47:35 PKT 2009
+ * Revision : $Revision: 1.0 $
+ * Updated : $Thu Dec 24 10:47:35 PKT 2009$
+ */
+
+package xdev.smpdev;
+
+import java.util.UUID;
+import xdev.ProcessID;
+
+public class SMPDevProcess extends ThreadGroup {
+
+ private ProcessID myID;
+
+ public SMPDevProcess(String name) {
+ super(name);
+ }
+
+ public SMPDevProcess(ThreadGroup parent,String name) {
+ super(parent,name);
+ }
+ public ProcessID getID() {
+ return myID;
+ }
+ public void setProcessID(ProcessID id) {
+ this.myID = id;
+ }
+
+}
+
diff --git a/src/xdev/smpdev/SMPDevice.java b/src/xdev/smpdev/SMPDevice.java
new file mode 100644
index 0000000..ee05e2c
--- /dev/null
+++ b/src/xdev/smpdev/SMPDevice.java
@@ -0,0 +1,372 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SMPDevice.java
+ * Author : Aamir Shafi
+ * Created :
+ * Revision :
+ * Updated :
+ */
+package xdev.smpdev;
+
+import xdev.*;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * An abstract device
+ */
+public class SMPDevice implements Device {
+
+ public static Logger logger = Logger.getLogger("mpj");
+ public static int SEND_OVERHEAD=0;
+ public static int RECV_OVERHEAD=0;
+
+
+ /**
+ * init
+ * The question that is coming to me mind again and again is ...
+ * so each thread has an object of xdev.smpdev.SMPDevice
+ * so when they call like SMPDevice.init( ..) method ...in order to sync
+ * the access, do we need to make this method static or its possible
+ * to sync different instances of this object ....
+ * Welcome to concurrent-programming ..but not as hard as parallel
+ * programming itself ...
+ *
+ * Write a test program .... yeah i did ..but we need static methods ...
+ * args[0] is +=+> nprocs ...
+ * args[1] is =+=> rank ... is it like ProcessID ?
+ * args[2] conf-file may be passed if required ...
+ */
+ public ProcessID[] init(String[] args) throws XDevException {
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug("Inside SMPDevice Init");
+ }
+ ProcessID[] ids = null;
+
+ try {
+
+ ids = xdev.smpdev.SMPDeviceImpl.init(args[1],
+ Integer.parseInt(args[0]));
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return ids;
+ }
+
+ /**
+ * returns my id
+ */
+ public ProcessID id() {
+ return xdev.smpdev.SMPDeviceImpl.WORLD.id();
+ }
+
+ /**
+ * Shuts the device
+ */
+ public void finish() throws XDevException {
+ xdev.smpdev.SMPDeviceImpl.finish();
+ }
+
+ /**
+ * Non-blocking send using standard-mode.
+ */
+ public mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context)
+ throws XDevException {
+
+ mpjdev.Request req = null;
+
+ try {
+ req = xdev.smpdev.SMPDeviceImpl.WORLD.isend(buf, destID,
+ tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return req;
+
+ }
+
+ /**
+ * Blocking send using standard-mode.
+ */
+ public void send(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws XDevException {
+
+ try {
+ xdev.smpdev.SMPDeviceImpl.WORLD.send(buf, destID, tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ }
+
+ /**
+ * Non-blocking send using synchronous-mode
+ */
+ public mpjdev.Request issend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws XDevException {
+ mpjdev.Request req = null;
+
+ try {
+ req = xdev.smpdev.SMPDeviceImpl.WORLD.isend(buf, destID, tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return req;
+
+ }
+
+ /**
+ * Blocking send using synchronous-mode
+ */
+ public void ssend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws XDevException {
+ try {
+ xdev.smpdev.SMPDeviceImpl.WORLD.send(buf, destID, tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+ }
+
+ public mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context)
+ throws XDevException {
+ mpjdev.Status s = null;
+
+ try {
+ s = xdev.smpdev.SMPDeviceImpl.WORLD.recv(buf, srcID, tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return s;
+
+ }
+
+ public mpjdev.Request irecv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context, mpjdev.Status status)
+ throws XDevException {
+ mpjdev.Request req = null;
+
+ try {
+ req = xdev.smpdev.SMPDeviceImpl.WORLD.irecv(buf, srcID,
+ tag, context, status);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+ return req;
+
+ }
+ /**
+ * Blocking probe method
+ * @param srcID The sourceID of the sender
+ * @param tag The tag of the message
+ * @param context The integer specifying the context
+ * @return mpjdev.Status The status object
+ */
+ public mpjdev.Status probe(ProcessID srcID, int tag,
+ int context) throws XDevException {
+
+ mpjdev.Status status = null;
+ boolean comp = false;
+
+ while (!comp) {
+ status = this.iprobe(srcID, tag, context);
+ if (status != null) {
+ comp = true;
+ }
+ }
+
+ return status;
+ }
+
+ /**
+ * Non-Blocking probe method.
+ * @param srcID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+
+ public mpjdev.Status iprobe(ProcessID srcID, int tag,
+ int context) throws XDevException {
+
+ // ProcessID dstUUID = id().uuid();
+ /// ProcessID srcUUID = srcID.uuid();
+ mpjdev.Status status = null;
+
+ try {
+ status = xdev.smpdev.SMPDeviceImpl.WORLD.iprobe(srcID,
+ tag, context);
+ } catch (Exception e) {
+ throw new XDevException(e);
+ }
+
+
+ return status;
+
+ // return null;
+}
+ /**
+ * Non-Blocking overloaded probe method.
+ *
+ * @param srcID
+ * @param dstID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ */
+ public mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID, int tag,
+ int context, mpjbuf.Buffer buf) throws XDevException {
+
+ return xdev.smpdev.SMPDeviceImpl.WORLD.iprobeAndFetch( srcID, dstID, tag,
+ context, buf);
+
+ }
+ /**
+ * This method does not have any definitation,
+ * It is added in xdev.Device.java
+ * Network device should have its implementation only
+ * */
+ public mpjdev.Status iprobe(ProcessID srcID, ProcessID dstID, int tag,
+ int context) throws XDevException {
+ return null;
+ }
+
+public mpjdev.Request peek() throws XDevException {
+ return null ;
+ }
+
+// putting in the the peek utility here in the file
+static CompletedList completedList = new CompletedList() ;
+
+ static class CompletedList {
+
+ SMPRequest front, back ;
+ int size ;
+
+ /**
+ * Remove request from any position in the completedList
+ */
+ synchronized void remove(SMPRequest request) {
+ if(request.inCompletedList) {
+ if(front == back) {
+ front = null;
+ back = null;
+ } else if (front == request) {
+ front.prevCompleted.nextCompleted = front.nextCompleted;
+ front.nextCompleted.prevCompleted = front.prevCompleted;
+ front = front.prevCompleted;
+ } else if (back == request) {
+ back.prevCompleted.nextCompleted = back.nextCompleted;
+ back.nextCompleted.prevCompleted = back.prevCompleted;
+ back = back.nextCompleted;
+ } else {
+ request.prevCompleted.nextCompleted = request.nextCompleted;
+ request.nextCompleted.prevCompleted = request.prevCompleted;
+ }
+
+ request.inCompletedList = false;
+ size--;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" size " + size);
+ }
+ }
+ }
+
+ /**
+ * Remove request from the front of completedList
+ * Wait until a request is found
+ */
+ synchronized SMPRequest remove() {
+
+ while (listEmpty()) {
+ try {
+ wait();
+ } catch (Exception e) {
+ }
+ }
+
+ SMPRequest oldFront = null;
+ oldFront = front;
+ if (front == back) {
+ front = null;
+ back = null;
+ } else {
+ front.prevCompleted.nextCompleted = front.nextCompleted;
+ front.nextCompleted.prevCompleted = front.prevCompleted;
+ front = front.prevCompleted;
+ }
+
+ oldFront.inCompletedList = false;
+ size--;
+
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" size " + size);
+ }
+
+ return oldFront;
+ }
+
+ /**
+ * Add request at the front of completedList
+ */
+ synchronized void add(SMPRequest request) {
+ if (listEmpty()) {
+ front = request;
+ back = request;
+ request.nextCompleted = request;
+ request.prevCompleted = request;
+ } else {
+ front.nextCompleted.prevCompleted = request;
+ request.nextCompleted = front.nextCompleted;
+ front.nextCompleted = request;
+ request.prevCompleted = front;
+ back = request;
+ }
+ size++;
+ if (mpi.MPI.DEBUG && logger.isDebugEnabled()) {
+ logger.debug(" size " + size);
+ }
+ request.inCompletedList = true;
+ notify();
+ }
+
+ boolean listEmpty() {
+ return (front == null && back == null);
+ }
+}
+
+/// ending here the pasting :)
+ public int getRecvOverhead() {
+ return RECV_OVERHEAD ;
+ }
+
+ public int getSendOverhead() {
+ return SEND_OVERHEAD ;
+ }
+}
diff --git a/src/xdev/smpdev/SMPDeviceImpl.java b/src/xdev/smpdev/SMPDeviceImpl.java
new file mode 100644
index 0000000..2852fc8
--- /dev/null
+++ b/src/xdev/smpdev/SMPDeviceImpl.java
@@ -0,0 +1,1047 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SMPDeviceImpl.java
+ * Author : Sang Lim, Bryan Carpenter, Aamir Shafi
+ * Created : Wed Nov 13 17:07:15 EST 2002
+ * Revision : $Revision: 1.5 $
+ * Updated : $Date: 2005/06/23 12:43:29 $
+ */
+package xdev.smpdev;
+
+//Replace these stars with something more understandable ...
+import xdev.*;
+//import xdev.niodev.ConfigReader ;
+import mpjdev.Status;
+import mpjdev.Request;
+import mpjbuf.*;
+import java.nio.ByteBuffer;
+import mpjbuf.NIOBuffer;
+import java.util.HashMap;
+import java.util.UUID;
+import java.io.PrintStream;
+import java.io.FileOutputStream;
+
+/**
+ * The communicator class. Directly analogous to an MPI communicator.
+ */
+public class SMPDeviceImpl {
+
+ static int numRegisteredThreads = 0;
+ private static boolean initialized = false; // MPJ initialized
+ public static PrintStream out = null;
+ private int size;
+ private Thread[] threads; //Map from node id to Thread.
+ private HashMap ids; //Map from Thread to node id.
+ xdev.ProcessID id = null;
+ xdev.ProcessID[] pids = null;
+ static SMPDevProcess smpProcess = null;
+
+ private int context;
+ private int barrierCount;
+ private SMPDeviceImpl newSMPDeviceImpl;
+ public static final int MODEL_MULTIPROCESS = 0;
+ public static final int MODEL_MULTITHREADED = 1;
+
+ public static int getModel() {
+ return MODEL_MULTITHREADED;
+ }
+
+ /**
+ * Number of processes spanned by this communicator.
+ */
+ public int size() {
+ return size;
+ }
+
+ /**
+ * Id of current process relative to this communicator.
+ * Equivalent to MPI_COMM_RANK.
+ */
+ public xdev.ProcessID id() throws XDevException {
+
+ Thread thisThread = Thread.currentThread();
+ ProcessID value = null ;
+
+ if(thisThread.getThreadGroup() instanceof SMPDevProcess) {
+ value = ((SMPDevProcess)(thisThread.getThreadGroup())).getID();
+ }
+
+ if (value == null) {
+ throw new XDevException("SMPDeviceImpl.id() invoked by thread " +
+ "outside communicator group");
+ }
+ return value;
+ }
+ /**
+ * Create a new communicator the spanning the same
+ * set of processes, but with a distinct communication context.
+ public SMPDeviceImpl dup() throws XDevException {
+ int [] ids = new int [size] ;
+ for(int i = 0 ; i < size ; i++)
+ ids [i] = i ;
+
+ return create(ids) ;
+ }
+ */
+ private static int nextContext;
+
+ /**
+ * Create a new communicator the spanning the set of processes
+ * selected by the `ids' array (containing ids are relative to this
+ * communicator).
+ * The new communicator also has a distinct communication context.
+ * Processes that are out side of the group will return null.
+
+ public synchronized SMPDeviceImpl create(int [] ids) throws XDevException {
+ int myId = id() ;
+ boolean amInGroup = false ;
+
+ if(barrierCount == 0) {
+ newSMPDeviceImpl = new SMPDeviceImpl() ;
+ synchronized(SMPDeviceImpl.class) {
+ newSMPDeviceImpl.context = nextContext++ ;
+ }
+ newSMPDeviceImpl.size = ids.length ;
+ newSMPDeviceImpl.threads = new Thread [newSMPDeviceImpl.size] ;
+ newSMPDeviceImpl.ids = new HashMap() ;
+ boolean inGroup [] = new boolean [size] ;
+
+ for(int i = 0 ; i < newSMPDeviceImpl.size ; i++) {
+ int id = ids [i] ;
+ if(id < 0 || id > size) {
+ throw new XDevException("In SMPDeviceImpl.create(), value ids [" +
+ i + "] is out of range (" + id + ")") ;
+ }
+
+ if(inGroup [id]) {
+ throw new XDevException("In SMPDeviceImpl.create(), value " + id +
+ "duplicated in ids array") ;
+ }
+ else
+ inGroup [id] = true ;
+
+ if(id == myId)
+ amInGroup = true ;
+
+ newSMPDeviceImpl.threads [i] = threads [id] ;
+ newSMPDeviceImpl.ids.put(threads [id], new Integer(i)) ;
+ }//end for ....
+
+ newSMPDeviceImpl.barrierCount = 0 ;
+ }//if barrierCount == 0 ends
+ else {
+ if(ids.length != newSMPDeviceImpl.size) {
+ throw new XDevException("In SMPDeviceImpl.create(), threads " +
+ "specify different values for ids array") ;
+ }
+
+ for(int i = 0 ; i < newSMPDeviceImpl.size ; i++) {
+ int id = ids [i] ;
+ if(id == myId)
+ amInGroup = true ;
+ if(id < 0 || id > size ||
+ newSMPDeviceImpl.threads [i] != threads [id]) {
+ throw new XDevException("In SMPDeviceImpl.create(), threads " +
+ "specify different values for ids array") ;
+ }
+ }
+ }//end else if barrierCount == 0
+
+ barrierCount++ ;
+ SMPDeviceImpl result = amInGroup ? newSMPDeviceImpl : null ;
+
+ if(barrierCount == size) {// Reset barrier and wake up other threads.
+ barrierCount = 0 ;
+ notifyAll() ;
+ }
+
+ else {
+ try {
+ wait() ;
+ }
+ catch(InterruptedException e) {
+ throw new XDevException("In SMPDeviceImpl.create(), unexpected " +
+ "interuption during wait()??") ;
+ }
+ }
+
+ return result ;
+ }
+ */
+ /**
+ * Destroy this communicator.
+ public void free() {}
+ */
+ /**
+ * Blocking send ...
+ *
+ * Equivalent to MPI_SEND
+ */
+ public void send(mpjbuf.Buffer buf, ProcessID destID, int tag, int context)
+ throws Exception {
+ SMPRequest req = (SMPRequest) isend(buf, destID, tag, context);
+
+ if (mpi.MPI.DEBUG && SMPDevice.logger.isDebugEnabled()) {
+ SMPDevice.logger.debug("After isend in -- calling iwait "
+ + req.hashCode());
+ }
+ req.iwait();
+ if (mpi.MPI.DEBUG && SMPDevice.logger.isDebugEnabled()) {
+ SMPDevice.logger.debug("After ---- calling iwait "+ req.hashCode());
+ }
+ }
+
+ /**
+ * Blocking receive of message, whose contents are copied to `buf'.
+ * The capacity of `buf' must be large enough to accept these
+ * contents. Initializes the `source' and `tag' fields of the
+ * returned `Status'. Equivalent to MPI_RECV.
+ */
+ public mpjdev.Status recv(mpjbuf.Buffer buf, ProcessID srcID, int tag,
+ int context) throws XDevException {
+ mpjdev.Status status = new mpjdev.Status(srcID.uuid(), tag, -1);
+ SMPRequest req = (SMPRequest) irecv(buf, srcID, tag, context, status);
+ return req.iwait();
+ }
+ private RecvQueue recvQueue = new RecvQueue();
+ private SendQueue sendQueue = new SendQueue();
+
+ /**
+ * Non-blocking version of `send'.
+ * Equivalent to MPI_ISEND
+ */
+ public mpjdev.Request isend(mpjbuf.Buffer buf, ProcessID destID,
+ int tag, int context) throws Exception {
+
+// out.println(id().uuid()+"-isend-<"+tag+">-<"+context+">-start");
+ // System.out.println("-isend-<"+tag+">-<"+context+">-start");
+
+ /*these checks should be at upper levels ...
+ if (buf == null)
+ throw new XDevException("In SMPDeviceImpl.isend(), buffer is null.");
+
+ if(dest < 0) {
+ throw new XDevException("In SMPDeviceImpl.isend(), requested negative " +
+ "message destination: " + dest) ;
+ } else if(dest >= size) {
+ throw new XDevException("In SMPDeviceImpl.isend(), requested destination " +
+ dest + " does not exist in communicator " +
+ "of size " + size) ;
+ }*/
+
+ ProcessID myID = id();
+// out.println(" start of isend <"+myID+">=<"+id()+">");
+ SMPSendRequest send = new SMPSendRequest(buf, context,
+ destID, myID, tag);
+ SMPRecvRequest matchingRecv = null;
+ // System.out.println(myID +" sending to "+destID+" context "+context+" tag "+ tag);
+ // System.out.println("In isend -- " + send.hashCode() + " Context " + context + " Tag " + tag + " srcID " + myID.uuid() + " destID " + destID.uuid());
+ synchronized (SMPDeviceImpl.class) {
+
+ matchingRecv = recvQueue.rem(send);
+// out.println("Did we find the matching recv "+matchingRecv);
+
+ if (matchingRecv != null) {
+
+// out.println("matching recv found ...");
+
+// copy data from `buf' to buffer in `matchingRecv'
+// and initialize status field in `matchingRecv'.
+// matchingRecv.buf.copy(buf) ;
+////////////////////////////////////////////////////////////////////
+/////////////////// *message copying stuff* ///////////////////////
+ // System.out.println(" isend -- matching recv size "+ ((NIOBuffer)(matchingRecv.buffer.getStaticBuffer())).getCapacity() +" receiver "+destID+" context "+context);
+ // System.out.println(" isend -- buf size "+ buf.getSize()+" sender "+myID);
+ matchingRecv.buffer.setSize(buf.getSize());
+//out.println(id() + " setting the size in the next line to <"+
+ // matchingRecv.buffer.getSize() +">") ;
+ if (buf.getDynamicBuffer() != null) {
+ matchingRecv.buffer.setDynamicBuffer(buf.getDynamicBuffer());
+ }
+
+ // ((NIOBuffer)
+ // matchingRecv.buffer.getStaticBuffer()).getBuffer().limit(
+ // buf.getSize() );
+
+ // HYB how much I need to get + myOffset
+
+ ((NIOBuffer) matchingRecv.buffer.getStaticBuffer()).getBuffer().limit(
+ matchingRecv.buffer.getSize() + matchingRecv.buffer.offset());
+ // ((NIOBuffer)
+ // matchingRecv.buffer.getStaticBuffer()).getBuffer().position();
+ ((NIOBuffer) matchingRecv.buffer.getStaticBuffer()).getBuffer()
+ .position(SMPDevice.RECV_OVERHEAD); // HYB
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(buf.getSize());
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(
+ buf.getSize() + buf.offset());
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(0);
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(
+ SMPDevice.SEND_OVERHEAD); // HYB
+ // System.out.println ("xdev-MRecv B$PUT: Src= limit:"+((NIOBuffer)
+ // buf.getStaticBuffer()).getBuffer().limit()
+ // +" Dst= Limit:"+((NIOBuffer)
+ // matchingRecv.buffer.getStaticBuffer()).getBuffer().limit()
+ // +"^^^^^^\n");
+ ((NIOBuffer) matchingRecv.buffer.getStaticBuffer()).getBuffer().put(
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer());
+ ((NIOBuffer) matchingRecv.buffer.getStaticBuffer()).getBuffer().flip();
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().clear();
+
+
+ matchingRecv.status.srcID = myID.uuid();
+ matchingRecv.status.tag = tag;
+ matchingRecv.setPending(false);
+ matchingRecv.status.numEls = send.numEls;
+ matchingRecv.status.type = send.type; //temp
+
+ matchingRecv.numEls = send.numEls; //temp
+ matchingRecv.type = send.type;
+
+ // Check if anybody is iwait-ing on `matchingRecv'.
+ // If so, remove all requests from wait set, and signal
+ // the waiting thread.
+
+ SMPRequest.WaitSet waiting = matchingRecv.getWaitSet();
+ if (waiting != null) {
+ waiting.select(matchingRecv);
+ }
+
+ send.setPending(false);
+ } else {
+ // System.out.println("No matching recv found ...");
+ send.setPending(true);
+ sendQueue.add(send);
+// out.println("added it to sendqueue "+sendQueue);
+
+ }
+ }
+//System.out.println("Returning send from smpdev ");
+// out.println(" end of isend <"+myID+">=<"+id()+">");
+// out.println(id().uuid()+"-isend-<"+tag+">-<"+context+">-end");
+ return send;
+ }
+
+
+
+
+
+ /**
+ * Non-Blocking overloaded probe method.
+ *
+ * @param srcID
+ * @param dstID
+ * @param tag
+ * @param context
+ * @return mpjdev.Status
+ **/
+ public mpjdev.Status iprobeAndFetch(ProcessID srcID, ProcessID dstID, int tag,
+ int context, mpjbuf.Buffer buf) throws XDevException {
+
+ SMPSendRequest request = sendQueue.check(context, dstID, srcID, tag);
+
+ if (request != null) {
+
+ synchronized (SMPDeviceImpl.class) {
+// System.out.println (" smpdev: complete Request, processing buffer ");
+ mpjdev.Status status = new mpjdev.Status(id().uuid(), tag, -1);
+ SMPRecvRequest recv = new SMPRecvRequest(buf, context, dstID, srcID, tag,
+ status);
+
+ SMPSendRequest matchingSend = sendQueue.rem(recv);
+ buf.setSize(matchingSend.buffer.getSize());
+ if (matchingSend.buffer.getDynamicBuffer() != null) {
+ buf.setDynamicBuffer(matchingSend.buffer.getDynamicBuffer());
+ }
+ // ((NIOBuffer)
+ // matchingSend.buffer.getStaticBuffer()).getBuffer().limit(buf.getSize());
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer().limit(
+ matchingSend.buffer.getSize() + matchingSend.buffer.offset()); // HYB
+ // ((NIOBuffer)
+ // matchingSend.buffer.getStaticBuffer()).getBuffer().position(0);
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer()
+ .position(SMPDevice.SEND_OVERHEAD); // HYB
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(buf.getSize()
+ // );
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(
+ buf.getSize() + buf.offset()); // HYB
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(0);
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(
+ SMPDevice.RECV_OVERHEAD); // HYB
+
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().put(
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer());
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().flip();
+
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer().clear();
+
+
+
+ recv.status = status;
+ // System.out.println("UUID" + matchingSend.sourceID.uuid());
+ // System.out.println("Status -- tag" + status.tag);
+ recv.status.srcID = matchingSend.srcID.uuid();
+ recv.status.tag = matchingSend.tag;
+ recv.type = matchingSend.type;
+ recv.numEls = matchingSend.numEls;
+ request.srcID = matchingSend.srcID;
+ status.srcID = matchingSend.srcID.uuid();
+
+ // recv.status.numEls = matchingSend.numEls; //temp
+ // recv.status.type = matchingSend.type; //temp
+
+ // System.out.println(" In irecv -- status " + status.index + " " +
+ // recv.status.srcID + " " + recv.status.tag );
+
+ matchingSend.setPending(false);
+
+ // Check if anybody is iwait-ing on `matchingSend'.
+ // If so, remove all requests from wait set, and signal
+ // the waiting thread.
+
+ SMPRequest.WaitSet waiting = matchingSend.getWaitSet();
+ if (waiting != null) {
+ waiting.select(matchingSend);
+ }
+ recv.setPending(false);
+
+
+ return status;
+ }
+ }
+ //System.out.println (" smpdev: incomplete Request, releasing lock in Fetch ");
+ return null;
+ }
+ /**
+ * Non-blocking version of `recv'.* Equivalent to MPI_IRECV
+ */
+ public mpjdev.Request irecv(mpjbuf.Buffer buf, ProcessID srcID,
+ int tag, int context, mpjdev.Status status)
+ throws XDevException {
+
+// out.println(id().uuid()+"-irecv-<"+tag+">-<"+context+">-start");
+// System.out.println("irecv-<"+tag+">-<"+context+">-start");
+/*
+ if (buf == null)
+ throw new XDevException("In SMPDeviceImpl.irecv(), buffer is null.");
+
+ if(src < -2) { // -1, -2 are ANY_TAG, ANY_SOURCE
+
+ throw new XDevException("In SMPDeviceImpl.irecv(), requested negative " +
+ "message source: " + src) ;
+ } else if(src >= size) {
+ throw new XDevException("In SMPDeviceImpl.irecv(), requested source " +
+ src + " does not exist in communicator " +
+ "of size " + size) ;
+ }
+ */
+//System.out.println("Inside irecv in smpdev ");
+ ProcessID myID = id();
+ //out.println(" start of irecv <"+myID+">=<"+id()+">");
+ SMPRecvRequest recv = new SMPRecvRequest(buf, context, myID,
+ srcID, tag, status);
+ //out.println(" recv_request <"+recv+">=<"+id()+">");
+// recv.status =status;
+ // System.out.println(myID +" receiving from "+srcID+" context "+context+" tag "+ tag);
+ synchronized (SMPDeviceImpl.class) {
+
+ SMPSendRequest matchingSend = sendQueue.rem(recv);
+//matchingSend.status = status;
+ if (matchingSend != null) {
+
+ //out.println(" got matching send req. <"+matchingSend+">=<"
+ // +id()+">");
+// Copy data from buffer in `matchingSend' to `buf'
+// and initialize status field in `recv'.
+// buf.copy(matchingSend.buf) ;
+// copying is going to be a little complicated than this ...
+/////////////////// *message copying stuff* ///////////////////////
+//out.println(id() + " setting the size in the next line to <"+
+ // matchingSend.buffer.getSize() +">") ;
+ buf.setSize(matchingSend.buffer.getSize());
+ if (matchingSend.buffer.getDynamicBuffer() != null) {
+ buf.setDynamicBuffer(matchingSend.buffer.getDynamicBuffer());
+ }
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer().limit(
+ matchingSend.buffer.getSize() + matchingSend.buffer.offset()); // HYB
+ // ((NIOBuffer)
+ // matchingSend.buffer.getStaticBuffer()).getBuffer().position(0);
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer()
+ .position(SMPDevice.SEND_OVERHEAD); // HYB
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(buf.getSize()
+ // );
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().limit(
+ buf.getSize() + buf.offset()); // HYB
+ // ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(0);
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().position(
+ SMPDevice.RECV_OVERHEAD); // HYB
+ // System.out.println ("xdev-MSend B$PUT: DST= limit:"+((NIOBuffer)
+ // buf.getStaticBuffer()).getBuffer().limit()
+ // +" SRC= Limit:"+((NIOBuffer)
+
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().put(
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer());
+ ((NIOBuffer) buf.getStaticBuffer()).getBuffer().flip();
+
+ /*
+ * if (commDone) { ((NIOBuffer)
+ * matchingSend.buffer.getStaticBuffer()).getBuffer().flip();
+ * ((NIOBuffer)
+ * matchingSend.buffer.getStaticBuffer()).getBuffer().position(4); try{
+ * int [] test = new int [6]; matchingSend.buffer.read(test, 0, 5);
+ * for(int i=0;i<test.length;i++) {
+ * System.out.print(" MS "+test[i]+" "); } }catch (BufferException e){
+ * System.out.print("MS buffer read exception " ); } }
+ */
+
+ ((NIOBuffer) matchingSend.buffer.getStaticBuffer()).getBuffer().clear();
+
+
+ recv.status =status;
+ // System.out.println("UUID" + matchingSend.sourceID.uuid());
+ // System.out.println("Status -- tag" + status.tag);
+ recv.status.srcID = matchingSend.srcID.uuid();
+ recv.status.tag = matchingSend.tag;
+ recv.type = matchingSend.type;
+ recv.numEls = matchingSend.numEls;
+ // recv.status.numEls = matchingSend.numEls; //temp
+ //recv.status.type = matchingSend.type; //temp
+
+
+ // System.out.println(" In irecv -- status " + status.index + " " + recv.status.srcID + " " + recv.status.tag );
+
+ matchingSend.setPending(false);
+
+ // Check if anybody is iwait-ing on `matchingSend'.
+ // If so, remove all requests from wait set, and signal
+ // the waiting thread.
+
+ SMPRequest.WaitSet waiting = matchingSend.getWaitSet();
+ if (waiting != null) {
+ waiting.select(matchingSend);
+ }
+
+ recv.setPending(false);
+ } else {
+ // System.out.println(" aint any matching send thing ");
+
+// out.println(" added it to recvQue ... "+recvQueue);
+ recv.setPending(true);
+ recvQueue.add(recv);
+ }
+ }
+//System.out.println("Returning recv from smpdev ");
+// out.println(" end of irecv <"+myID+">=<"+id()+">");
+// out.println(id().uuid()+"-irecv-<"+tag+">-<"+context+">-end");
+ return recv;
+ }
+
+
+ public mpjdev.Status iprobe(ProcessID srcID, int tag,
+ int context) throws XDevException {
+
+ mpjdev.Status status = null;
+ ProcessID myID = id();
+ SMPSendRequest request = sendQueue.check(context, myID, srcID, tag);
+//System.out.print(" request null? "+request);
+ if (request != null) {
+ //now this is a tricky one ...
+ // System.out.print(" mpjdev request numEls = "+request.numEls);
+ status = new mpjdev.Status(request.srcID.uuid(),
+ request.tag, -1, request.type,
+ request.numEls); //jd
+
+ }
+
+ return status;
+ // return null;
+ }
+
+
+
+
+ /**
+ * Initialize MPJ, and register current thread as a node in the new
+ * MPJ world. This assumes every thread knows in advance the total
+ * number of threads, and also knows its own unique rank in the set of
+ * threads.
+ * <p>
+ * <table>
+ * <tr><td><tt> nprocs </tt></td><td> number of nodes in the MPJ world.</tr>
+ * <tr><td><tt> myId </tt></td><td> rank the current thread should have
+ * in that world.</tr>
+ * </table>
+ * <p>
+ */
+ public synchronized static ProcessID[] init(String file, int rank)
+ throws Exception {
+ /* putting the debug initialization code here */
+ // String LOG_FILE = new String("../logs/"+rank+".log");
+ out = System.out;
+
+ //out.println("number of registered threads are "+numRegisteredThreads);
+/* FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(LOG_FILE);
+ } catch (Exception fnfe) {
+ throw new Exception("FileNotFoundException, LOG_FILE=" +
+ LOG_FILE +
+ " and the message is " + fnfe.getMessage());
+ }
+
+ out = new PrintStream(fos);
+ */
+ /* putting the debug initialization code here */
+
+
+ //System.out.println(" -- File "+file);
+ int nprocs = 0, psl = 0;
+/*
+ try {
+ String mpjHome = System.getenv("MPJ_HOME");
+ //ConfigReader reader = new ConfigReader(file);
+ ConfigReader reader = new ConfigReader(mpjHome+"/conf/mpjdev.conf");
+
+ nprocs = (new Integer(reader.readNoOfProc())).intValue();
+ //System.out.println(" nprocs "+nprocs);
+ psl = (new Integer(reader.readIntAsString())).intValue();
+ reader.close();
+ } catch (Exception eex) {
+ eex.printStackTrace();
+ }
+*/
+ nprocs = Integer.parseInt(file); //FIXME: this variable needs to be
+ // renamed ...
+ /* out.println("rank<"+rank+">,nprocs<"+nprocs+">");
+ out.println("SMPDeviceImpl "+Thread.currentThread() +"time"+
+ System.currentTimeMillis() +"numRegistered"+
+ numRegisteredThreads );
+ */
+ if (initialized) {
+ throw new XDevException("Call to SMPDeviceImpl.init() after MPJ has " +
+ "already been successfully initialized");
+ }
+
+ if (nprocs < 0) {
+ throw new XDevException("In SMPDeviceImpl.init(), requested negative " +
+ "world size " + nprocs);
+ } else if (numRegisteredThreads == 0) {
+
+ WORLD.size = nprocs;
+
+ WORLD.pids = new ProcessID[WORLD.size];
+ WORLD.threads = new Thread[WORLD.size];
+ WORLD.ids = new HashMap();
+
+ WORLD.context = 0;
+ nextContext = 1;
+
+ WORLD.barrierCount = 0;
+
+ } else if (nprocs != WORLD.size) {
+ throw new XDevException("In SMPDeviceImpl.init(), mismatch in number of " +
+ "nodes requested by threads: " +
+ WORLD.size + " vs " + nprocs);
+ }
+
+ /*
+ if(myId < 0) {
+ throw new XDevException("In SMPDeviceImpl.init(), requested negative " +
+ "node id, " + myId) ;
+ }
+ else if(myId >= WORLD.size) {
+ throw new XDevException("In SMPDeviceImpl.init(), requested node id, " +
+ myId + " is too large for requested " +
+ "world size, " + WORLD.size) ;
+ }
+ */
+ Thread thread = Thread.currentThread();
+
+ if (WORLD.threads[rank] != null) {
+
+// System.out.println("Current thread caused exception is "+Thread.currentThread());
+
+ throw new XDevException("In SMPDeviceImpl.init(), requested node id, " +
+ rank + " has already been registered");
+ } else {
+
+
+ UUID myuuid = UUID.randomUUID();
+ //WORLD.id = new ProcessID(myuuid, rank);
+ //FIXME: is there any effect of not having `rank'
+ WORLD.id = new ProcessID(myuuid);
+ WORLD.pids[rank] = WORLD.id;
+ smpProcess = (SMPDevProcess)thread.getThreadGroup();
+ smpProcess.setProcessID(WORLD.id);
+
+ WORLD.threads[rank] = thread;
+ //WORLD.ids.put(thread, new Integer(myId)) ;
+ //System.out.println("ids.put(thread) has thread value = "+thread.getId()+" and thread.getContextClassLoader() = "+thread.getContextClassLoader().toString());
+ //WORLD.ids.put(thread.getContextClassLoader(), WORLD.id);
+
+
+ /* out.println("SMPDeviceImpl "+Thread.currentThread() +"time"+
+ System.currentTimeMillis() +"numRegistered"+
+ numRegisteredThreads);
+ */
+
+ numRegisteredThreads++;
+
+
+ /* out.println("SMPDeviceImpl "+Thread.currentThread() +"time"+
+ System.currentTimeMillis() +"numRegistered"+
+ numRegisteredThreads);
+ out.println("WORLD.size "+WORLD.size);
+ */
+ if (numRegisteredThreads == WORLD.size) {
+
+ initialized = true;
+ // System.out.println(" || notifying wait <"+rank+">");
+ // out.println("notifying wait <"+rank+">");
+ SMPDeviceImpl.class.notifyAll();
+
+ } else {
+ try {
+
+ // out.println("calling wait (init) <"+rank+">");
+ SMPDeviceImpl.class.wait();
+ // out.println("called wait (init) <"+rank+">");
+ // System.out.println(" || called wait (init) <"+rank+">");
+ } catch (InterruptedException e) {
+ throw new XDevException("In SMPDeviceImpl.init(), unexpected " +
+ "interuption during wait()??");
+ }
+ } //end else
+ } //end else
+// out.println("Last call to SMPDeviceImpl.init() <"+rank+">");
+ return WORLD.pids;
+ //TTD:- it may throw a null pointer exception ..
+ }//end init()
+
+ /**
+ * Finalize MPI.
+ * <p>
+ * Java binding of the MPI operation <tt>MPI_FINALIZE</tt>.
+ */
+ public synchronized static void finish() throws XDevException {
+ // out.println("Finish method Called");
+// System.out.println("finished called");
+ // Need to clean up properly, so applets can be restarted.
+
+ // Check current thread belongs to this communicator
+
+ //if (WORLD.ids.get(Thread.currentThread()) == null) {
+ if(!(Thread.currentThread().getThreadGroup()
+ instanceof SMPDevProcess)) {
+ //if (WORLD.ids.get(Thread.currentThread().getContextClassLoader())
+ // == null) {
+ throw new XDevException("SMPDeviceImpl.finish() invoked by thread " +
+ "outside MPJ world");
+ }
+
+ numRegisteredThreads--;
+
+ if (numRegisteredThreads == 0) {
+
+ // Reset MPJ initialized status and wake up other threads.
+
+ initialized = false;
+
+ SMPDeviceImpl.class.notifyAll();
+ } else {
+
+ try {
+ SMPDeviceImpl.class.wait();
+ } catch (InterruptedException e) {
+ throw new XDevException("In SMPDeviceImpl.finish(), unexpected " +
+ "interuption during wait()??");
+ }
+ }
+ }
+ /**
+ * Equivalent of MPI_ANY_SOURCE.
+ * May be passed as `src' argument of `recv' or `irecv'.
+ */
+ public static final int ANY_SOURCE = -2;
+ //OK this null is throwing exception
+ public static final ProcessID ANY_SRC =
+ //new ProcessID(UUID.randomUUID(), -2);
+ new ProcessID(UUID.randomUUID());
+ /**
+ * Equivalent of MPI_ANY_TAG.
+ * May be passed as `tag' argument of `recv' or `irecv'.
+ */
+ public static final int ANY_TAG = -1;
+ /**
+ * The initial communicator.
+ * Equivalent of MPI_COMM_WORLD.
+ */
+ public static final SMPDeviceImpl WORLD = new SMPDeviceImpl();
+ static int MAX_PROCESSOR_NAME = 256;
+ long handle;
+
+ //private static native void init();
+ static class RecvQueue {
+
+ /**
+ * Add a `SMPRecvRequest' to the front of the queue associated with
+ * its key.
+ */
+ public void add(SMPRecvRequest recv) {
+
+ add(recv.key, recv);
+ }
+
+ /**
+ * Remove from its queue the next `SMPRecvRequest'
+ * that matches one of the keys in `send'.
+ */
+ public SMPRecvRequest rem(SMPSendRequest send) {
+
+ SMPRecvRequest matchingRecv = null;
+
+ Key[] keys = send.keys;
+
+ long minSequenceNum = Long.MAX_VALUE;
+ for (int i = 0; i < keys.length; i++) {
+ SMPRecvRequest recv = get(keys[i]);
+ if (recv != null && recv.sequenceNum < minSequenceNum) {
+ minSequenceNum = recv.sequenceNum;
+ matchingRecv = recv;
+ }
+ // System.out.println("Remove keys -- " + send.hashCode());
+ // keys[i].tostring();
+
+ }
+
+ if (matchingRecv != null) {
+ rem(matchingRecv.key, matchingRecv);
+ }
+
+ return matchingRecv;
+ }
+
+ private SMPRecvRequest get(Key key) {
+
+ return (SMPRecvRequest) map.get(key);
+ }
+
+ private void add(Key key, SMPRecvRequest recv) {
+
+ SMPRecvRequest head = (SMPRecvRequest) map.get(key);
+
+ if (head == null) {
+ recv.next = recv;
+ recv.prev = recv;
+
+ map.put(key, recv);
+ } else {
+ SMPRecvRequest last = head.prev;
+
+ last.next = recv;
+ head.prev = recv;
+
+ recv.prev = last;
+ recv.next = head;
+ }
+ }
+
+ private void rem(Key key, SMPRecvRequest recv) {
+
+ SMPRecvRequest head = (SMPRecvRequest) map.get(key);
+
+ if (recv == head) {
+ if (recv.next == recv) {
+
+ // Unique entry.
+
+ map.remove(key);
+ } else {
+ SMPRecvRequest next = recv.next;
+ SMPRecvRequest last = recv.prev;
+
+ last.next = next;
+ next.prev = last;
+
+ map.put(key, next);
+ }
+ } else {
+ SMPRecvRequest next = recv.next;
+ SMPRecvRequest prev = recv.prev;
+
+ prev.next = next;
+ next.prev = prev;
+ }
+ }
+
+
+
+ private HashMap map = new HashMap();
+ }
+
+ static class SendQueue {
+
+ /**
+ * Add a `SendRequest' to the front of the queues associated with
+ * its keys.
+ */
+ public void add(SMPSendRequest send) {
+
+ Key[] keys = send.keys;
+
+ for (int i = 0; i < keys.length; i++) {
+ add(i, keys[i], send);
+
+//keys[i].tostring();
+ }
+ }
+
+ private void add(int i, Key key, SMPSendRequest send) {
+ SMPSendRequest head = (SMPSendRequest) map.get(key);
+ // SMPDeviceImpl.out.println("got the sort of head <"+head+">");
+ if (head == null) {
+ // SMPDeviceImpl.out.println("creating the first element in the queues");
+ //SMPDeviceImpl.out.println("..");
+// SMPDeviceImpl.out.println("map "+map);
+// SMPDeviceImpl.out.println(".... keys ....");
+// SMPDeviceImpl.out.println("send "+send);
+ send.next[i] = send;
+ send.prev[i] = send;
+ map.put(key, send);
+ } else {
+ // SMPDeviceImpl.out.println("managing ds coz head is still there ...");
+ SMPSendRequest last = head.prev[i];
+ last.next[i] = send;
+ head.prev[i] = send;
+ send.prev[i] = last;
+ send.next[i] = head;
+ }
+ }
+
+ /**
+ * Remove from its queues the next `SMPSendRequest' that matches the
+ * key in `recv'.
+ */
+ public SMPSendRequest rem(SMPRecvRequest recv) {
+// SMPDeviceImpl.out.println("rem method ...");
+// SMPDeviceImpl.out.println(".... keys ....");
+// SMPDeviceImpl.out.println("map "+map);
+ // SMPDeviceImpl.out.println(".... keys ....");
+ // SMPDeviceImpl.out.println("recv "+recv);
+ // SMPDeviceImpl.out.println("recv.key "+recv.key);
+ SMPSendRequest matchingSend = get(recv.key);
+// SMPDeviceImpl.out.println("matchingSend "+matchingSend);
+ if (matchingSend != null) {
+ Key[] keys = matchingSend.keys;
+ for (int i = 0; i < keys.length; i++) {
+ rem(i, keys[i], matchingSend);
+ }
+ }
+ return matchingSend;
+ }
+
+ private SMPSendRequest get(Key key) {
+ return (SMPSendRequest) map.get(key);
+ }
+
+ private void rem(int i, Key key, SMPSendRequest send) {
+ SMPSendRequest head = (SMPSendRequest) map.get(key);
+ if (send == head) {
+ if (send.next[i] == send) {
+ // Unique entry.
+ map.remove(key);
+ } else {
+ SMPSendRequest next = send.next[i];
+ SMPSendRequest last = send.prev[i];
+ last.next[i] = next;
+ next.prev[i] = last;
+ map.put(key, next);
+ }
+ } else {
+ SMPSendRequest next = send.next[i];
+ SMPSendRequest prev = send.prev[i];
+ prev.next[i] = next;
+ next.prev[i] = prev;
+ }
+ }
+
+ SMPSendRequest check(int context, ProcessID destID, ProcessID srcID, int tag) {
+ Key key = new Key(context, destID, srcID, tag);
+
+ return (SMPSendRequest)map.get(key);
+
+ }
+
+
+ private HashMap map = new HashMap();
+ }
+
+ static class Key {
+
+ private int context, tag;
+ private ProcessID destID, srcID;
+
+ Key(int context, ProcessID destID, ProcessID srcID, int tag) {
+
+ this.context = context;
+ this.destID = destID;
+ this.srcID = srcID;
+ this.tag = tag;
+ }
+/*
+ Key(int context, ProcessID srcID, int tag) {
+
+ this.context = context;
+ this.srcID = srcID;
+ this.tag = tag;
+ }
+*/
+ // Typically the fields (except possibly `tag') will be small integers.
+ // There's no particular rationale to this formula, but maybe it
+ // gives a reasonable scatter...
+ public int hashCode() {
+ return -1;
+ //return tag + context * 5 + dest * 11 + source * 17 ;
+
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof Key) {
+ Key other = (Key) obj;
+
+//System.out.println(" other.destID.uuid() "+other.destID.uuid());
+//System.out.println(" destID.uuid() "+destID.uuid());
+//System.out.println(" other.srcID.uuid() "+other.srcID.uuid());
+//System.out.println(" srcID.uuid() "+srcID.uuid());
+
+ return (other.context == context) &&
+ (other.destID.uuid().equals(destID.uuid())) &&
+ (other.srcID.uuid().equals(srcID.uuid())) &&
+ (other.tag == tag);
+ }
+ return false;
+ }
+
+ public void tostring() {
+ System.out.println("Context " + context + " Tag " + tag + " srcID " + srcID.uuid());
+ }
+ }
+}
+
+
diff --git a/src/xdev/smpdev/SMPRecvRequest.java b/src/xdev/smpdev/SMPRecvRequest.java
new file mode 100644
index 0000000..9e7d9a0
--- /dev/null
+++ b/src/xdev/smpdev/SMPRecvRequest.java
@@ -0,0 +1,71 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/*
+ * File : SMPRecvRequest.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Fri Nov 15 21:19:37 EST 2002
+ * Revision : $Revision: 1.2 $
+ * Updated : $Date: 2005/03/24 10:49:51 $
+ */
+
+package xdev.smpdev;
+
+import xdev.ProcessID;
+
+public class SMPRecvRequest extends SMPRequest {
+
+ // Hash table key for queue in which receive request may be placed,
+ // or in which matching send request may be found.
+ SMPDeviceImpl.Key key ;
+
+ // Link fields for queue in which request may be placed.
+ // Next entry in queue.
+ SMPRecvRequest next ;
+
+ // Previous entry in queue, (or final entry in queue, if this request
+ // is at front of queue).
+ SMPRecvRequest prev ;
+
+ long sequenceNum ;
+
+ private static long nextSequenceNum = 0 ;
+
+ SMPRecvRequest(mpjbuf.Buffer buf, int context, ProcessID destID,
+ ProcessID sourceID, int tag, mpjdev.Status status) {
+//System.out.println("Overloaded constructor called in SMPRecvRequest "+this.hashCode());
+ completed = false;
+ //this.status = status;
+/* SMPDeviceImpl.out.println(" initializing the keys of SMPRecvRequest");
+ SMPDeviceImpl.out.println(" context "+context );
+ SMPDeviceImpl.out.println(" destID "+destID );
+ SMPDeviceImpl.out.println(" sourceID "+sourceID );
+ SMPDeviceImpl.out.println(" tag "+tag );
+*/
+ key = new SMPDeviceImpl.Key(context, destID, sourceID, tag) ;
+ // key = new SMPDeviceImpl.Key(context, sourceID, tag) ;
+ //this.rank_source = sourceID.rank();
+ this.buffer = buf ;
+ this.dynamicBuffer = buf.getDynamicBuffer();
+ this.status = status;
+ this.srcID = sourceID;
+ synchronized(SMPRecvRequest.class) {
+ sequenceNum = nextSequenceNum++ ;
+ }
+ }
+}
+
diff --git a/src/xdev/smpdev/SMPRequest.java b/src/xdev/smpdev/SMPRequest.java
new file mode 100644
index 0000000..8708e35
--- /dev/null
+++ b/src/xdev/smpdev/SMPRequest.java
@@ -0,0 +1,316 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SMPRequest.java
+ * Author : Sang Lim, Aamir Shafi
+ * Created : Thu Jan 17 17:17:40 2002
+ * Revision : $Revision: 1.4 $
+ * Updated : $Date: 2005/06/23 12:43:29 $
+ */
+/**
+ * Request object for non-blocking communications.
+ */
+package xdev.smpdev;
+
+import mpi.*;
+import mpjdev.Status;
+import mpjdev.Request;
+import mpjbuf.Buffer;
+import xdev.XDevException;
+import xdev.ProcessID;
+import mpjbuf.RawBuffer;
+import java.nio.*;
+import java.util.UUID;
+
+public class SMPRequest extends mpjdev.Request {
+
+
+ int context = -1, tag, numEls = -1;
+ mpjbuf.Type type = null;
+ ProcessID srcID;
+ // added variable for the peek method
+ SMPRequest nextCompleted, prevCompleted;
+ boolean inCompletedList;
+ boolean dSection = true, sSection = true;
+ int commMode, rank_source = 0, sBufSize = 0, dBufSize = 0;
+ RawBuffer eagerBuffer = null;
+ byte[] dynamicBuffer = null;
+ ByteBuffer staticBuffer;
+ int sendCounter;
+ mpjbuf.Buffer buffer;
+ mpjdev.Status status=null;// jd
+
+ /**
+ * Wait for a single non-blocking communication to complete.
+ * If this was a receive, initializes the `source' and `tag' fields
+ * of the returned status object.
+ * Equivalent to MPI_WAIT.
+ */
+ public SMPRequest() {
+//System.out.println("Default constructor called in SMPRequest "+this.hashCode());
+ }
+
+ public mpjdev.Status iwait() throws XDevException {
+
+ /* why is this returning null?! */
+ if (completed) {
+//System.out.println("Returning null from -- iwait ");
+ // return null;
+ return this.status;
+ }
+
+
+ WaitSet waiting = null;
+
+ synchronized (SMPDeviceImpl.class) {
+ if (isPending()) {
+ // System.out.println("isPending Status "+ this.hashCode());
+ waiting = new WaitSet(new SMPRequest[]{this});
+ }
+ }
+
+ if (waiting != null) {
+
+ try {
+ // System.out.println("awaiting selection "+ this.hashCode());
+ waiting.awaitSelection();
+ } catch (InterruptedException e) {
+ // Should use `cause', but not sure if everybody is using 1.4
+ throw new XDevException("In iwait, unexpected " +
+ "InterruptedException: " + e.getMessage());
+ }
+ }
+ // complete(new mpjdev.Status(status));
+//System.out.println("calling complete "+ this.hashCode());
+ // System.out.println("-- 2 Status "+ status.srcID +" "+status.tag);
+
+
+ complete(status);
+ completed = true;
+
+ status.numEls = this.numEls ;
+ status.type = this.type ;
+
+//System.out.println("Returning status from -- iwait "+ this.hashCode());
+ return this.status;
+
+ }
+
+ /**
+ * Wait for one non-blocking communication from a set to complete.
+ * The `index' field of the returned status object defines which
+ * communication in the `reqs' array was selected.
+ * If this was a receive, the `source' and `tag' fields
+ * of the returned status object are also initialized.
+ * Equivalent to MPI_WAITANY.
+ */
+ public static mpjdev.Status iwaitany(SMPRequest[] reqs) throws XDevException {
+//System.out.println("Inide iwaitany");
+ boolean empty = true;
+ SMPRequest selected = null;
+ WaitSet waiting = null;
+
+ synchronized (SMPDeviceImpl.class) {
+
+ for (int i = 0; i < reqs.length; i++) {
+ SMPRequest req = reqs[i];
+ if (req == null) {
+ throw new XDevException("In iwaitany, requests array " +
+ "contains a null element");
+ } else if (!req.completed) {
+ empty = false;
+ if (!req.isPending()) {
+ req.status.index = i;
+ selected = req;
+ break;
+ }
+ }
+ }
+
+ if (empty) {
+ return null;
+ }
+
+ if (selected == null) {
+ waiting = new WaitSet(reqs);
+ }
+ }
+
+ if (waiting != null) {
+ try {
+
+ selected = waiting.awaitSelection();
+ } catch (InterruptedException e) {
+ // Should use `cause', but not sure if everybody is using 1.4
+ throw new XDevException("In iwaitany, unexpected " +
+ "InterruptedException: " + e.getMessage());
+ }
+ }
+
+ selected.completed = true;
+
+ //Should be changed... should remove 'MPI_REQUEST_NULL'
+
+ reqs[selected.status.index] = MPI_REQUEST_NULL;
+
+ return selected.status;
+ }
+ // The `pending' flag is cleared after a send (respectively receive)
+ // matching this receive (respectively send) request has been posted.
+ private boolean pending = false;
+
+ void setPending(boolean pending) {
+
+ this.pending = pending;
+ }
+
+ boolean isPending() {
+
+ return pending;
+ }
+ // The `completed' flag is set after successful completion of an
+ // `iwait' on this request, or succesful completion of an `iwaitany'
+ // selecting this request.
+ boolean completed = true;
+ private WaitSet waitSet;
+
+ void addToWaitSet(WaitSet waitSet, int index) {
+
+ this.waitSet = waitSet;
+
+ status.index = index;
+ }
+
+ public boolean cancel() {
+ return false;
+ }
+
+ public void free() {
+ }
+
+ public boolean isnull() {
+ return false;
+ }
+
+ public mpjdev.Status itest() {
+ if (completed) {
+ return null;
+ }
+ synchronized (this) {
+ // System.out.println("is pending? "+this.isPending());
+ if (!this.isPending()) { //jd
+ UUID srcUUID = srcID.uuid();
+ mpjdev.Status st = new mpjdev.Status(srcUUID, tag, -1); //what is index ?
+ // System.out.println("status is null? "+st);
+ return st;
+ }
+ else {
+ // System.out.println("status is null");
+ return null; //change this to something understand at higher levels ...
+ }
+ }
+ }
+ /*
+ public mpjdev.Status itest() {
+ return null;
+ }
+ */
+
+ void removeFromWaitSet() {
+ waitSet = null;
+ }
+
+ WaitSet getWaitSet() {
+ return waitSet;
+ }
+
+ /**
+ * Not sure what this is exactly. It's like the requests are channels
+ * and the "WaitSet" is an alternation---sort of, but not quite.
+ * There is probably a cleaner abstraction lurking here somewhere.
+ */
+ static class WaitSet {
+
+ private Semaphore sem;
+ SMPRequest reqs[];
+ SMPRequest selected;
+
+ /**
+ * Create a "wait set" containing specified requests.
+ */
+ public WaitSet(SMPRequest[] reqs) {
+
+ sem = new Semaphore(0);
+
+ this.reqs = reqs;
+
+ for (int i = 0; i < reqs.length; i++) {
+ reqs[i].addToWaitSet(this, i);
+ }
+ }
+
+ /**
+ * Select an element from the wait set, and clear the set.
+ */
+ void select(SMPRequest req) {
+
+ selected = req;
+
+ for (int i = 0; i < reqs.length; i++) {
+ reqs[i].removeFromWaitSet();
+ }
+
+ sem.signal();
+ }
+
+ /**
+ * Wait for an element of the wait set to be selected.
+ */
+ SMPRequest awaitSelection() throws InterruptedException {
+
+ sem.acquire();
+ // System.out.println("---sem aquired ");
+ return selected;
+ }
+ }
+ public static final SMPRequest MPI_REQUEST_NULL = new SMPRequest();
+}
+
+class Semaphore {
+
+ private int s;
+
+ public Semaphore(int s) {
+ this.s = s;
+ }
+
+ public synchronized void acquire() throws InterruptedException {
+ if (s == 0) {
+//System.out.println("calling wait(0) "+ this.hashCode());
+//new Exception().printStackTrace(System.out);
+ wait(0);
+ }
+ s--;
+ }
+
+ public synchronized void signal() {
+ s++;
+ notify();
+ }
+}
+
diff --git a/src/xdev/smpdev/SMPSendRequest.java b/src/xdev/smpdev/SMPSendRequest.java
new file mode 100644
index 0000000..57edd09
--- /dev/null
+++ b/src/xdev/smpdev/SMPSendRequest.java
@@ -0,0 +1,112 @@
+/*
+The MIT License
+
+ Copyright (c) 2005 - 2010
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Community Grids Laboratory, Indiana University (2004)
+ 3. Aamir Shafi (2005 - 2010)
+ 4. Bryan Carpenter (2005 - 2010)
+ 5. Jawad Manzoor (2009)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File : SMPSendRequest.java
+ * Author : Bryan Carpenter, Aamir Shafi
+ * Created : Thu Nov 14 12:06:35 EST 2002
+ * Revision : $Revision: 1.2 $
+ * Updated : $Date: 2005/03/24 10:49:51 $
+ */
+package xdev.smpdev;
+import mpjbuf.RawBuffer ;
+import xdev.XDevException;
+import mpjbuf.NIOBuffer ;
+import xdev.ProcessID;
+import mpjbuf.RawBuffer ;
+import java.util.UUID;
+
+public class SMPSendRequest extends SMPRequest {
+
+ // 4 hash table keys for queues in which send request may be placed,
+ // or in which matching receive requests may be found.
+ SMPDeviceImpl.Key[] keys;
+
+ // Link fields for 4 queues in which request may be placed.
+
+ // Next entry in queue.
+ SMPSendRequest next[];
+
+ // Previous entry in queue, (or final entry in queue, if this request
+ // is at front of queue).
+ SMPSendRequest prev[];
+ // int tag, context;
+ // ProcessID sourceID;
+int bufoffset = 0;
+
+// constructor of the SMPSendRequest
+ SMPSendRequest(mpjbuf.Buffer buf, int context, ProcessID destID,
+ ProcessID sourceID, int tag) {
+
+ completed = false;
+
+ try {
+ buf.commit();
+ this.type = buf.getSectionHeader();
+ this.numEls = buf.getSectionSize();
+ } catch (Exception e) {
+ throw new XDevException(e);
+ } //jd
+
+ /* SMPDeviceImpl.out.println(" initializing the keys of SMPSendRequest");
+ SMPDeviceImpl.out.println(" context "+context );
+ SMPDeviceImpl.out.println(" destID "+destID );
+ SMPDeviceImpl.out.println(" sourceID "+sourceID );
+ SMPDeviceImpl.out.println(" tag "+tag );
+ */
+ /* keys = new SMPDeviceImpl.Key [] {
+ new SMPDeviceImpl.Key(context, destID, sourceID, tag),
+ new SMPDeviceImpl.Key(context, destID, sourceID, SMPDeviceImpl.ANY_TAG),
+ new SMPDeviceImpl.Key(context, destID, SMPDeviceImpl.ANY_SRC, tag),
+ new SMPDeviceImpl.Key(context, destID, SMPDeviceImpl.ANY_SRC, SMPDeviceImpl.ANY_TAG)
+ } ;
+*/
+
+ keys = new SMPDeviceImpl.Key[]{
+ new SMPDeviceImpl.Key(context,destID, sourceID, tag),
+ new SMPDeviceImpl.Key(context, destID,sourceID, SMPDevice.ANY_TAG),
+ new SMPDeviceImpl.Key(context, destID,xdev.Device.ANY_SRC, tag),
+ new SMPDeviceImpl.Key(context, destID,xdev.Device.ANY_SRC, SMPDevice.ANY_TAG)
+ };
+
+/*
+ keys = new SMPDeviceImpl.Key[]{
+ new SMPDeviceImpl.Key(context, sourceID, tag),
+ new SMPDeviceImpl.Key(context, sourceID, SMPDevice.ANY_TAG),
+ new SMPDeviceImpl.Key(context, xdev.Device.ANY_SRC, tag),
+ new SMPDeviceImpl.Key(context, xdev.Device.ANY_SRC, SMPDevice.ANY_TAG)
+ };
+*/
+ next = new SMPSendRequest[4];
+ prev = new SMPSendRequest[4];
+
+ this.buffer = buf;
+ // this.sourceID = sourceID;
+ this.tag = tag;
+ this.context = context;
+ this.srcID = sourceID;
+ this.sBufSize = buf.getSize();
+ this.staticBuffer = ((NIOBuffer) buf.getStaticBuffer()).getBuffer();
+
+ // this.commMode = commMode;
+ // this.sendCounter = sendCounter;
+ this.bufoffset = buf.offset();
+ UUID srcUUID = sourceID.uuid();
+ this.status = new mpjdev.Status(srcUUID, tag, -1); //jd
+ }
+}
+
diff --git a/src/xdev/smpdev/init_smp.java b/src/xdev/smpdev/init_smp.java
new file mode 100644
index 0000000..9cfac5d
--- /dev/null
+++ b/src/xdev/smpdev/init_smp.java
@@ -0,0 +1,43 @@
+
+package xdev.smpdev;
+
+import mpjdev.*;
+import xdev.*;
+import mpjbuf.*;
+import java.util.Arrays;
+
+public class init_smp {
+ public static void main(String args[]) throws Exception{
+ Device dev = new xdev.smpdev.SMPDevice();
+ long t1 = System.nanoTime();
+xdev.ProcessID [] ids ;
+
+ try{
+ ids = dev.init(args);
+
+ xdev.ProcessID myID = dev.id();
+
+ if(Integer.parseInt(args[1]) == 0) { // i have changed from args[0] to args[1]
+ System.out.print("\n"+args[0]+">su-time<"+(System.nanoTime()-t1)/(1000*1000*1000)+">");
+ System.out.println("myID "+myID);
+ System.out.println("rank "+args[0]);
+ System.out.println("uuid "+myID.uuid());
+
+ for(int i=0 ; i<ids.length ; i++) {
+ System.out.println("\n -----<"+i+">------");
+ System.out.print("ids["+i+"]=>"+ids[i]+"\t");
+ System.out.println("uuid "+ids[i].uuid());
+ }
+ }
+ dev.finish();
+
+ }catch (Exception ee) {
+
+ System.out.println("here is the exception in init_smp");
+ ee.printStackTrace();
+ }
+
+
+ }
+}
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/mpj.git
More information about the pkg-java-commits
mailing list