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