【问题标题】:JNI with openmpJNI 与 openmp
【发布时间】:2015-10-28 23:49:20
【问题描述】:

我正在尝试从 Java 调用 C 函数。 C 函数使用 openmp 并行一个 for 循环。然而,程序结束后,结果显示只使用了一个线程。所以,我想知道将openmp与JNI一起使用是否可行。

谢谢

下面是我的clang信息和makefile的内容:

clang version 3.5.0 
Target: x86_64-apple-darwin15.0.0
Thread model: posix


CC = gcc
CLANG = clang-omp
CFLAGS = -c -Wall -fPIC -std=c11
OMP = -fopenmp
LIBFLAG = -dynamiclib
INCPATH = -I/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/include -I/usr/local/Cellar/libiomp/20150701/include/libiomp -I/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/include/darwin -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers
LIBPATH = -L./ -L/usr/local/Cellar/libiomp/20150701/lib -lepanet -liomp5
all: library

library: *.o
    $(CC) $(LIBFLAG) $(OMP) -o libJNIFitness.jnilib *.o 

*.o: *.c
    $(CC) $(OMP) $(CFLAGS) $(INCPATH) *.c

clean:
    rm *.o libJNIFitness.jnilib

【问题讨论】:

  • 是的,我这样做了cholmod-in-java
  • 什么操作系统,什么编译器,你使用了什么编译器选项,你的硬件是什么?
  • 它是 OSX EI Capitan 所以编译器是 LLVM,我使用 clang-omp 编译 C 代码。
  • 您使用的是什么版本的 Clang?你的编译器选项是什么?你有没有用 openmp 和 clang 写过一个小小的 hello world 来看看你得到了多个线程?如果你没有注意到最近有几个关于 Clang 和 OpenMP 问题的问题。
  • @Zboson 感谢您的回复,我添加了您要求的信息。我的测试程序仅使用 C 运行良好。

标签: java-native-interface openmp


【解决方案1】:

当然,您可以在 JNI 方法中运行 OpenMP。观看以下示例(其中包括 JNI 代码 [Java 和 C-counter-side] 和 Makefile)。它通过使用多个线程的近似值来计算 pi,并且在计算它之前,每个线程在屏幕上标识自己。

您可能需要修改 CC 和 JDK 变量以适应您的环境以及一些 Linux/gcc 与 MacOsX/clang 标志(例如将 -fPIC -DPIC 更改为 -dynamiclib 等)。然后你可以通过执行来运行它:

make run

并输出以下内容

LD_LIBRARY_PATH=. JNItest
within Java_JNItest_CalculatePi
Java_JNItest_calculatepi: I'm thread 0 out of 4
Java_JNItest_calculatepi: I'm thread 2 out of 4
Java_JNItest_calculatepi: I'm thread 1 out of 4
Java_JNItest_calculatepi: I'm thread 3 out of 4
returning to Java...
In Java, the value of pi is 3.1415926535896825

文件JNItest.java

public class JNItest
{
    static { System.loadLibrary("pi"); }

    public static native double CalculatePi (long nsteps);

    public static void main(String args[])
    {
        System.out.println ("In Java, the value of pi is " +
          new JNItest().CalculatePi(100_000_000));
    }
}

文件 pi.c

#include <stdio.h>
#include <JNItest.h>

JNIEXPORT jdouble JNICALL Java_JNItest_CalculatePi
  (JNIEnv * env, jclass jc, jlong nsteps)
{
    jdouble h, area, x;

    printf ("within Java_JNItest_CalculatePi\n");

    h = 1.0 / (jdouble) nsteps;
    area = 0.0;
    #pragma omp parallel private(x)
    {
        int i;
        printf ("Java_JNItest_calculatepi: I'm thread %d out of %d\n",
            omp_get_thread_num(), omp_get_num_threads());

        #pragma omp for reduction(+:area)
        for (i = 1; i <= nsteps; i++)
        {
            x = h * ((double)i - 0.5);
            area += (4.0 / (1.0 + x*x));
        }
    }

    printf ("returning to Java...\n");

    return h * area;
}

文件ma​​kefile

all: JNItest.class libpi.so

CC=gcc
JDK=/usr/lib/jvm/java-7-openjdk-amd64

JNItest.class: JNItest.java
    $(JDK)/bin/javac JNItest.java

JNItest.h: JNItest.java
    $(JDK)/bin/javah JNItest

libpi.so: JNItest.h
    $(CC) -fopenmp -fPIC -DPIC pi.c -I. -I$(JDK)/include -shared -o libpi.so

clean:
    rm libpi.so JNItest.h JNItest.class

run: JNItest.class libpi.so
    LD_LIBRARY_PATH=$(PWD):$(LD_LIBRARY_PATH) $(JDK)/bin/java JNItest

【讨论】:

    猜你喜欢
    • 2021-08-10
    • 2018-08-04
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多