hadoop通过JNI调用cuda程序

一、通过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所指向的文件夹下

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




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值