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 }