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