【问题标题】:Get integer array in Hadoop's Reducer在 Hadoop 的 Reducer 中获取整数数组
【发布时间】:2016-01-14 00:38:25
【问题描述】:

我正在调用一个 cuda 代码来获取每个键的所有值的总和。 目的是通过并行操作来减少reducer所花费的时间。 但是,reducer 中的值是 IntWritable 形式。因此,我必须将它们转换为整数数组以传递给 cuda 代码。 这是我的减速器代码:

public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
   private IntWritable result = new IntWritable();

   public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
       List<Integer> numbers = new ArrayList<Integer>();
       for(IntWritable val : values)
            numbers.add(val.get());
       }
       int[] ret = ArrayUtils.toPrimitive(numbers.toArray(new Integer[numbers.size()]));
       result.set(Main.sumNumbers(ret));
       context.write(key,result);
   }
}

问题在于,为了将 IntWritable 转换为 Integer 数组,我必须遍历每个作为串行操作的值。因此,它正在增加更多的时间。 那么,有什么方法可以让我不必遍历每个值并直接转换为 int 数组?

这是映射器代码:

public static class TokenizerMapper extends
            Mapper<Object, Text, Text, IntWritable> {

        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();

        public void map(Object key, Text value, Context context)
                throws IOException, InterruptedException {
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);
            }
        }
    }

这是我的 cuda 代码:

#include <stdio.h>
#ifndef _ADDARRAY_KERNEL_H_
#define _ADDARRAY_KERNEL_H_

#ifdef __cplusplus
extern "C"
{
#endif
__global__ void add_array(int *a, int *c, int N)
{
  *c = 0;
  int i;
   for(i = 0; i<N;i++)
   {
    *c = *c + a[i];
   }
}
#ifdef __cplusplus
}
#endif 
#endif // #ifndef _ADDARRAY_KERNEL_H_

#ifdef __cplusplus
extern "C"
{
#endif

int cuda_sum(int *a_h, int N)
{   
    int *a_d, c=0;
    int *dev_c;
    cudaMalloc((void**)&dev_c, sizeof(int));
    size_t size = N * sizeof (int);

//      a_h = (int *) malloc(size);
    cudaMalloc((void **) & a_d, size);
    cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
        add_array <<<1, 1 >>>(a_d, dev_c, N);
        cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost);
    cudaFree(dev_c);
    return c;
}
#ifdef __cplusplus
}
#endif 

谢谢

【问题讨论】:

  • 您能否分享一个“cuda 代码”的链接,它是一个添加数字更有效的库吗?我假设您可以使用内置的 IntSumReducer
  • cuda 代码将创建一个自定义库以有效地添加数字
  • 你能给我这个图书馆的链接吗?然后@Pradyumna 的回复似乎还可以。
  • 看,我正在创建一个扩展名为 .so 的 cuda 库。该库使用内核调用对所有整数求和。 (就像任何 cuda 代码中的简单添加操作一样)。所以,我需要给一个整数数组作为这个 cuda 库的输入。
  • 已经提供的答案有什么不足吗?

标签: java hadoop mapreduce


【解决方案1】:

我建议你应该做如下的事情

public static class IntSumReducer extends Reducer<Text, IntWritable, Text, ArrayPrimitiveWritable>{ private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<ArrayPrimitiveWritable> values, Context context) throws IOException,InterruptedException { int[] ret = values.next(); result.set(Main.sumNumbers(ret)); context.write(key,result); } }

ArrayPrimitiveWritable 将为您完成这项工作。

【讨论】:

  • 没有可用于值的方法“next()”。
  • 是 values.iterator().next()
  • 它显示错误并建议将'ret'类型更改为'ArrayPrimitiveWritable'
【解决方案2】:
public static class IntSumReducer extends Reducer<Text, ArrayPrimitiveWritable, Text, IntWritable>{
        private IntWritable result = new IntWritable();
        public void reduce(Text key, Iterable<ArrayPrimitiveWritable> values, Context context) throws IOException,InterruptedException {
            ArrayPrimitiveWritable arrayOfInts = values.iterator().next();
            final int[] ret = (int [])arrayOfInts.get();
            result.set(Main.sumNumbers(ret));
            context.write(key,result);
        }
    }

我已经稍微修改了代码以便它可以工作,但是我还没有运行它,你可以试一试吗?我坚持使用刚刚更新的 ArrayPrimitiveWritable,这样编译错误就会消失。

【讨论】:

  • 上述代码出现错误。这是screenshot
  • 也粘贴您的映射器代码,我认为您也需要在那里进行一些更改
  • 我不确定,为什么你要经历这么多!!,你从你的映射器发送一个硬编码的 1,那么你为什么要提取值并做一个总和?为什么你不能继续在 for 循环中添加一个 for(IntWritable val : values) sum++; } 在减速器中像上面这样的东西,对于你的情况应该足够了
  • 这不是我的目标。我想减少将值从 O(n) 求和到 O(logn) 的时间。所以,为此,我将来会使用 cuda 的推力库。它将在 O(logn) 中求和。因此,出于这个原因,我希望在 O(1) 中的 reducer 中进行转换操作
  • 哦,好吧,我不认为你可以实现这一点,尤其是 WordCount 类型的问题,要在减速器中实现 O(1),它需要提供一个可迭代的集合
猜你喜欢
  • 2012-05-18
  • 1970-01-01
  • 2015-04-27
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 2015-12-14
相关资源
最近更新 更多