1 /* 2 * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana 3 * University Research and Technology 4 * Corporation. All rights reserved. 5 * Copyright (c) 2004-2005 The University of Tennessee and The University 6 * of Tennessee Research Foundation. All rights 7 * reserved. 8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 9 * University of Stuttgart. All rights reserved. 10 * Copyright (c) 2004-2005 The Regents of the University of California. 11 * All rights reserved. 12 * Copyright (c) 2015 Los Alamos National Security, LLC. All rights 13 * reserved. 14 * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved. 15 * $COPYRIGHT$ 16 * 17 * Additional copyrights may follow 18 * 19 * $HEADER$ 20 * 21 * 22 * This file is almost a complete re-write for Open MPI compared to the 23 * original mpiJava package. Its license and copyright are listed below. 24 * See <path to ompi/mpi/java/README> for more information. 25 * 26 * 27 * Licensed under the Apache License, Version 2.0 (the "License"); 28 * you may not use this file except in compliance with the License. 29 * You may obtain a copy of the License at 30 * 31 * http://www.apache.org/licenses/LICENSE-2.0 32 * 33 * Unless required by applicable law or agreed to in writing, software 34 * distributed under the License is distributed on an "AS IS" BASIS, 35 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 * See the License for the specific language governing permissions and 37 * limitations under the License. 38 * 39 * 40 * File : MPI.java 41 * Author : Sang Lim, Sung-Hoon Ko, Xinying Li, Bryan Carpenter 42 * (contributions from MAEDA Atusi) 43 * Created : Thu Apr 9 12:22:15 1998 44 * Revision : $Revision: 1.18 $ 45 * Updated : $Date: 2003/01/16 16:39:34 $ 46 * Copyright: Northeast Parallel Architectures Center 47 * at Syracuse University 1998 48 */ 49 package mpi; 50 51 import java.io.*; 52 import java.nio.*; 53 54 /** 55 * MPI environment. 56 */ 57 public final class MPI 58 { 59 private static boolean initialized, finalized; 60 private static byte[] buffer = null; // Buffer allocation 61 private static final int MAX_PROCESSOR_NAME = 256; 62 private static final ByteOrder nativeOrder = ByteOrder.nativeOrder(); 63 64 public static final Intracomm COMM_WORLD, COMM_SELF; 65 66 public static final int THREAD_SINGLE, THREAD_FUNNELED, THREAD_SERIALIZED, 67 THREAD_MULTIPLE; 68 69 public static final int GRAPH, DIST_GRAPH, CART; 70 public static final int ANY_SOURCE, ANY_TAG; 71 72 public static final Op MAX, MIN, SUM, PROD, LAND, BAND, 73 LOR, BOR, LXOR, BXOR, REPLACE, NO_OP; 74 75 /** 76 * Global minimum operator. 77 * <p>{@code MINLOC} and {@link #MAXLOC} can be used with each of the following 78 * datatypes: {@link #INT2}, {@link #SHORT_INT}, {@link #LONG_INT}, 79 * {@link #FLOAT_INT} and {@link #DOUBLE_INT}. 80 */ 81 public static final Op MINLOC; 82 83 /** Global maximum operator. See {@link #MINLOC}.*/ 84 public static final Op MAXLOC; 85 86 public static final Datatype DATATYPE_NULL; 87 88 public static final Datatype BYTE, CHAR, SHORT, BOOLEAN, 89 INT, LONG, FLOAT, DOUBLE, PACKED, 90 FLOAT_COMPLEX, DOUBLE_COMPLEX; 91 92 /** Struct which must be used with {@link #int2}. */ 93 public static final Datatype INT2; 94 /** Struct which must be used with {@link #shortInt}. */ 95 public static final Datatype SHORT_INT; 96 /** Struct which must be used with {@link #longInt}. */ 97 public static final Datatype LONG_INT; 98 /** Struct which must be used with {@link #floatInt}. */ 99 public static final Datatype FLOAT_INT; 100 /** Struct which must be used with {@link #doubleInt}. */ 101 public static final Datatype DOUBLE_INT; 102 103 /** Struct object for {@link #INT2} datatype. */ 104 public static final Int2 int2; 105 /** Struct object for {@link #SHORT_INT} datatype. */ 106 public static final ShortInt shortInt; 107 /** Struct object for {@link #LONG_INT} datatype. */ 108 public static final LongInt longInt; 109 /** Struct object for {@link #FLOAT_INT} datatype. */ 110 public static final FloatInt floatInt; 111 /** Struct object for {@link #DOUBLE_INT} datatype. */ 112 public static final DoubleInt doubleInt; 113 114 public static final Request REQUEST_NULL; 115 public static final Group GROUP_EMPTY; 116 public static final Info INFO_ENV, INFO_NULL; 117 118 public static final int PROC_NULL; 119 public static final int UNDEFINED; 120 public static final int IDENT, CONGRUENT, SIMILAR, UNEQUAL; 121 public static final int TAG_UB, HOST, IO, WTIME_IS_GLOBAL; 122 123 public static final int APPNUM, LASTUSEDCODE, UNIVERSE_SIZE, WIN_BASE, 124 WIN_SIZE, WIN_DISP_UNIT; 125 126 public static final int VERSION, SUBVERSION; 127 public static final int ROOT, KEYVAL_INVALID, BSEND_OVERHEAD; 128 public static final int MAX_OBJECT_NAME, MAX_PORT_NAME, MAX_DATAREP_STRING; 129 public static final int MAX_INFO_KEY, MAX_INFO_VAL; 130 public static final int ORDER_C, ORDER_FORTRAN; 131 public static final int DISTRIBUTE_BLOCK, DISTRIBUTE_CYCLIC, DISTRIBUTE_NONE, 132 DISTRIBUTE_DFLT_DARG; 133 134 public static final int MODE_CREATE, MODE_RDONLY, MODE_WRONLY, MODE_RDWR, 135 MODE_DELETE_ON_CLOSE, MODE_UNIQUE_OPEN, MODE_EXCL, 136 MODE_APPEND, MODE_SEQUENTIAL; 137 public static final int DISPLACEMENT_CURRENT; 138 public static final int SEEK_SET, SEEK_CUR, SEEK_END; 139 140 public static final int MODE_NOCHECK, MODE_NOPRECEDE, MODE_NOPUT, 141 MODE_NOSTORE, MODE_NOSUCCEED; 142 public static final int LOCK_EXCLUSIVE, LOCK_SHARED; 143 144 public static final Errhandler ERRORS_ARE_FATAL, ERRORS_RETURN; 145 146 // Error classes and codes 147 public static final int SUCCESS; 148 public static final int ERR_BUFFER; 149 public static final int ERR_COUNT; 150 public static final int ERR_TYPE; 151 public static final int ERR_TAG; 152 public static final int ERR_COMM; 153 public static final int ERR_RANK; 154 public static final int ERR_REQUEST; 155 public static final int ERR_ROOT; 156 public static final int ERR_GROUP; 157 public static final int ERR_OP; 158 public static final int ERR_TOPOLOGY; 159 public static final int ERR_DIMS; 160 public static final int ERR_ARG; 161 public static final int ERR_UNKNOWN; 162 public static final int ERR_TRUNCATE; 163 public static final int ERR_OTHER; 164 public static final int ERR_INTERN; 165 public static final int ERR_IN_STATUS; 166 public static final int ERR_PENDING; 167 public static final int ERR_ACCESS; 168 public static final int ERR_AMODE; 169 public static final int ERR_ASSERT; 170 public static final int ERR_BAD_FILE; 171 public static final int ERR_BASE; 172 public static final int ERR_CONVERSION; 173 public static final int ERR_DISP; 174 public static final int ERR_DUP_DATAREP; 175 public static final int ERR_FILE_EXISTS; 176 public static final int ERR_FILE_IN_USE; 177 public static final int ERR_FILE; 178 public static final int ERR_INFO_KEY; 179 public static final int ERR_INFO_NOKEY; 180 public static final int ERR_INFO_VALUE; 181 public static final int ERR_INFO; 182 public static final int ERR_IO; 183 public static final int ERR_KEYVAL; 184 public static final int ERR_LOCKTYPE; 185 public static final int ERR_NAME; 186 public static final int ERR_NO_MEM; 187 public static final int ERR_NOT_SAME; 188 public static final int ERR_NO_SPACE; 189 public static final int ERR_NO_SUCH_FILE; 190 public static final int ERR_PORT; 191 public static final int ERR_QUOTA; 192 public static final int ERR_READ_ONLY; 193 public static final int ERR_RMA_CONFLICT; 194 public static final int ERR_RMA_SYNC; 195 public static final int ERR_SERVICE; 196 public static final int ERR_SIZE; 197 public static final int ERR_SPAWN; 198 public static final int ERR_UNSUPPORTED_DATAREP; 199 public static final int ERR_UNSUPPORTED_OPERATION; 200 public static final int ERR_WIN; 201 public static final int ERR_LASTCODE; 202 public static final int ERR_SYSRESOURCE; 203 204 static 205 { 206 System.loadLibrary("mpi_java"); 207 208 DATATYPE_NULL = new Datatype(); 209 210 BYTE = new Datatype(); 211 CHAR = new Datatype(); 212 SHORT = new Datatype(); 213 BOOLEAN = new Datatype(); 214 INT = new Datatype(); 215 LONG = new Datatype(); 216 FLOAT = new Datatype(); 217 DOUBLE = new Datatype(); 218 PACKED = new Datatype(); 219 INT2 = new Datatype(); 220 221 SHORT_INT = new Datatype(); 222 LONG_INT = new Datatype(); 223 FLOAT_INT = new Datatype(); 224 DOUBLE_INT = new Datatype(); 225 FLOAT_COMPLEX = new Datatype(); 226 DOUBLE_COMPLEX = new Datatype(); 227 228 int2 = newInt2(); 229 shortInt = newShortInt(); 230 longInt = newLongInt(); 231 floatInt = newFloatInt(); 232 doubleInt = newDoubleInt(); 233 234 MAX = new Op(1); 235 MIN = new Op(2); 236 SUM = new Op(3); 237 PROD = new Op(4); 238 LAND = new Op(5); 239 BAND = new Op(6); 240 LOR = new Op(7); 241 BOR = new Op(8); 242 LXOR = new Op(9); 243 BXOR = new Op(10); 244 MINLOC = new Op(11); 245 MAXLOC = new Op(12); 246 REPLACE = new Op(13); 247 NO_OP = new Op(14); 248 249 GROUP_EMPTY = new Group(Group.getEmpty()); 250 REQUEST_NULL = new Request(Request.getNull()); 251 INFO_ENV = Info.newEnv(); 252 INFO_NULL = new Info(Info.NULL); 253 254 Constant c = new Constant(); 255 256 THREAD_SINGLE = c.THREAD_SINGLE; 257 THREAD_FUNNELED = c.THREAD_FUNNELED; 258 THREAD_SERIALIZED = c.THREAD_SERIALIZED; 259 THREAD_MULTIPLE = c.THREAD_MULTIPLE; 260 261 GRAPH = c.GRAPH; 262 DIST_GRAPH = c.DIST_GRAPH; 263 CART = c.CART; 264 265 ANY_SOURCE = c.ANY_SOURCE; 266 ANY_TAG = c.ANY_TAG; 267 PROC_NULL = c.PROC_NULL; 268 269 UNDEFINED = c.UNDEFINED; 270 271 IDENT = c.IDENT; 272 CONGRUENT = c.CONGRUENT; 273 SIMILAR = c.SIMILAR; 274 UNEQUAL = c.UNEQUAL; 275 276 TAG_UB = c.TAG_UB; 277 HOST = c.HOST; 278 IO = c.IO; 279 WTIME_IS_GLOBAL = c.WTIME_IS_GLOBAL; 280 281 APPNUM = c.APPNUM; 282 LASTUSEDCODE = c.LASTUSEDCODE; 283 UNIVERSE_SIZE = c.UNIVERSE_SIZE; 284 WIN_BASE = c.WIN_BASE; 285 WIN_SIZE = c.WIN_SIZE; 286 WIN_DISP_UNIT = c.WIN_DISP_UNIT; 287 288 VERSION = c.VERSION; 289 SUBVERSION = c.SUBVERSION; 290 291 ROOT = c.ROOT; 292 KEYVAL_INVALID = c.KEYVAL_INVALID; 293 BSEND_OVERHEAD = c.BSEND_OVERHEAD; 294 295 MAX_OBJECT_NAME = c.MAX_OBJECT_NAME; 296 MAX_PORT_NAME = c.MAX_PORT_NAME; 297 MAX_DATAREP_STRING = c.MAX_DATAREP_STRING; 298 299 MAX_INFO_KEY = c.MAX_INFO_KEY; 300 MAX_INFO_VAL = c.MAX_INFO_VAL; 301 302 ORDER_C = c.ORDER_C; 303 ORDER_FORTRAN = c.ORDER_FORTRAN; 304 305 DISTRIBUTE_BLOCK = c.DISTRIBUTE_BLOCK; 306 DISTRIBUTE_CYCLIC = c.DISTRIBUTE_CYCLIC; 307 DISTRIBUTE_NONE = c.DISTRIBUTE_NONE; 308 DISTRIBUTE_DFLT_DARG = c.DISTRIBUTE_DFLT_DARG; 309 310 MODE_CREATE = c.MODE_CREATE; 311 MODE_RDONLY = c.MODE_RDONLY; 312 MODE_WRONLY = c.MODE_WRONLY; 313 MODE_RDWR = c.MODE_RDWR; 314 MODE_DELETE_ON_CLOSE = c.MODE_DELETE_ON_CLOSE; 315 MODE_UNIQUE_OPEN = c.MODE_UNIQUE_OPEN; 316 MODE_EXCL = c.MODE_EXCL; 317 MODE_APPEND = c.MODE_APPEND; 318 MODE_SEQUENTIAL = c.MODE_SEQUENTIAL; 319 320 DISPLACEMENT_CURRENT = c.DISPLACEMENT_CURRENT; 321 322 SEEK_SET = c.SEEK_SET; 323 SEEK_CUR = c.SEEK_CUR; 324 SEEK_END = c.SEEK_END; 325 326 MODE_NOCHECK = c.MODE_NOCHECK; 327 MODE_NOPRECEDE = c.MODE_NOPRECEDE; 328 MODE_NOPUT = c.MODE_NOPUT; 329 MODE_NOSTORE = c.MODE_NOSTORE; 330 MODE_NOSUCCEED = c.MODE_NOSUCCEED; 331 LOCK_EXCLUSIVE = c.LOCK_EXCLUSIVE; 332 LOCK_SHARED = c.LOCK_SHARED; 333 334 ERRORS_ARE_FATAL = new Errhandler(Errhandler.getFatal()); 335 ERRORS_RETURN = new Errhandler(Errhandler.getReturn()); 336 337 COMM_WORLD = new Intracomm(); 338 COMM_SELF = new Intracomm(); 339 340 // Error classes and codes 341 SUCCESS = c.SUCCESS; 342 ERR_BUFFER = c.ERR_BUFFER; 343 ERR_COUNT = c.ERR_COUNT; 344 ERR_TYPE = c.ERR_TYPE; 345 ERR_TAG = c.ERR_TAG; 346 ERR_COMM = c.ERR_COMM; 347 ERR_RANK = c.ERR_RANK; 348 ERR_REQUEST = c.ERR_REQUEST; 349 ERR_ROOT = c.ERR_ROOT; 350 ERR_GROUP = c.ERR_GROUP; 351 ERR_OP = c.ERR_OP; 352 ERR_TOPOLOGY = c.ERR_TOPOLOGY; 353 ERR_DIMS = c.ERR_DIMS; 354 ERR_ARG = c.ERR_ARG; 355 ERR_UNKNOWN = c.ERR_UNKNOWN; 356 ERR_TRUNCATE = c.ERR_TRUNCATE; 357 ERR_OTHER = c.ERR_OTHER; 358 ERR_INTERN = c.ERR_INTERN; 359 ERR_IN_STATUS = c.ERR_IN_STATUS; 360 ERR_PENDING = c.ERR_PENDING; 361 ERR_ACCESS = c.ERR_ACCESS; 362 ERR_AMODE = c.ERR_AMODE; 363 ERR_ASSERT = c.ERR_ASSERT; 364 ERR_BAD_FILE = c.ERR_BAD_FILE; 365 ERR_BASE = c.ERR_BASE; 366 ERR_CONVERSION = c.ERR_CONVERSION; 367 ERR_DISP = c.ERR_DISP; 368 ERR_DUP_DATAREP = c.ERR_DUP_DATAREP; 369 ERR_FILE_EXISTS = c.ERR_FILE_EXISTS; 370 ERR_FILE_IN_USE = c.ERR_FILE_IN_USE; 371 ERR_FILE = c.ERR_FILE; 372 ERR_INFO_KEY = c.ERR_INFO_KEY; 373 ERR_INFO_NOKEY = c.ERR_INFO_NOKEY; 374 ERR_INFO_VALUE = c.ERR_INFO_VALUE; 375 ERR_INFO = c.ERR_INFO; 376 ERR_IO = c.ERR_IO; 377 ERR_KEYVAL = c.ERR_KEYVAL; 378 ERR_LOCKTYPE = c.ERR_LOCKTYPE; 379 ERR_NAME = c.ERR_NAME; 380 ERR_NO_MEM = c.ERR_NO_MEM; 381 ERR_NOT_SAME = c.ERR_NOT_SAME; 382 ERR_NO_SPACE = c.ERR_NO_SPACE; 383 ERR_NO_SUCH_FILE = c.ERR_NO_SUCH_FILE; 384 ERR_PORT = c.ERR_PORT; 385 ERR_QUOTA = c.ERR_QUOTA; 386 ERR_READ_ONLY = c.ERR_READ_ONLY; 387 ERR_RMA_CONFLICT = c.ERR_RMA_CONFLICT; 388 ERR_RMA_SYNC = c.ERR_RMA_SYNC; 389 ERR_SERVICE = c.ERR_SERVICE; 390 ERR_SIZE = c.ERR_SIZE; 391 ERR_SPAWN = c.ERR_SPAWN; 392 ERR_UNSUPPORTED_DATAREP = c.ERR_UNSUPPORTED_DATAREP; 393 ERR_UNSUPPORTED_OPERATION = c.ERR_UNSUPPORTED_OPERATION; 394 ERR_WIN = c.ERR_WIN; 395 ERR_LASTCODE = c.ERR_LASTCODE; 396 ERR_SYSRESOURCE = c.ERR_SYSRESOURCE; 397 initVersion()398 initVersion(); 399 } 400 newInt2()401 private static native Int2 newInt2(); newShortInt()402 private static native ShortInt newShortInt(); newLongInt()403 private static native LongInt newLongInt(); newFloatInt()404 private static native FloatInt newFloatInt(); newDoubleInt()405 private static native DoubleInt newDoubleInt(); initVersion()406 private static native void initVersion(); 407 initCommon()408 private static void initCommon() throws MPIException 409 { 410 initialized = true; 411 412 DATATYPE_NULL.setBasic(Datatype.NULL); 413 414 BYTE.setBasic(Datatype.BYTE); 415 CHAR.setBasic(Datatype.CHAR); 416 SHORT.setBasic(Datatype.SHORT); 417 BOOLEAN.setBasic(Datatype.BOOLEAN); 418 INT.setBasic(Datatype.INT); 419 LONG.setBasic(Datatype.LONG); 420 FLOAT.setBasic(Datatype.FLOAT); 421 DOUBLE.setBasic(Datatype.DOUBLE); 422 PACKED.setBasic(Datatype.PACKED); 423 424 INT2.setBasic(Datatype.INT2, MPI.BYTE); 425 SHORT_INT.setBasic(Datatype.SHORT_INT, MPI.BYTE); 426 LONG_INT.setBasic(Datatype.LONG_INT, MPI.BYTE); 427 FLOAT_INT.setBasic(Datatype.FLOAT_INT, MPI.BYTE); 428 DOUBLE_INT.setBasic(Datatype.DOUBLE_INT, MPI.BYTE); 429 FLOAT_COMPLEX.setBasic(Datatype.FLOAT_COMPLEX, MPI.FLOAT); 430 DOUBLE_COMPLEX.setBasic(Datatype.DOUBLE_COMPLEX, MPI.DOUBLE); 431 432 COMM_WORLD.setType(Intracomm.WORLD); 433 COMM_SELF.setType(Intracomm.SELF); 434 } 435 436 /** 437 * Initialize MPI. 438 * <p>Java binding of the MPI operation {@code MPI_INIT}. 439 * @param args arguments to the {@code main} method. 440 * @return arguments 441 * @throws MPIException Signals that an MPI exception of some sort has occurred. 442 */ Init(String[] args)443 public static String[] Init(String[] args) throws MPIException 444 { 445 if(initialized) 446 throw new MPIException("MPI is already initialized."); 447 448 String[] newArgs = Init_jni(args); 449 initCommon(); 450 return newArgs; 451 } 452 Init_jni(String[] args)453 private static native String [] Init_jni(String[] args); 454 455 /** 456 * Initialize MPI with threads. 457 * <p>Java binding of the MPI operation {@code MPI_INIT_THREAD}. 458 * @param args arguments to the {@code main} method. 459 * @param required desired level of thread support 460 * @return provided level of thread support 461 * @throws MPIException Signals that an MPI exception of some sort has occurred. 462 */ InitThread(String[] args, int required)463 public static int InitThread(String[] args, int required) throws MPIException 464 { 465 if(initialized) 466 throw new MPIException("MPI is already initialized."); 467 468 int provided = InitThread_jni(args, required); 469 initCommon(); 470 return provided; 471 } 472 InitThread_jni(String[] args, int required)473 private static native int InitThread_jni(String[] args, int required) 474 throws MPIException; 475 476 /** 477 * Java binding of the MPI operation {@code MPI_QUERY_THREAD}. 478 * @return provided level of thread support 479 * @throws MPIException Signals that an MPI exception of some sort has occurred. 480 */ queryThread()481 public static int queryThread() throws MPIException 482 { 483 MPI.check(); 484 return queryThread_jni(); 485 } 486 queryThread_jni()487 private static native int queryThread_jni() throws MPIException; 488 489 /** 490 * Java binding of the MPI operation {@code MPI_IS_THREAD_MAIN}. 491 * @return true if it is the main thread 492 * @throws MPIException Signals that an MPI exception of some sort has occurred. 493 */ isThreadMain()494 public static boolean isThreadMain() throws MPIException 495 { 496 MPI.check(); 497 return isThreadMain_jni(); 498 } 499 isThreadMain_jni()500 private static native boolean isThreadMain_jni() throws MPIException; 501 502 /** 503 * Finalize MPI. 504 * <p>Java binding of the MPI operation {@code MPI_FINALIZE}. 505 * @throws MPIException Signals that an MPI exception of some sort has occurred. 506 */ Finalize()507 public static void Finalize() throws MPIException 508 { 509 check(); 510 Finalize_jni(); 511 finalized = true; 512 } 513 Finalize_jni()514 private static native void Finalize_jni() throws MPIException; 515 516 /** 517 * Returns an elapsed time on the calling processor. 518 * <p>Java binding of the MPI operation {@code MPI_WTIME}. 519 * @return time in seconds since an arbitrary time in the past. 520 * @throws MPIException Signals that an MPI exception of some sort has occurred. 521 */ wtime()522 public static double wtime() throws MPIException 523 { 524 check(); 525 return wtime_jni(); 526 } 527 wtime_jni()528 private static native double wtime_jni(); 529 530 /** 531 * Returns resolution of timer. 532 * <p>Java binding of the MPI operation {@code MPI_WTICK}. 533 * @return resolution of {@code wtime} in seconds. 534 * @throws MPIException Signals that an MPI exception of some sort has occurred. 535 */ wtick()536 public static double wtick() throws MPIException 537 { 538 check(); 539 return wtick_jni(); 540 } 541 wtick_jni()542 private static native double wtick_jni(); 543 544 /** 545 * Returns a version object representing the version of MPI being used. 546 * <p>Java binding of the MPI operation {@code MPI_GET_VERSION}. 547 * @return A version object representing the version and subversion of MPI being used. 548 */ getVersion()549 public static Version getVersion() { 550 return getVersionJNI(); 551 } 552 getVersionJNI()553 private static native Version getVersionJNI(); 554 555 /** 556 * Returns the version of the MPI Library 557 * <p>Java binding of the MPI operation {@code MPI_GET_LIBRARY_VERSION}. 558 * @return A string representation of the MPI Library 559 */ getLibVersion()560 public static String getLibVersion() { 561 return getLibVersionJNI(); 562 } 563 getLibVersionJNI()564 private static native String getLibVersionJNI(); 565 566 /** 567 * Returns the name of the processor on which it is called. 568 * <p>Java binding of the MPI operation {@code MPI_GET_PROCESSOR_NAME}. 569 * @return A unique specifier for the actual node. 570 * @throws MPIException Signals that an MPI exception of some sort has occurred. 571 */ getProcessorName()572 static public String getProcessorName() throws MPIException 573 { 574 check(); 575 byte[] buf = new byte[MAX_PROCESSOR_NAME]; 576 int lengh = getProcessorName(buf); 577 return new String(buf,0,lengh); 578 } 579 getProcessorName(byte[] buf)580 static private native int getProcessorName(byte[] buf); 581 582 /** 583 * Test if MPI has been initialized. 584 * <p>Java binding of the MPI operation {@code MPI_INITIALIZED}. 585 * @return {@code true} if {@code Init} has been called, 586 * {@code false} otherwise. 587 * @throws MPIException Signals that an MPI exception of some sort has occurred. 588 */ isInitialized()589 static public native boolean isInitialized() throws MPIException; 590 591 /** 592 * Test if MPI has been finalized. 593 * <p>Java binding of the MPI operation {@code MPI_FINALIZED}. 594 * @return {@code true} if {@code Finalize} has been called, 595 * {@code false} otherwise. 596 * @throws MPIException Signals that an MPI exception of some sort has occurred. 597 */ isFinalized()598 static public native boolean isFinalized() throws MPIException; 599 600 /** 601 * Attaches a user-provided buffer for sending. 602 * <p>Java binding of the MPI operation {@code MPI_BUFFER_ATTACH}. 603 * @param buffer initial buffer 604 * @throws MPIException Signals that an MPI exception of some sort has occurred. 605 */ attachBuffer(byte[] buffer)606 static public void attachBuffer(byte[] buffer) throws MPIException 607 { 608 check(); 609 MPI.buffer = buffer; 610 attachBuffer_jni(buffer); 611 } 612 attachBuffer_jni(byte[] buffer)613 static private native void attachBuffer_jni(byte[] buffer); 614 615 /** 616 * Removes an existing buffer (for use in sending). 617 * <p>Java binding of the MPI operation {@code MPI_BUFFER_DETACH}. 618 * @return initial buffer 619 * @throws MPIException Signals that an MPI exception of some sort has occurred. 620 */ detachBuffer()621 static public byte[] detachBuffer() throws MPIException 622 { 623 check(); 624 detachBuffer_jni(buffer); 625 byte[] result = MPI.buffer; 626 MPI.buffer = null; 627 return result; 628 } 629 detachBuffer_jni(byte[] buffer)630 static private native void detachBuffer_jni(byte[] buffer); 631 632 /** 633 * Controls profiling. 634 * <p>This method is not implemented. 635 * <p>Java binding of the MPI operation {@code MPI_PCONTROL}. 636 * @param level Profiling level. 637 * @param obj Profiling information. 638 */ pControl(int level, Object obj)639 public static void pControl(int level, Object obj) 640 { 641 // Nothing to do here. 642 } 643 644 /** 645 * Check if MPI has been initialized and hasn't been finalized. 646 * @throws MPIException Signals that an MPI exception of some sort has occurred. 647 */ check()648 protected static void check() throws MPIException 649 { 650 if(!initialized) 651 throw new MPIException("MPI is not initialized."); 652 653 if(finalized) 654 throw new MPIException("MPI is finalized."); 655 } 656 attrSet(Object value)657 protected static byte[] attrSet(Object value) throws MPIException 658 { 659 try 660 { 661 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 662 ObjectOutputStream os = new ObjectOutputStream(baos); 663 os.writeObject(value); 664 os.close(); 665 return baos.toByteArray(); 666 } 667 catch(IOException ex) 668 { 669 MPIException mpiex = new MPIException(ex); 670 mpiex.setStackTrace(ex.getStackTrace()); 671 throw mpiex; 672 } 673 } 674 attrGet(byte[] value)675 protected static Object attrGet(byte[] value) throws MPIException 676 { 677 if(value == null) 678 return null; 679 680 try 681 { 682 ByteArrayInputStream bais = new ByteArrayInputStream(value); 683 ObjectInputStream is = new ObjectInputStream(bais); 684 Object obj = is.readObject(); 685 is.close(); 686 return obj; 687 } 688 catch(ClassNotFoundException ex) 689 { 690 throw new MPIException(ex); 691 } 692 catch(IOException ex) 693 { 694 throw new MPIException(ex); 695 } 696 } 697 698 /** 699 * Allocates a new direct byte buffer. 700 * @param capacity The new buffer's capacity, in bytes 701 * @return The new byte buffer 702 */ newByteBuffer(int capacity)703 public static ByteBuffer newByteBuffer(int capacity) 704 { 705 ByteBuffer buf = ByteBuffer.allocateDirect(capacity); 706 buf.order(nativeOrder); 707 return buf; 708 } 709 710 /** 711 * Allocates a new direct char buffer. 712 * @param capacity The new buffer's capacity, in chars 713 * @return The new char buffer 714 */ newCharBuffer(int capacity)715 public static CharBuffer newCharBuffer(int capacity) 716 { 717 assert capacity <= Integer.MAX_VALUE / 2; 718 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 2); 719 buf.order(nativeOrder); 720 return buf.asCharBuffer(); 721 } 722 723 /** 724 * Allocates a new direct short buffer. 725 * @param capacity The new buffer's capacity, in shorts 726 * @return The new short buffer 727 */ newShortBuffer(int capacity)728 public static ShortBuffer newShortBuffer(int capacity) 729 { 730 assert capacity <= Integer.MAX_VALUE / 2; 731 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 2); 732 buf.order(nativeOrder); 733 return buf.asShortBuffer(); 734 } 735 736 /** 737 * Allocates a new direct int buffer. 738 * @param capacity The new buffer's capacity, in ints 739 * @return The new int buffer 740 */ newIntBuffer(int capacity)741 public static IntBuffer newIntBuffer(int capacity) 742 { 743 assert capacity <= Integer.MAX_VALUE / 4; 744 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 4); 745 buf.order(nativeOrder); 746 return buf.asIntBuffer(); 747 } 748 749 /** 750 * Allocates a new direct long buffer. 751 * @param capacity The new buffer's capacity, in longs 752 * @return The new long buffer 753 */ newLongBuffer(int capacity)754 public static LongBuffer newLongBuffer(int capacity) 755 { 756 assert capacity <= Integer.MAX_VALUE / 8; 757 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 8); 758 buf.order(nativeOrder); 759 return buf.asLongBuffer(); 760 } 761 762 /** 763 * Allocates a new direct float buffer. 764 * @param capacity The new buffer's capacity, in floats 765 * @return The new float buffer 766 */ newFloatBuffer(int capacity)767 public static FloatBuffer newFloatBuffer(int capacity) 768 { 769 assert capacity <= Integer.MAX_VALUE / 4; 770 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 4); 771 buf.order(nativeOrder); 772 return buf.asFloatBuffer(); 773 } 774 775 /** 776 * Allocates a new direct double buffer. 777 * @param capacity The new buffer's capacity, in doubles 778 * @return The new double buffer 779 */ newDoubleBuffer(int capacity)780 public static DoubleBuffer newDoubleBuffer(int capacity) 781 { 782 assert capacity <= Integer.MAX_VALUE / 8; 783 ByteBuffer buf = ByteBuffer.allocateDirect(capacity * 8); 784 buf.order(nativeOrder); 785 return buf.asDoubleBuffer(); 786 } 787 788 /** 789 * Asserts that a buffer is direct. 790 * @param buf buffer 791 */ assertDirectBuffer(Buffer buf)792 protected static void assertDirectBuffer(Buffer buf) 793 { 794 if(!buf.isDirect()) 795 throw new IllegalArgumentException("The buffer must be direct."); 796 } 797 798 /** 799 * Asserts that buffers are direct. 800 * @param sendbuf The send buffer 801 * @param recvbuf The receive buffer 802 */ assertDirectBuffer(Buffer sendbuf, Buffer recvbuf)803 protected static void assertDirectBuffer(Buffer sendbuf, Buffer recvbuf) 804 { 805 if(!sendbuf.isDirect()) 806 throw new IllegalArgumentException("The send buffer must be direct."); 807 808 if(!recvbuf.isDirect()) 809 throw new IllegalArgumentException("The recv. buffer must be direct."); 810 } 811 812 /** 813 * Checks if an object is a direct buffer. 814 * @param obj object 815 * @return true if the object is a direct buffer 816 */ isDirectBuffer(Object obj)817 protected static boolean isDirectBuffer(Object obj) 818 { 819 return obj instanceof Buffer && ((Buffer)obj).isDirect(); 820 } 821 822 /** 823 * Checks if an object is a heap buffer. 824 * @param obj object 825 * @return true if the object is a heap buffer 826 */ isHeapBuffer(Object obj)827 protected static boolean isHeapBuffer(Object obj) 828 { 829 return obj instanceof Buffer && !((Buffer)obj).isDirect(); 830 } 831 832 /** 833 * Creates a new buffer whose content is a shared subsequence of a buffer. 834 * <p>The content of the new buffer will start at the specified offset. 835 * @param buf buffer 836 * @param offset offset 837 * @return the new buffer. 838 */ slice(ByteBuffer buf, int offset)839 public static ByteBuffer slice(ByteBuffer buf, int offset) 840 { 841 return ((ByteBuffer)buf.clear().position(offset)) 842 .slice().order(nativeOrder); 843 } 844 845 /** 846 * Creates a new buffer whose content is a shared subsequence of a buffer. 847 * <p>The content of the new buffer will start at the specified offset. 848 * @param buf buffer 849 * @param offset offset 850 * @return the new buffer. 851 */ slice(CharBuffer buf, int offset)852 public static CharBuffer slice(CharBuffer buf, int offset) 853 { 854 return ((CharBuffer)buf.clear().position(offset)).slice(); 855 } 856 857 /** 858 * Creates a new buffer whose content is a shared subsequence of a buffer. 859 * <p>The content of the new buffer will start at the specified offset. 860 * @param buf buffer 861 * @param offset offset 862 * @return the new buffer. 863 */ slice(ShortBuffer buf, int offset)864 public static ShortBuffer slice(ShortBuffer buf, int offset) 865 { 866 return ((ShortBuffer)buf.clear().position(offset)).slice(); 867 } 868 869 /** 870 * Creates a new buffer whose content is a shared subsequence of a buffer. 871 * <p>The content of the new buffer will start at the specified offset. 872 * @param buf buffer 873 * @param offset offset 874 * @return the new buffer. 875 */ slice(IntBuffer buf, int offset)876 public static IntBuffer slice(IntBuffer buf, int offset) 877 { 878 return ((IntBuffer)buf.clear().position(offset)).slice(); 879 } 880 881 /** 882 * Creates a new buffer whose content is a shared subsequence of a buffer. 883 * <p>The content of the new buffer will start at the specified offset. 884 * @param buf buffer 885 * @param offset offset 886 * @return the new buffer. 887 */ slice(LongBuffer buf, int offset)888 public static LongBuffer slice(LongBuffer buf, int offset) 889 { 890 return ((LongBuffer)buf.clear().position(offset)).slice(); 891 } 892 893 /** 894 * Creates a new buffer whose content is a shared subsequence of a buffer. 895 * <p>The content of the new buffer will start at the specified offset. 896 * @param buf buffer 897 * @param offset offset 898 * @return the new buffer. 899 */ slice(FloatBuffer buf, int offset)900 public static FloatBuffer slice(FloatBuffer buf, int offset) 901 { 902 return ((FloatBuffer)buf.clear().position(offset)).slice(); 903 } 904 905 /** 906 * Creates a new buffer whose content is a shared subsequence of a buffer. 907 * <p>The content of the new buffer will start at the specified offset. 908 * @param buf buffer 909 * @param offset offset 910 * @return the new buffer. 911 */ slice(DoubleBuffer buf, int offset)912 public static DoubleBuffer slice(DoubleBuffer buf, int offset) 913 { 914 return ((DoubleBuffer)buf.clear().position(offset)).slice(); 915 } 916 917 /** 918 * Creates a new buffer whose content is a shared subsequence of a buffer. 919 * <p>The content of the new buffer will start at the specified offset. 920 * @param buf buffer 921 * @param offset offset 922 * @return the new buffer. 923 */ slice(byte[] buf, int offset)924 public static ByteBuffer slice(byte[] buf, int offset) 925 { 926 return ByteBuffer.wrap(buf, offset, buf.length - offset) 927 .slice().order(nativeOrder); 928 } 929 930 /** 931 * Creates a new buffer whose content is a shared subsequence of a buffer. 932 * <p>The content of the new buffer will start at the specified offset. 933 * @param buf buffer 934 * @param offset offset 935 * @return the new buffer. 936 */ slice(char[] buf, int offset)937 public static CharBuffer slice(char[] buf, int offset) 938 { 939 return CharBuffer.wrap(buf, offset, buf.length - offset).slice(); 940 } 941 942 /** 943 * Creates a new buffer whose content is a shared subsequence of a buffer. 944 * <p>The content of the new buffer will start at the specified offset. 945 * @param buf buffer 946 * @param offset offset 947 * @return the new buffer. 948 */ slice(short[] buf, int offset)949 public static ShortBuffer slice(short[] buf, int offset) 950 { 951 return ShortBuffer.wrap(buf, offset, buf.length - offset).slice(); 952 } 953 954 /** 955 * Creates a new buffer whose content is a shared subsequence of a buffer. 956 * <p>The content of the new buffer will start at the specified offset. 957 * @param buf buffer 958 * @param offset offset 959 * @return the new buffer. 960 */ slice(int[] buf, int offset)961 public static IntBuffer slice(int[] buf, int offset) 962 { 963 return IntBuffer.wrap(buf, offset, buf.length - offset).slice(); 964 } 965 966 /** 967 * Creates a new buffer whose content is a shared subsequence of a buffer. 968 * <p>The content of the new buffer will start at the specified offset. 969 * @param buf buffer 970 * @param offset offset 971 * @return the new buffer. 972 */ slice(long[] buf, int offset)973 public static LongBuffer slice(long[] buf, int offset) 974 { 975 return LongBuffer.wrap(buf, offset, buf.length - offset).slice(); 976 } 977 978 /** 979 * Creates a new buffer whose content is a shared subsequence of a buffer. 980 * <p>The content of the new buffer will start at the specified offset. 981 * @param buf buffer 982 * @param offset offset 983 * @return the new buffer. 984 */ slice(float[] buf, int offset)985 public static FloatBuffer slice(float[] buf, int offset) 986 { 987 return FloatBuffer.wrap(buf, offset, buf.length - offset).slice(); 988 } 989 990 /** 991 * Creates a new buffer whose content is a shared subsequence of a buffer. 992 * <p>The content of the new buffer will start at the specified offset. 993 * @param buf buffer 994 * @param offset offset 995 * @return the new buffer. 996 */ slice(double[] buf, int offset)997 public static DoubleBuffer slice(double[] buf, int offset) 998 { 999 return DoubleBuffer.wrap(buf, offset, buf.length - offset).slice(); 1000 } 1001 1002 } // MPI 1003