hadoop通过JNI调用cuda程序

原创 2013年12月04日 15:12:02

一、通过JNI,将C写成的cuda编译成动态链接库

1、 写一个java类,类中包含一个native的函数,导入.so动态链接库,注意,linux中,SiftGPU其实指的是libSiftGPU.so。

package nfs.sil.image.sift.main;
import java.util.List;
import java.lang.reflect.*;
import java.util.ArrayList;
import net.semanticmetadata.lire.imageanalysis.sift.Feature;

public class FeatureExtractSIFT_GPU 
{
	static{
		try{
			System.loadLibrary("SiftGPU");
		}
		catch(UnsatisfiedLinkError e){
			System.err.println("Cannot load SIFT library\n"+e.toString());
		}
	}
	
	public FeatureExtractSIFT_GPU(){
	//	features = new ArrayList();
	}
	
	public native void ExtractSIFT(String filename, List features) throws Exception; 
	public native void ExtractSIFT(float[] data, int width, int height, List feature) throws Exception;
	
	public List ExtractFeatures(float[] data, int width, int height){
		List features = new ArrayList();
		List result = new ArrayList();
		
		try{
			ExtractSIFT(data, width, height, features);
		}catch (Exception e){
			e.printStackTrace();
			return null;
		}
		
		for(int i = 0; i < features.size(); ++i){
			float[] vec = features.get(i);
			Feature temp = new Feature();
			temp.location = new float[2];
			temp.location[0] = vec[0];
			temp.location[1] = vec[1];
			temp.scale = vec[2];
			temp.descriptor = new float[128];
			System.arraycopy(vec, 4, temp.descriptor, 0, 128);
			result.add(temp);
		}

		return result;
	}
	
	public List ExtractFeatures(String filename){
		List features = new ArrayList();
		List result = new ArrayList();
		
		try{
			ExtractSIFT(filename类, features);
		}catch (Exception e){
			e.printStackTrace();
			return null;
		}

		for(int i = 0; i < features.size(); ++i){
			float[] vec = features.get(i);
			Feature temp = new Feature();
			temp.location = new float[2];
			temp.location[0] = vec[0];
			temp.location[1] = vec[1];
			temp.scale = vec[2];
			temp.descriptor = new float[128];
			System.arraycopy(vec, 4, temp.descriptor, 0, 128);
			result.add(temp);
		}

		return result;
	}
	public static void main(String[] args){
		
		String filename = "01.png";
		System.out.println("compute 1!");
		FeatureExtractSIFT_GPU t = new FeatureExtractSIFT_GPU();
		try{
			t.ExtractFeatures(filename);
		}catch (Exception e){
			e.printStackTrace();
			return;
		}
		System.out.println("compute success!");
      
	}
}

2、javac编译这个类生成.class文件,我直接用eclipse编译了。

3、在项目目录下的./bin文件目录下,使用如下命令,生成C++函数的头文件

javah -jni -classpath . nfs.sil.image.sift.main.FeatureExtractSIFT_GPU

在该目录下会出现一个nfs_sil_image_sift_main_FeatureExtractSIFT_GPU.h的头文件,文件内容如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class nfs_sil_image_sift_main_FeatureExtractSIFT_GPU */

#ifndef _Included_nfs_sil_image_sift_main_FeatureExtractSIFT_GPU
#define _Included_nfs_sil_image_sift_main_FeatureExtractSIFT_GPU
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     nfs_sil_image_sift_main_FeatureExtractSIFT_GPU
 * Method:    ExtractSIFT
 * Signature: (Ljava/lang/String;Ljava/util/List;)V
 */
JNIEXPORT void JNICALL Java_nfs_sil_image_sift_main_FeatureExtractSIFT_1GPU_ExtractSIFT__Ljava_lang_String_2Ljava_util_List_2
  (JNIEnv *, jobject, jstring, jobject);

/*
 * Class:     nfs_sil_image_sift_main_FeatureExtractSIFT_GPU
 * Method:    ExtractSIFT
 * Signature: ([FIILjava/util/List;)V
 */
JNIEXPORT void JNICALL Java_nfs_sil_image_sift_main_FeatureExtractSIFT_1GPU_ExtractSIFT___3FIILjava_util_List_2
  (JNIEnv *, jobject, jfloatArray, jint, jint, jobject);

#ifdef __cplusplus
}
#endif
#endif

4、实现nfs_sil_image_sift_main_FeatureExtractSIFT_GPU.cu,实现.h中的C++函数

5、编译,生成动态链接库

先把所有的.cu文件用nvcc编译成.o文件

最后 gcc -Wall -rdynamic 'pkg-config --cflags opencv' -fopenmp -shared -L/home/OpenCV-2.4.3/lib -lopencv_core -lopencv_highgui -L/usr/local/cuda/lib -lcudart -o libSiftGPU.so $(ALL)


二、使用hadoop运行程序

注意,在需要运行的类中包含,将一些参数分析交给GenericOptionsParser做。

GenericOptionsParser parser = new GenericOptionsParser(conf, args);
String[]otherArgs = parser.getRemainingArgs();

运行命令

hadoop jar imageRetrieval.jar nfs.sil.image.sift.index.SiftHadoopImageIndexer  -files libSiftGPU.so images index

-files意思是把libSiftGPU.so拷贝到工作机上。

另一个可行的办法是,手动将libSiftGPU.so拷贝到java.library.path所指向的文件夹下

咳咳,这种方法比较暴力~~




相关文章推荐

Java通过JNI调用CUDA程序

在这里不讨论为什么不使用Jcuda,只是说明如何通过JNI(Java Native Interface)调用CUDA程序 (1)编写java程序通过native关键字声明调用接口 (2)生成调用头...

Linux下,JAVA通过JNI调用CUDA程序

最近在做这一块,通过我自己的程序,简要写一些笔记。简单说来,先通过一个java类,调用C++的库中的函数 1、先写java类,写好类后,使用javac FeatureExtract.java编译 ...

Java通过JNI调用CUDA

——NG     这段时间因为工作需要,要用到在java中调用cuda程序,但是令人蛋疼的是网上这方面的资料几乎没有,所以只好我自己摸索。我的想法是通过java的JNI接口调用cuda,但是很明显正常...

如何在Hadoop集群运行JNI程序

点击查看原文 hadoop是基于java的数据计算平台,引入第三方库,例如C语言实现的开发包将会大大增强数据分析的效率和能力。 阿里巴巴内部使用的分词软件(用c++实现的,以下简称WS包...

Hadoop使用JNI调用C++动态库

由于工作需要,要在Hadoop中使用C++的代码,故开始研究在hadoop中使用Java本地接口,实现流程如下: 1、使用java封装C++接口; 2、使用C++实现该接口,并编译生成动态库; 3、将...

java 调用cuda程序

【转载】 原链接地址 http://hpcbbs.it168.com/thread-6014-1-1.html   由于CUDA不支持Java下直接调用,因此,想在Java程序中把计算量密集的一...

Android通过JNI调用驱动程序(完全解析实例)

要达到的目的:android系统中,用JAVA写界面程序,调用jni中间库提供的接口,去操作某个驱动节点,实现read,writer ioctl等操作!这对底层驱动开发人员是很重要的一个调试通道,也是...

jni调用java数组导致VM aborting,安卓程序莫名闪退

如果你的程序使用了如下的场景: jint JNICALL Java_Test_WriteRCArray( JNIEnv *env, jobject obj, jintArray buf) {  ji...

java开发第一个JNI示例程序(基于linux操作系统)--java调用native方法

大家都知道,通过jni可以实现java和c以及c++的交互,但是这对于新手来说,想实现自己的本地调用还是有一定困难,万事开头难,这里我将用一个最简单的程序向大家展示jni的真面目。项目的基本流程: ...

Windows 7下,java jni调用C程序demo,编译器为mingw

网上看了很多的
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hadoop通过JNI调用cuda程序
举报原因:
原因补充:

(最多只允许输入30个字)