This source file includes following definitions.
- bufferConstructor
- bufferDestructor
- JNI_OnLoad
- initFreeList
- findClass
- findClasses
- deleteClasses
- Java_mpi_MPI_newInt2
- Java_mpi_MPI_newShortInt
- Java_mpi_MPI_newLongInt
- Java_mpi_MPI_newFloatInt
- Java_mpi_MPI_newDoubleInt
- Java_mpi_MPI_initVersion
- Java_mpi_MPI_Init_1jni
- Java_mpi_MPI_InitThread_1jni
- Java_mpi_MPI_queryThread_1jni
- Java_mpi_MPI_isThreadMain_1jni
- Java_mpi_MPI_Finalize_1jni
- Java_mpi_MPI_getVersionJNI
- Java_mpi_MPI_getLibVersionJNI
- Java_mpi_MPI_getProcessorName
- Java_mpi_MPI_wtime_1jni
- Java_mpi_MPI_wtick_1jni
- Java_mpi_MPI_isInitialized
- Java_mpi_MPI_isFinalized
- Java_mpi_MPI_attachBuffer_1jni
- Java_mpi_MPI_detachBuffer_1jni
- ompi_java_getArrayCritical
- ompi_java_getDirectBufferAddress
- getTypeExtent
- getArrayRegion
- setArrayRegion
- getBuffer
- releaseBuffer
- getCountv
- getReadPtr
- getReadPtrRank
- getReadPtrvRank
- getReadPtrvAll
- getWritePtr
- getWritePtrv
- ompi_java_getReadPtr
- ompi_java_getReadPtrRank
- ompi_java_getReadPtrv
- ompi_java_releaseReadPtr
- ompi_java_getWritePtr
- ompi_java_getWritePtrv
- ompi_java_releaseWritePtr
- ompi_java_releaseWritePtrv
- ompi_java_Integer_valueOf
- ompi_java_Long_valueOf
- ompi_java_getIntArray
- ompi_java_releaseIntArray
- ompi_java_forgetIntArray
- ompi_java_getDatatypeArray
- ompi_java_forgetDatatypeArray
- ompi_java_getBooleanArray
- ompi_java_releaseBooleanArray
- ompi_java_forgetBooleanArray
- ompi_java_getPtrArray
- ompi_java_releasePtrArray
- ompi_java_exceptionCheck
- ompi_java_attrSet
- ompi_java_attrGet
- ompi_java_attrCopy
- ompi_java_attrDelete
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 #include "ompi_config.h"
  55 
  56 #include <stdio.h>
  57 #ifdef HAVE_SYS_TYPES_H
  58 #include <sys/types.h>
  59 #endif
  60 #include <stdlib.h>
  61 #include <string.h>
  62 #ifdef HAVE_TARGETCONDITIONALS_H
  63 #include <TargetConditionals.h>
  64 #endif
  65 #ifdef HAVE_SYS_STAT_H
  66 #include <sys/stat.h>
  67 #endif
  68 #ifdef HAVE_DLFCN_H
  69 #include <dlfcn.h>
  70 #endif
  71 #include <poll.h>
  72 #ifdef HAVE_LIBGEN_H
  73 #include <libgen.h>
  74 #endif
  75 
  76 #include "opal/util/output.h"
  77 #include "opal/datatype/opal_convertor.h"
  78 #include "opal/mca/base/mca_base_var.h"
  79 
  80 #include "mpi.h"
  81 #include "ompi/errhandler/errcode.h"
  82 #include "ompi/errhandler/errcode-internal.h"
  83 #include "ompi/datatype/ompi_datatype.h"
  84 #include "mpi_MPI.h"
  85 #include "mpiJava.h"
  86 
  87 ompi_java_globals_t ompi_java = {0};
  88 int ompi_mpi_java_eager = 65536;
  89 opal_free_list_t ompi_java_buffers = {{{0}}};
  90 
  91 static void bufferConstructor(ompi_java_buffer_t *item)
  92 {
  93     item->buffer = malloc(ompi_mpi_java_eager);
  94 }
  95 
  96 static void bufferDestructor(ompi_java_buffer_t *item)
  97 {
  98     free(item->buffer);
  99 }
 100 
 101 OBJ_CLASS_INSTANCE(ompi_java_buffer_t,
 102                    opal_free_list_item_t,
 103                    bufferConstructor,
 104                    bufferDestructor);
 105 
 106 
 107 
 108 
 109 
 110 
 111 jint JNI_OnLoad(JavaVM *vm, void *reserved)
 112 {
 113     
 114     
 115     opal_init_psm();
 116 
 117     return JNI_VERSION_1_6;
 118 }
 119 
 120 static void initFreeList(void)
 121 {
 122     OBJ_CONSTRUCT(&ompi_java_buffers, opal_free_list_t);
 123 
 124     int r = opal_free_list_init(&ompi_java_buffers,
 125                                 sizeof(ompi_java_buffer_t),
 126                                 opal_cache_line_size,
 127                                 OBJ_CLASS(ompi_java_buffer_t),
 128                                 0, 
 129                                 0, 
 130                                 2, 
 131                                 -1, 
 132                                 2, 
 133                                 NULL, 
 134                                 0, 
 135                                 NULL, 
 136                                 NULL, 
 137                                 NULL );
 138     if(r != OPAL_SUCCESS)
 139     {
 140         fprintf(stderr, "Unable to initialize ompi_java_buffers.\n");
 141         exit(1);
 142     }
 143 }
 144 
 145 static jclass findClass(JNIEnv *env, const char *className)
 146 {
 147     jclass c = (*env)->FindClass(env, className),
 148            r = (*env)->NewGlobalRef(env, c);
 149 
 150     (*env)->DeleteLocalRef(env, c);
 151     return r;
 152 }
 153 
 154 static void findClasses(JNIEnv *env)
 155 {
 156     ompi_java.CartParmsClass  = findClass(env, "mpi/CartParms");
 157     ompi_java.ShiftParmsClass = findClass(env, "mpi/ShiftParms");
 158     ompi_java.GraphParmsClass = findClass(env, "mpi/GraphParms");
 159 
 160     ompi_java.DistGraphNeighborsClass = findClass(
 161                                         env, "mpi/DistGraphNeighbors");
 162 
 163     ompi_java.StatusClass    = findClass(env, "mpi/Status");
 164     ompi_java.ExceptionClass = findClass(env, "mpi/MPIException");
 165 
 166     ompi_java.ExceptionInit = (*env)->GetMethodID(
 167                               env, ompi_java.ExceptionClass,
 168                               "<init>", "(IILjava/lang/String;)V");
 169 
 170     ompi_java.IntegerClass = findClass(env, "java/lang/Integer");
 171     ompi_java.LongClass    = findClass(env, "java/lang/Long");
 172 
 173     ompi_java.IntegerValueOf = (*env)->GetStaticMethodID(
 174             env, ompi_java.IntegerClass, "valueOf", "(I)Ljava/lang/Integer;");
 175     ompi_java.LongValueOf = (*env)->GetStaticMethodID(
 176             env, ompi_java.LongClass, "valueOf", "(J)Ljava/lang/Long;");
 177 }
 178 
 179 static void deleteClasses(JNIEnv *env)
 180 {
 181     (*env)->DeleteGlobalRef(env, ompi_java.CartParmsClass);
 182     (*env)->DeleteGlobalRef(env, ompi_java.ShiftParmsClass);
 183     (*env)->DeleteGlobalRef(env, ompi_java.VersionClass);
 184     (*env)->DeleteGlobalRef(env, ompi_java.CountClass);
 185     (*env)->DeleteGlobalRef(env, ompi_java.GraphParmsClass);
 186     (*env)->DeleteGlobalRef(env, ompi_java.DistGraphNeighborsClass);
 187     (*env)->DeleteGlobalRef(env, ompi_java.StatusClass);
 188     (*env)->DeleteGlobalRef(env, ompi_java.ExceptionClass);
 189     (*env)->DeleteGlobalRef(env, ompi_java.IntegerClass);
 190     (*env)->DeleteGlobalRef(env, ompi_java.LongClass);
 191 }
 192 
 193 JNIEXPORT jobject JNICALL Java_mpi_MPI_newInt2(JNIEnv *env, jclass clazz)
 194 {
 195     struct { int a; int b; } s;
 196     int iOff = (int)((MPI_Aint)(&(s.b)) - (MPI_Aint)(&(s.a)));
 197     jclass c = (*env)->FindClass(env, "mpi/Int2");
 198     jmethodID m = (*env)->GetMethodID(env, c, "<init>", "(II)V");
 199     return (*env)->NewObject(env, c, m, iOff, sizeof(int));
 200 }
 201 
 202 JNIEXPORT jobject JNICALL Java_mpi_MPI_newShortInt(JNIEnv *env, jclass clazz)
 203 {
 204     struct { short a; int b; } s;
 205     int iOff = (int)((MPI_Aint)(&(s.b)) - (MPI_Aint)(&(s.a)));
 206     jclass c = (*env)->FindClass(env, "mpi/ShortInt");
 207     jmethodID m = (*env)->GetMethodID(env, c, "<init>", "(III)V");
 208     return (*env)->NewObject(env, c, m, sizeof(short), iOff, sizeof(int));
 209 }
 210 
 211 JNIEXPORT jobject JNICALL Java_mpi_MPI_newLongInt(JNIEnv *env, jclass clazz)
 212 {
 213     struct { long a; int b; } s;
 214     int iOff = (int)((MPI_Aint)(&(s.b)) - (MPI_Aint)(&(s.a)));
 215     jclass c = (*env)->FindClass(env, "mpi/LongInt");
 216     jmethodID m = (*env)->GetMethodID(env, c, "<init>", "(III)V");
 217     return (*env)->NewObject(env, c, m, sizeof(long), iOff, sizeof(int));
 218 }
 219 
 220 JNIEXPORT jobject JNICALL Java_mpi_MPI_newFloatInt(JNIEnv *env, jclass clazz)
 221 {
 222     struct { float a; int b; } s;
 223     int iOff = (int)((MPI_Aint)(&(s.b)) - (MPI_Aint)(&(s.a)));
 224     jclass c = (*env)->FindClass(env, "mpi/FloatInt");
 225     jmethodID m = (*env)->GetMethodID(env, c, "<init>", "(II)V");
 226     return (*env)->NewObject(env, c, m, iOff, sizeof(int));
 227 }
 228 
 229 JNIEXPORT jobject JNICALL Java_mpi_MPI_newDoubleInt(JNIEnv *env, jclass clazz)
 230 {
 231     struct { double a; int b; } s;
 232     int iOff = (int)((MPI_Aint)(&(s.b)) - (MPI_Aint)(&(s.a)));
 233     jclass c = (*env)->FindClass(env, "mpi/DoubleInt");
 234     jmethodID m = (*env)->GetMethodID(env, c, "<init>", "(II)V");
 235     return (*env)->NewObject(env, c, m, iOff, sizeof(int));
 236 }
 237 
 238 JNIEXPORT void JNICALL Java_mpi_MPI_initVersion(JNIEnv *env, jclass jthis)
 239 {
 240     ompi_java.VersionClass = findClass(env, "mpi/Version");
 241     ompi_java.VersionInit = (*env)->GetMethodID(env, ompi_java.VersionClass, "<init>", "(II)V");
 242 }
 243 
 244 JNIEXPORT jobjectArray JNICALL Java_mpi_MPI_Init_1jni(
 245         JNIEnv *env, jclass clazz, jobjectArray argv)
 246 {
 247     jsize i;
 248     jclass string;
 249     jobject value;
 250 
 251     int len = (*env)->GetArrayLength(env, argv);
 252     char **sargs = (char**)calloc(len+1, sizeof(char*));
 253 
 254     for(i = 0; i < len; i++)
 255     {
 256         jstring jc = (jstring)(*env)->GetObjectArrayElement(env, argv, i);
 257         const char *s = (*env)->GetStringUTFChars(env, jc, NULL);
 258         sargs[i] = strdup(s);
 259         (*env)->ReleaseStringUTFChars(env, jc, s);
 260         (*env)->DeleteLocalRef(env, jc);
 261     }
 262 
 263     int rc = MPI_Init(&len, &sargs);
 264     
 265     if(ompi_java_exceptionCheck(env, rc)) {
 266         for(i = 0; i < len; i++)
 267             free (sargs[i]);
 268         free(sargs);
 269         return NULL;
 270     }
 271 
 272     mca_base_var_register("ompi", "mpi", "java", "eager",
 273                           "Java buffers eager size",
 274                           MCA_BASE_VAR_TYPE_INT, NULL, 0, 0,
 275                           OPAL_INFO_LVL_5,
 276                           MCA_BASE_VAR_SCOPE_READONLY,
 277                           &ompi_mpi_java_eager);
 278 
 279     string = (*env)->FindClass(env, "java/lang/String");
 280     value = (*env)->NewObjectArray(env, len, string, NULL);
 281 
 282     for(i = 0; i < len; i++)
 283     {
 284         jstring jc = (*env)->NewStringUTF(env, sargs[i]);
 285         (*env)->SetObjectArrayElement(env, value, i, jc);
 286         (*env)->DeleteLocalRef(env, jc);
 287         free (sargs[i]);
 288     }
 289 
 290     free (sargs);
 291 
 292     findClasses(env);
 293     initFreeList();
 294     return value;
 295 }
 296 
 297 JNIEXPORT jint JNICALL Java_mpi_MPI_InitThread_1jni(
 298         JNIEnv *env, jclass clazz, jobjectArray argv, jint required)
 299 {
 300     jsize i;
 301     int len = (*env)->GetArrayLength(env,argv);
 302     char **sargs = (char**)calloc(len+1, sizeof(char*));
 303 
 304     for(i = 0; i < len; i++)
 305     {
 306         jstring jc = (jstring)(*env)->GetObjectArrayElement(env, argv, i);
 307         const char *s = (*env)->GetStringUTFChars(env, jc, 0);
 308         sargs[i] = strdup(s);
 309         (*env)->ReleaseStringUTFChars(env, jc, s);
 310         (*env)->DeleteLocalRef(env, jc);
 311     }
 312 
 313     int provided;
 314     int rc = MPI_Init_thread(&len, &sargs, required, &provided);
 315     
 316     if(ompi_java_exceptionCheck(env, rc)) {
 317         for(i = 0; i < len; i++)
 318             free (sargs[i]);
 319         free(sargs);
 320         return -1;
 321     }
 322 
 323     findClasses(env);
 324     initFreeList();
 325     return provided;
 326 }
 327 
 328 JNIEXPORT jint JNICALL Java_mpi_MPI_queryThread_1jni(JNIEnv *env, jclass clazz)
 329 {
 330     int provided;
 331     int rc = MPI_Query_thread(&provided);
 332     ompi_java_exceptionCheck(env, rc);
 333     return provided;
 334 }
 335 
 336 JNIEXPORT jboolean JNICALL Java_mpi_MPI_isThreadMain_1jni(
 337                            JNIEnv *env, jclass clazz)
 338 {
 339     int flag;
 340     int rc = MPI_Is_thread_main(&flag);
 341     ompi_java_exceptionCheck(env, rc);
 342     return flag ? JNI_TRUE : JNI_FALSE;
 343 }
 344 
 345 JNIEXPORT void JNICALL Java_mpi_MPI_Finalize_1jni(JNIEnv *env, jclass obj)
 346 {
 347     OBJ_DESTRUCT(&ompi_java_buffers);
 348     int rc = MPI_Finalize();
 349     ompi_java_exceptionCheck(env, rc);
 350     deleteClasses(env);
 351 }
 352 
 353 JNIEXPORT jobject JNICALL Java_mpi_MPI_getVersionJNI(JNIEnv *env, jclass jthis)
 354 {
 355         int version, subversion;
 356         int rc = MPI_Get_version(&version, &subversion);
 357         ompi_java_exceptionCheck(env, rc);
 358 
 359         return (*env)->NewObject(env, ompi_java.VersionClass,
 360                                      ompi_java.VersionInit, version, subversion);
 361 }
 362 
 363 JNIEXPORT jstring JNICALL Java_mpi_MPI_getLibVersionJNI(JNIEnv *env, jclass jthis)
 364 {
 365         int length;
 366         char version[MPI_MAX_LIBRARY_VERSION_STRING];
 367         int rc = MPI_Get_library_version(version, &length);
 368         ompi_java_exceptionCheck(env, rc);
 369 
 370         return (*env)->NewStringUTF(env, version);
 371 }
 372 
 373 JNIEXPORT jint JNICALL Java_mpi_MPI_getProcessorName(
 374                        JNIEnv *env, jclass obj, jbyteArray buf)
 375 {
 376     int len;
 377     jbyte* bufc = (jbyte*)((*env)->GetByteArrayElements(env, buf, NULL));
 378     int rc = MPI_Get_processor_name((char*)bufc, &len);
 379     ompi_java_exceptionCheck(env, rc);
 380     (*env)->ReleaseByteArrayElements(env, buf, bufc, 0);
 381     return len;
 382 }
 383 
 384 JNIEXPORT jdouble JNICALL Java_mpi_MPI_wtime_1jni(JNIEnv *env, jclass jthis)
 385 {
 386     return MPI_Wtime();
 387 }
 388 
 389 JNIEXPORT jdouble JNICALL Java_mpi_MPI_wtick_1jni(JNIEnv *env, jclass jthis)
 390 {
 391     return MPI_Wtick();
 392 }
 393 
 394 JNIEXPORT jboolean JNICALL Java_mpi_MPI_isInitialized(JNIEnv *env, jclass jthis)
 395 {
 396     int flag;
 397     int rc = MPI_Initialized(&flag);
 398     ompi_java_exceptionCheck(env, rc);
 399     return flag ? JNI_TRUE : JNI_FALSE;
 400 }
 401 
 402 JNIEXPORT jboolean JNICALL Java_mpi_MPI_isFinalized(JNIEnv *env, jclass jthis)
 403 {
 404     int flag;
 405     int rc = MPI_Finalized(&flag);
 406     ompi_java_exceptionCheck(env, rc);
 407     return flag ? JNI_TRUE : JNI_FALSE;
 408 }
 409 
 410 JNIEXPORT void JNICALL Java_mpi_MPI_attachBuffer_1jni(
 411                        JNIEnv *env, jclass jthis, jbyteArray buf)
 412 {
 413     int size=(*env)->GetArrayLength(env,buf);
 414     jbyte* bufptr = (*env)->GetByteArrayElements(env, buf, NULL);
 415     int rc = MPI_Buffer_attach(bufptr,size);
 416     ompi_java_exceptionCheck(env, rc);
 417 }
 418 
 419 JNIEXPORT void JNICALL Java_mpi_MPI_detachBuffer_1jni(
 420                        JNIEnv *env, jclass jthis, jbyteArray buf)
 421 {
 422     int size;
 423     jbyte* bufptr;
 424     int rc = MPI_Buffer_detach(&bufptr, &size);
 425     ompi_java_exceptionCheck(env, rc);
 426 
 427     if(buf != NULL)
 428         (*env)->ReleaseByteArrayElements(env,buf,bufptr,0);
 429 }
 430 
 431 void* ompi_java_getArrayCritical(void** bufBase, JNIEnv *env,
 432                                  jobject buf, int offset)
 433 {
 434     *bufBase = (jbyte*)(*env)->GetPrimitiveArrayCritical(env, buf, NULL);
 435     return ((jbyte*)*bufBase) + offset;
 436 }
 437 
 438 void* ompi_java_getDirectBufferAddress(JNIEnv *env, jobject buf)
 439 {
 440     
 441     return buf == NULL ? NULL : (*env)->GetDirectBufferAddress(env, buf);
 442 }
 443 
 444 static int getTypeExtent(JNIEnv *env, MPI_Datatype type)
 445 {
 446     MPI_Aint lb, extent;
 447     int rc = MPI_Type_get_extent(type, &lb, &extent);
 448     ompi_java_exceptionCheck(env, rc);
 449     int value = extent;
 450     assert(((MPI_Aint)value) == extent);
 451     return value;
 452 }
 453 
 454 static void getArrayRegion(JNIEnv *env, jobject buf, int baseType,
 455                            int offset, int length, void *ptr)
 456 {
 457     switch(baseType)
 458     {
 459         case 0:
 460             break;
 461         case 1:
 462             (*env)->GetByteArrayRegion(env, buf, offset, length, ptr);
 463             break;
 464         case 2:
 465             (*env)->GetCharArrayRegion(env, buf, offset / 2, length / 2, ptr);
 466             break;
 467         case 3:
 468             (*env)->GetShortArrayRegion(env, buf, offset / 2, length / 2, ptr);
 469             break;
 470         case 4:
 471             (*env)->GetBooleanArrayRegion(env, buf, offset, length, ptr);
 472             break;
 473         case 5:
 474             (*env)->GetIntArrayRegion(env, buf, offset / 4, length / 4, ptr);
 475             break;
 476         case 6:
 477             (*env)->GetLongArrayRegion(env, buf, offset / 8, length / 8, ptr);
 478             break;
 479         case 7:
 480             (*env)->GetFloatArrayRegion(env, buf, offset / 4, length / 4, ptr);
 481             break;
 482         case 8:
 483             (*env)->GetDoubleArrayRegion(env, buf, offset / 8, length / 8, ptr);
 484             break;
 485         case 9:
 486             (*env)->GetByteArrayRegion(env, buf, offset, length, ptr);
 487             break;
 488         default:
 489             assert(0);
 490     }
 491 }
 492 
 493 static void setArrayRegion(JNIEnv *env, jobject buf, int baseType,
 494                            int offset, int length, void *ptr)
 495 {
 496     switch(baseType)
 497     {
 498         case 0:
 499             break;
 500         case 1:
 501             (*env)->SetByteArrayRegion(env, buf, offset, length, ptr);
 502             break;
 503         case 2:
 504             (*env)->SetCharArrayRegion(env, buf, offset / 2, length / 2, ptr);
 505             break;
 506         case 3:
 507             (*env)->SetShortArrayRegion(env, buf, offset / 2, length / 2, ptr);
 508             break;
 509         case 4:
 510             (*env)->SetBooleanArrayRegion(env, buf, offset, length, ptr);
 511             break;
 512         case 5:
 513             (*env)->SetIntArrayRegion(env, buf, offset / 4, length / 4, ptr);
 514             break;
 515         case 6:
 516             (*env)->SetLongArrayRegion(env, buf, offset / 8, length / 8, ptr);
 517             break;
 518         case 7:
 519             (*env)->SetFloatArrayRegion(env, buf, offset / 4, length / 4, ptr);
 520             break;
 521         case 8:
 522             (*env)->SetDoubleArrayRegion(env, buf, offset / 8, length / 8, ptr);
 523             break;
 524         case 9:
 525             (*env)->SetByteArrayRegion(env, buf, offset, length, ptr);
 526             break;
 527         default:
 528             assert(0);
 529     }
 530 }
 531 
 532 static void* getBuffer(JNIEnv *env, ompi_java_buffer_t **item, int size)
 533 {
 534     if(size > ompi_mpi_java_eager)
 535     {
 536         *item = NULL;
 537         return malloc(size);
 538     }
 539     else
 540     {
 541         opal_free_list_item_t *freeListItem;
 542         freeListItem = opal_free_list_get (&ompi_java_buffers);
 543 
 544         ompi_java_exceptionCheck(env, NULL == freeListItem ? MPI_ERR_NO_MEM :
 545                                  MPI_SUCCESS);
 546         if (NULL == freeListItem) {
 547             return NULL;
 548         }
 549 
 550         *item = (ompi_java_buffer_t*)freeListItem;
 551         return (*item)->buffer;
 552     }
 553 }
 554 
 555 static void releaseBuffer(void *ptr, ompi_java_buffer_t *item)
 556 {
 557     if(item == NULL)
 558     {
 559         free(ptr);
 560     }
 561     else
 562     {
 563         assert(item->buffer == ptr);
 564         opal_free_list_return (&ompi_java_buffers, (opal_free_list_item_t*)item);
 565     }
 566 }
 567 
 568 static int getCountv(int *counts, int *displs, int size)
 569 {
 570     
 571     int i, max = 0;
 572 
 573     for(i = 1; i < size; i++)
 574     {
 575         if(displs[max] < displs[i])
 576             max = i;
 577     }
 578 
 579     return displs[max] * counts[max];
 580 }
 581 
 582 static void* getReadPtr(ompi_java_buffer_t **item, JNIEnv *env, jobject buf,
 583                         int offset, int count, MPI_Datatype type, int baseType)
 584 {
 585     int  length = count * getTypeExtent(env, type);
 586     void *ptr   = getBuffer(env, item, length);
 587 
 588     if(opal_datatype_is_contiguous_memory_layout(&type->super, count))
 589     {
 590         getArrayRegion(env, buf, baseType, offset, length, ptr);
 591     }
 592     else
 593     {
 594         void *inBuf, *inBase;
 595         inBuf = ompi_java_getArrayCritical(&inBase, env, buf, offset);
 596 
 597         int rc = opal_datatype_copy_content_same_ddt(
 598                  &type->super, count, ptr, inBuf);
 599 
 600         ompi_java_exceptionCheck(env,
 601                 rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 602 
 603         (*env)->ReleasePrimitiveArrayCritical(env, buf, inBase, JNI_ABORT);
 604     }
 605 
 606     return ptr;
 607 }
 608 
 609 static void* getReadPtrRank(
 610         ompi_java_buffer_t **item, JNIEnv *env, jobject buf, int offset,
 611         int count, int size, int rank, MPI_Datatype type, int baseType)
 612 {
 613     int  extent = getTypeExtent(env, type),
 614          rLen   = extent * count,
 615          length = rLen * size,
 616          rDispl = rLen * rank,
 617          rOff   = offset + rDispl;
 618     void *ptr   = getBuffer(env, item, length);
 619     void *rPtr  = (char*)ptr + rDispl;
 620 
 621     if(opal_datatype_is_contiguous_memory_layout(&type->super, count))
 622     {
 623         getArrayRegion(env, buf, baseType, rOff, rLen, rPtr);
 624     }
 625     else
 626     {
 627         void *bufPtr, *bufBase;
 628         bufPtr = ompi_java_getArrayCritical(&bufBase, env, buf, rOff);
 629 
 630         int rc = opal_datatype_copy_content_same_ddt(
 631                  &type->super, count, rPtr, bufPtr);
 632 
 633         ompi_java_exceptionCheck(env,
 634                 rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 635 
 636         (*env)->ReleasePrimitiveArrayCritical(env, buf, bufBase, JNI_ABORT);
 637     }
 638 
 639     return ptr;
 640 }
 641 
 642 static void* getReadPtrvRank(
 643         ompi_java_buffer_t **item, JNIEnv *env, jobject buf,
 644         int offset, int *counts, int *displs, int size,
 645         int rank, MPI_Datatype type, int baseType)
 646 {
 647     int  extent  = getTypeExtent(env, type),
 648          length  = extent * getCountv(counts, displs, size);
 649     void *ptr    = getBuffer(env, item, length);
 650     int  rootOff = offset + extent * displs[rank];
 651 
 652     if(opal_datatype_is_contiguous_memory_layout(&type->super, counts[rank]))
 653     {
 654         int  rootLength = extent * counts[rank];
 655         void *rootPtr   = (char*)ptr + extent * displs[rank];
 656         getArrayRegion(env, buf, baseType, rootOff, rootLength, rootPtr);
 657     }
 658     else
 659     {
 660         void *inBuf, *inBase;
 661         inBuf = ompi_java_getArrayCritical(&inBase, env, buf, rootOff);
 662 
 663         int rc = opal_datatype_copy_content_same_ddt(
 664                  &type->super, counts[rank], ptr, inBuf);
 665 
 666         ompi_java_exceptionCheck(env,
 667                 rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 668 
 669         (*env)->ReleasePrimitiveArrayCritical(env, buf, inBase, JNI_ABORT);
 670     }
 671 
 672     return ptr;
 673 }
 674 
 675 static void* getReadPtrvAll(
 676         ompi_java_buffer_t **item, JNIEnv *env, jobject buf,
 677         int offset, int *counts, int *displs, int size,
 678         MPI_Datatype type, int baseType)
 679 {
 680     int  i,
 681          extent  = getTypeExtent(env, type),
 682          length  = extent * getCountv(counts, displs, size);
 683     void *ptr    = getBuffer(env, item, length);
 684 
 685     if(opal_datatype_is_contiguous_memory_layout(&type->super, 2))
 686     {
 687         for(i = 0; i < size; i++)
 688         {
 689             int   iOff = offset + extent * displs[i],
 690                   iLen = extent * counts[i];
 691             void *iPtr = (char*)ptr + extent * displs[i];
 692             getArrayRegion(env, buf, baseType, iOff, iLen, iPtr);
 693         }
 694     }
 695     else
 696     {
 697         void *bufPtr, *bufBase;
 698         bufPtr = ompi_java_getArrayCritical(&bufBase, env, buf, offset);
 699 
 700         for(i = 0; i < size; i++)
 701         {
 702             int   iOff = extent * displs[i];
 703             char *iBuf = iOff + (char*)bufPtr,
 704                  *iPtr = iOff + (char*)ptr;
 705 
 706             int rc = opal_datatype_copy_content_same_ddt(
 707                      &type->super, counts[i], iPtr, iBuf);
 708 
 709             ompi_java_exceptionCheck(env,
 710                     rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 711         }
 712 
 713         (*env)->ReleasePrimitiveArrayCritical(env, buf, bufBase, JNI_ABORT);
 714     }
 715 
 716     return ptr;
 717 }
 718 
 719 static void* getWritePtr(ompi_java_buffer_t **item, JNIEnv *env,
 720                          int count, MPI_Datatype type)
 721 {
 722     int extent = getTypeExtent(env, type),
 723         length = count * extent;
 724 
 725     return getBuffer(env, item, length);
 726 }
 727 
 728 static void* getWritePtrv(ompi_java_buffer_t **item, JNIEnv *env,
 729                           int *counts, int *displs, int size, MPI_Datatype type)
 730 {
 731     int extent = getTypeExtent(env, type),
 732         count  = getCountv(counts, displs, size),
 733         length = extent * count;
 734 
 735     return getBuffer(env, item, length);
 736 }
 737 
 738 void ompi_java_getReadPtr(
 739         void **ptr, ompi_java_buffer_t **item, JNIEnv *env, jobject buf,
 740         jboolean db, int offset, int count, MPI_Datatype type, int baseType)
 741 {
 742     if(buf == NULL || baseType == 0)
 743     {
 744         
 745         *ptr  = NULL;
 746         *item = NULL;
 747     }
 748     else if(db)
 749     {
 750         assert(offset == 0);
 751         *ptr  = (*env)->GetDirectBufferAddress(env, buf);
 752         *item = NULL;
 753     }
 754     else
 755     {
 756         *ptr = getReadPtr(item, env, buf, offset, count, type, baseType);
 757     }
 758 }
 759 
 760 void ompi_java_getReadPtrRank(
 761         void **ptr, ompi_java_buffer_t **item, JNIEnv *env,
 762         jobject buf, jboolean db, int offset, int count, int size,
 763         int rank, MPI_Datatype type, int baseType)
 764 {
 765     if(buf == NULL || baseType == 0)
 766     {
 767         
 768         *ptr  = NULL;
 769         *item = NULL;
 770     }
 771     else if(db)
 772     {
 773         assert(offset == 0);
 774         *ptr  = (*env)->GetDirectBufferAddress(env, buf);
 775         *item = NULL;
 776     }
 777     else
 778     {
 779         *ptr = getReadPtrRank(item, env, buf, offset, count,
 780                               size, rank, type, baseType);
 781     }
 782 }
 783 
 784 void ompi_java_getReadPtrv(
 785         void **ptr, ompi_java_buffer_t **item, JNIEnv *env,
 786         jobject buf, jboolean db, int offset, int *counts, int *displs,
 787         int size, int rank, MPI_Datatype type, int baseType)
 788 {
 789     if(buf == NULL)
 790     {
 791         
 792         *ptr  = NULL;
 793         *item = NULL;
 794     }
 795     else if(db)
 796     {
 797         assert(offset == 0);
 798         *ptr  = (*env)->GetDirectBufferAddress(env, buf);
 799         *item = NULL;
 800     }
 801     else if(rank == -1)
 802     {
 803         *ptr = getReadPtrvAll(item, env, buf, offset, counts,
 804                               displs, size, type, baseType);
 805     }
 806     else
 807     {
 808         *ptr = getReadPtrvRank(item, env, buf, offset, counts,
 809                                displs, size, rank, type, baseType);
 810     }
 811 }
 812 
 813 void ompi_java_releaseReadPtr(
 814         void *ptr, ompi_java_buffer_t *item, jobject buf, jboolean db)
 815 {
 816     if(!db && buf && ptr)
 817         releaseBuffer(ptr, item);
 818 }
 819 
 820 void ompi_java_getWritePtr(
 821         void **ptr, ompi_java_buffer_t **item, JNIEnv *env,
 822         jobject buf, jboolean db, int count, MPI_Datatype type)
 823 {
 824     if(buf == NULL)
 825     {
 826         
 827         *ptr  = NULL;
 828         *item = NULL;
 829     }
 830     else if(db)
 831     {
 832         *ptr  = (*env)->GetDirectBufferAddress(env, buf);
 833         *item = NULL;
 834     }
 835     else
 836     {
 837         *ptr = getWritePtr(item, env, count, type);
 838     }
 839 }
 840 
 841 void ompi_java_getWritePtrv(
 842         void **ptr, ompi_java_buffer_t **item, JNIEnv *env, jobject buf,
 843         jboolean db, int *counts, int *displs, int size, MPI_Datatype type)
 844 {
 845     if(buf == NULL)
 846     {
 847         
 848         *ptr  = NULL;
 849         *item = NULL;
 850     }
 851     else if(db)
 852     {
 853         *ptr  = (*env)->GetDirectBufferAddress(env, buf);
 854         *item = NULL;
 855     }
 856     else
 857     {
 858         *ptr = getWritePtrv(item, env, counts, displs, size, type);
 859     }
 860 }
 861 
 862 void ompi_java_releaseWritePtr(
 863         void *ptr, ompi_java_buffer_t *item, JNIEnv *env, jobject buf,
 864         jboolean db, int offset, int count, MPI_Datatype type, int baseType)
 865 {
 866     if(db || !buf || !ptr)
 867         return;
 868 
 869     if(opal_datatype_is_contiguous_memory_layout(&type->super, count))
 870     {
 871         int length = count * getTypeExtent(env, type);
 872         setArrayRegion(env, buf, baseType, offset, length, ptr);
 873     }
 874     else
 875     {
 876         void *inBuf, *inBase;
 877         inBuf = ompi_java_getArrayCritical(&inBase, env, buf, offset);
 878 
 879         int rc = opal_datatype_copy_content_same_ddt(
 880                  &type->super, count, inBuf, ptr);
 881 
 882         ompi_java_exceptionCheck(env,
 883                 rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 884 
 885         (*env)->ReleasePrimitiveArrayCritical(env, buf, inBase, 0);
 886     }
 887 
 888     releaseBuffer(ptr, item);
 889 }
 890 
 891 void ompi_java_releaseWritePtrv(
 892         void *ptr, ompi_java_buffer_t *item, JNIEnv *env,
 893         jobject buf, jboolean db, int offset, int *counts, int *displs,
 894         int size, MPI_Datatype type, int baseType)
 895 {
 896     if(db || !buf || !ptr)
 897         return;
 898 
 899     int i;
 900     int extent = getTypeExtent(env, type);
 901 
 902     if(opal_datatype_is_contiguous_memory_layout(&type->super, 2))
 903     {
 904         for(i = 0; i < size; i++)
 905         {
 906             int   iOff = offset + extent * displs[i],
 907                   iLen = extent * counts[i];
 908             void *iPtr = (char*)ptr + extent * displs[i];
 909             setArrayRegion(env, buf, baseType, iOff, iLen, iPtr);
 910         }
 911     }
 912     else
 913     {
 914         void *bufPtr, *bufBase;
 915         bufPtr = ompi_java_getArrayCritical(&bufBase, env, buf, offset);
 916 
 917         for(i = 0; i < size; i++)
 918         {
 919             int   iOff = extent * displs[i];
 920             char *iBuf = iOff + (char*)bufPtr,
 921                  *iPtr = iOff + (char*)ptr;
 922 
 923             int rc = opal_datatype_copy_content_same_ddt(
 924                      &type->super, counts[i], iBuf, iPtr);
 925 
 926             ompi_java_exceptionCheck(env,
 927                     rc==OPAL_SUCCESS ? OMPI_SUCCESS : OMPI_ERROR);
 928         }
 929 
 930         (*env)->ReleasePrimitiveArrayCritical(env, buf, bufBase, 0);
 931     }
 932 
 933     releaseBuffer(ptr, item);
 934 }
 935 
 936 jobject ompi_java_Integer_valueOf(JNIEnv *env, jint i)
 937 {
 938     return (*env)->CallStaticObjectMethod(env,
 939            ompi_java.IntegerClass, ompi_java.IntegerValueOf, i);
 940 }
 941 
 942 jobject ompi_java_Long_valueOf(JNIEnv *env, jlong i)
 943 {
 944     return (*env)->CallStaticObjectMethod(env,
 945            ompi_java.LongClass, ompi_java.LongValueOf, i);
 946 }
 947 
 948 void ompi_java_getIntArray(JNIEnv *env, jintArray array,
 949                            jint **jptr, int **cptr)
 950 {
 951     jint *jInts = (*env)->GetIntArrayElements(env, array, NULL);
 952     *jptr = jInts;
 953 
 954     if(sizeof(int) == sizeof(jint))
 955     {
 956         *cptr = (int*)jInts;
 957     }
 958     else
 959     {
 960         int i, length = (*env)->GetArrayLength(env, array);
 961         int *cInts = calloc(length, sizeof(int));
 962 
 963         for(i = 0; i < length; i++)
 964             cInts[i] = jInts[i];
 965 
 966         *cptr = cInts;
 967     }
 968 }
 969 
 970 void ompi_java_releaseIntArray(JNIEnv *env, jintArray array,
 971                                jint *jptr, int *cptr)
 972 {
 973     if(jptr != cptr)
 974     {
 975         int i, length = (*env)->GetArrayLength(env, array);
 976 
 977         for(i = 0; i < length; i++)
 978             jptr[i] = cptr[i];
 979 
 980         free(cptr);
 981     }
 982 
 983     (*env)->ReleaseIntArrayElements(env, array, jptr, 0);
 984 }
 985 
 986 void ompi_java_forgetIntArray(JNIEnv *env, jintArray array,
 987                               jint *jptr, int *cptr)
 988 {
 989     if(jptr != cptr)
 990         free(cptr);
 991 
 992     (*env)->ReleaseIntArrayElements(env, array, jptr, JNI_ABORT);
 993 }
 994 
 995 void ompi_java_getDatatypeArray(JNIEnv *env, jlongArray array,
 996                            jlong **jptr, MPI_Datatype **cptr)
 997 {
 998     jlong *jLongs = (*env)->GetLongArrayElements(env, array, NULL);
 999     *jptr = jLongs;
1000 
1001     int i, length = (*env)->GetArrayLength(env, array);
1002     MPI_Datatype *cDatatypes = calloc(length, sizeof(MPI_Datatype));
1003 
1004     for(i = 0; i < length; i++){
1005         cDatatypes[i] = (MPI_Datatype)jLongs[i];
1006     }
1007     *cptr = cDatatypes;
1008 }
1009 
1010 void ompi_java_forgetDatatypeArray(JNIEnv *env, jlongArray array,
1011                               jlong *jptr, MPI_Datatype *cptr)
1012 {
1013     if((long)jptr != (long)cptr)
1014         free(cptr);
1015 
1016     (*env)->ReleaseLongArrayElements(env, array, jptr, JNI_ABORT);
1017 }
1018 
1019 void ompi_java_getBooleanArray(JNIEnv *env, jbooleanArray array,
1020                                jboolean **jptr, int **cptr)
1021 {
1022     int i, length = (*env)->GetArrayLength(env, array);
1023     jboolean *jb = (*env)->GetBooleanArrayElements(env, array, NULL);
1024     int *cb = (int*)calloc(length, sizeof(int));
1025 
1026     for(i = 0; i < length; i++)
1027         cb[i] = jb[i];
1028 
1029     *jptr = jb;
1030     *cptr = cb;
1031 }
1032 
1033 void ompi_java_releaseBooleanArray(JNIEnv *env, jbooleanArray array,
1034                                    jboolean *jptr, int *cptr)
1035 {
1036     int i, length = (*env)->GetArrayLength(env, array);
1037 
1038     for(i = 0; i < length; i++)
1039         jptr[i] = cptr[i] ? JNI_TRUE : JNI_FALSE;
1040 
1041     free(cptr);
1042     (*env)->ReleaseBooleanArrayElements(env, array, jptr, 0);
1043 }
1044 
1045 void ompi_java_forgetBooleanArray(JNIEnv *env, jbooleanArray array,
1046                                   jboolean *jptr, int *cptr)
1047 {
1048     free(cptr);
1049     (*env)->ReleaseBooleanArrayElements(env, array, jptr, JNI_ABORT);
1050 }
1051 
1052 void ompi_java_getPtrArray(JNIEnv *env, jlongArray array,
1053                            jlong **jptr, void ***cptr)
1054 {
1055     jlong *jp = *jptr = (*env)->GetLongArrayElements(env, array, NULL);
1056 
1057     if(sizeof(jlong) == sizeof(void*))
1058     {
1059         *cptr = (void**)jp;
1060     }
1061     else
1062     {
1063         int i, length = (*env)->GetArrayLength(env, array);
1064         void **cp = *cptr = calloc(length, sizeof(void*));
1065 
1066         for(i = 0; i < length; i++)
1067             cp[i] = (void*)jp[i];
1068     }
1069 }
1070 
1071 void ompi_java_releasePtrArray(JNIEnv *env, jlongArray array,
1072                                jlong *jptr, void **cptr)
1073 {
1074     if(jptr != (jlong*)cptr)
1075     {
1076         int i, length = (*env)->GetArrayLength(env, array);
1077 
1078         for(i = 0; i < length; i++)
1079             jptr[i] = (jlong)cptr[i];
1080 
1081         free(cptr);
1082     }
1083 
1084     (*env)->ReleaseLongArrayElements(env, array, jptr, 0);
1085 }
1086 
1087 
1088 
1089 
1090 
1091 
1092 
1093 
1094 
1095 
1096 
1097 
1098 
1099 jboolean ompi_java_exceptionCheck(JNIEnv *env, int rc)
1100 {
1101     jboolean jni_exception;
1102 
1103     if (rc < 0) {
1104         
1105         rc = ompi_errcode_get_mpi_code (rc);
1106         
1107 
1108         assert (rc >= 0);
1109     }
1110     jni_exception = (*env)->ExceptionCheck(env);
1111 
1112     if(MPI_SUCCESS == rc && JNI_FALSE == jni_exception)
1113     {
1114         return JNI_FALSE;
1115     }
1116     else if(MPI_SUCCESS != rc)
1117     {
1118         int     errClass = ompi_mpi_errcode_get_class(rc);
1119         char    *message = ompi_mpi_errnum_get_string(rc);
1120         jstring jmessage = (*env)->NewStringUTF(env, (const char*)message);
1121 
1122         jobject mpiex = (*env)->NewObject(env, ompi_java.ExceptionClass,
1123                                           ompi_java.ExceptionInit,
1124                                           rc, errClass, jmessage);
1125         (*env)->Throw(env, mpiex);
1126         (*env)->DeleteLocalRef(env, mpiex);
1127         (*env)->DeleteLocalRef(env, jmessage);
1128         return JNI_TRUE;
1129     }
1130     
1131     return JNI_TRUE;
1132 }
1133 
1134 void* ompi_java_attrSet(JNIEnv *env, jbyteArray jval)
1135 {
1136     int length = (*env)->GetArrayLength(env, jval);
1137     void *cval = malloc(sizeof(int) + length);
1138     *((int*)cval) = length;
1139 
1140     (*env)->GetByteArrayRegion(env, jval,
1141             0, length, (jbyte*)cval + sizeof(int));
1142 
1143     return cval;
1144 }
1145 
1146 jbyteArray ompi_java_attrGet(JNIEnv *env, void *cval)
1147 {
1148     int length = *((int*)cval);
1149     jbyteArray jval = (*env)->NewByteArray(env, length);
1150 
1151     (*env)->SetByteArrayRegion(env, jval,
1152             0, length, (jbyte*)cval + sizeof(int));
1153 
1154     return jval;
1155 }
1156 
1157 int ompi_java_attrCopy(void *attrValIn, void *attrValOut, int *flag)
1158 {
1159     int length = *((int*)attrValIn) + sizeof(int);
1160     *((void**)attrValOut) = malloc(length);
1161     memcpy(*((void**)attrValOut), attrValIn, length);
1162     *flag = 1;
1163     return MPI_SUCCESS;
1164 }
1165 
1166 int ompi_java_attrDelete(void *attrVal)
1167 {
1168     free(attrVal);
1169     return MPI_SUCCESS;
1170 }