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$
15  *
16  * Additional copyrights may follow
17  *
18  * $HEADER$
19  */
20 /*
21  * This file is almost a complete re-write for Open MPI compared to the
22  * original mpiJava package. Its license and copyright are listed below.
23  * See <path to ompi/mpi/java/README> for more information.
24  */
25 /*
26     Licensed under the Apache License, Version 2.0 (the "License");
27     you may not use this file except in compliance with the License.
28     You may obtain a copy of the License at
29 
30        http://www.apache.org/licenses/LICENSE-2.0
31 
32     Unless required by applicable law or agreed to in writing, software
33     distributed under the License is distributed on an "AS IS" BASIS,
34     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35     See the License for the specific language governing permissions and
36     limitations under the License.
37 */
38 
39 /*
40  * File         : mpi_Op.c
41  * Headerfile   : mpi_Op.h
42  * Author       : Xinying Li, Bryan Carpenter
43  * Created      : Thu Apr  9 12:22:15 1998
44  * Revision     : $Revision: 1.7 $
45  * Updated      : $Date: 2003/01/16 16:39:34 $
46  * Copyright: Northeast Parallel Architectures Center
47  *            at Syracuse University 1998
48  */
49 #include "ompi_config.h"
50 
51 #ifdef HAVE_TARGETCONDITIONALS_H
52 #include <TargetConditionals.h>
53 #endif
54 
55 #include "mpi.h"
56 #include "mpi_Op.h"
57 #include "mpiJava.h"
58 #include "ompi/op/op.h"
59 
Java_mpi_Op_init(JNIEnv * env,jclass clazz)60 JNIEXPORT void JNICALL Java_mpi_Op_init(JNIEnv *env, jclass clazz)
61 {
62     ompi_java.OpHandle  = (*env)->GetFieldID(env, clazz, "handle", "J");
63     ompi_java.OpCommute = (*env)->GetFieldID(env, clazz, "commute", "Z");
64 
65     ompi_java.OpCall = (*env)->GetMethodID(env, clazz, "call",
66                        "(Ljava/lang/Object;Ljava/lang/Object;I)V");
67 }
68 
Java_mpi_Op_getOp(JNIEnv * env,jobject jthis,jint type)69 JNIEXPORT void JNICALL Java_mpi_Op_getOp(JNIEnv *env, jobject jthis, jint type)
70 {
71     static MPI_Op Ops[] = {
72         MPI_OP_NULL, MPI_MAX, MPI_MIN, MPI_SUM,
73         MPI_PROD, MPI_LAND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR,
74         MPI_BXOR, MPI_MINLOC, MPI_MAXLOC, MPI_REPLACE, MPI_NO_OP
75     };
76     (*env)->SetLongField(env,jthis, ompi_java.OpHandle, (jlong)Ops[type]);
77 }
78 
setBooleanArray(JNIEnv * env,void * vec,int len)79 static jobject setBooleanArray(JNIEnv *env, void *vec, int len)
80 {
81     jobject obj = (*env)->NewBooleanArray(env, len);
82 
83     if(obj != NULL)
84         (*env)->SetBooleanArrayRegion(env, obj, 0, len, vec);
85 
86     return obj;
87 }
88 
getBooleanArray(JNIEnv * env,jobject obj,void * vec,int len)89 static void getBooleanArray(JNIEnv *env, jobject obj, void *vec, int len)
90 {
91     (*env)->GetBooleanArrayRegion(env, obj, 0, len, vec);
92 }
93 
opIntercept(void * invec,void * inoutvec,int * count,MPI_Datatype * datatype,int baseType,void * jnienv,void * object)94 static void opIntercept(void *invec, void *inoutvec, int *count,
95                         MPI_Datatype *datatype, int baseType,
96                         void *jnienv, void *object)
97 {
98     JNIEnv  *env  = jnienv;
99     jobject jthis = object;
100     jobject jin, jio;
101 
102     MPI_Aint extent;
103     int rc = MPI_Type_extent(*datatype, &extent);
104 
105     if(ompi_java_exceptionCheck(env, rc))
106         return;
107 
108     int len = (*count) * extent;
109 
110     if(baseType == 4)
111     {
112         jin = setBooleanArray(env, invec, len);
113         jio = setBooleanArray(env, inoutvec, len);
114     }
115     else
116     {
117         jin = (*env)->NewDirectByteBuffer(env, invec, len);
118         jio = (*env)->NewDirectByteBuffer(env, inoutvec, len);
119     }
120 
121     if((*env)->ExceptionCheck(env))
122         return;
123 
124     (*env)->CallVoidMethod(env, jthis, ompi_java.OpCall, jin, jio, *count);
125 
126     if(baseType == 4)
127         getBooleanArray(env, jio, inoutvec, len);
128 
129     (*env)->DeleteLocalRef(env, jin);
130     (*env)->DeleteLocalRef(env, jio);
131 }
132 
ompi_java_op_getHandle(JNIEnv * env,jobject jOp,jlong hOp,int baseType)133 MPI_Op ompi_java_op_getHandle(JNIEnv *env, jobject jOp, jlong hOp, int baseType)
134 {
135     MPI_Op op = (MPI_Op)hOp;
136 
137     if(op == NULL)
138     {
139         /* It is an uninitialized user Op. */
140         int commute = (*env)->GetBooleanField(
141                       env, jOp, ompi_java.OpCommute);
142 
143         int rc = MPI_Op_create((MPI_User_function*)opIntercept, commute, &op);
144 
145         if(ompi_java_exceptionCheck(env, rc))
146             return NULL;
147 
148         (*env)->SetLongField(env, jOp, ompi_java.OpHandle, (jlong)op);
149         ompi_op_set_java_callback(op, env, jOp, baseType);
150     }
151 
152     return op;
153 }
154 
Java_mpi_Op_free(JNIEnv * env,jobject jthis)155 JNIEXPORT void JNICALL Java_mpi_Op_free(JNIEnv *env, jobject jthis)
156 {
157     MPI_Op op = (MPI_Op)((*env)->GetLongField(env, jthis, ompi_java.OpHandle));
158 
159     if(op != NULL && op != MPI_OP_NULL)
160     {
161         int rc = MPI_Op_free(&op);
162         ompi_java_exceptionCheck(env, rc);
163         ((*env)->SetLongField(env,jthis,ompi_java.OpHandle,(long)MPI_OP_NULL));
164     }
165 }
166 
Java_mpi_Op_isNull(JNIEnv * env,jobject jthis)167 JNIEXPORT jboolean JNICALL Java_mpi_Op_isNull(JNIEnv *env, jobject jthis)
168 {
169     MPI_Op op = (MPI_Op)((*env)->GetLongField(env, jthis, ompi_java.OpHandle));
170     return op == NULL || op == MPI_OP_NULL ? JNI_TRUE : JNI_FALSE;
171 }
172