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