my @s=<1 2 3 2 3 4>;
say reduce {$^a < $^b}, @s;
say [<] @s;
# --------
# True
# False
Run Code Online (Sandbox Code Playgroud)
我的问题有两个方面:首先,为什么归约元<运算符对运算符的处理方式不同?似乎归约元操作估计使用了一个变量,在从true到false的第一个更改中,保留了该更改,原因是:
say [\<] @s;
# ----------
# (True True True False False False)
Run Code Online (Sandbox Code Playgroud)
其次,我也想在reduce函数中使用它,即,在reduce函数的花括号内引入一些代码,以使其产生与reduce元运算符相同的结果。我该怎么做?谢谢。
我正在学习OpenMP,并遇到了以下示例:
#pragma omp parallel shared(n,a,b,c,d,sum) private(i)
{
#pragma omp for nowait
for (i=0; i<n; i++)
a[i] += b[i];
#pragma omp for nowait
for (i=0; i<n; i++)
c[i] += d[i];
#pragma omp barrier
#pragma omp for nowait reduction(+:sum)
for (i=0; i<n; i++)
sum += a[i] + c[i];
} /*-- End of parallel region --*/
Run Code Online (Sandbox Code Playgroud)
在最后一个for循环中,有一个nowait和一个reduction子句.它是否正确?减少条款不需要同步吗?
我有关于基于warp的并行缩减的想法,因为warp的所有线程都是按照定义同步的.
因此,我们的想法是输入数据可以减少64倍(每个线程减少两个元素),而不需要任何同步.
与Mark Harris的原始实现相同,减少应用于块级别,数据应用于共享内存. http://gpgpu.org/static/sc2007/SC07_CUDA_5_Optimization_Harris.pdf
我创建了一个内核来测试他的版本和基于warp的版本.
内核本身完全相同地将BLOCK_SIZE元素存储在共享内存中,并将其结果输出到输出数组中的唯一块索引.
算法本身工作正常.测试完整的一个数组以测试"计数".
实现的功能体:
/**
* Performs a parallel reduction with operator add
* on the given array and writes the result with the thread 0
* to the given target value
*
* @param inValues T* Input float array, length must be a multiple of 2 and equal to blockDim.x
* @param targetValue float
*/
__device__ void reductionAddBlockThread_f(float* inValues,
float &outTargetVar)
{
// code of the below functions
}
Run Code Online (Sandbox Code Playgroud)
1.执行他的版本:
if (blockDim.x >= 1024 …Run Code Online (Sandbox Code Playgroud) 我正在尝试减少CUDA,我真的是一个新手.我目前正在研究NVIDIA的示例代码.
我想我真的不确定如何设置块大小和网格大小,特别是当我的输入数组大于(512 X 512)而不是单个块大小时.
这是代码.
template <unsigned int blockSize>
__global__ void reduce6(int *g_idata, int *g_odata, unsigned int n)
{
extern __shared__ int sdata[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*(blockSize*2) + tid;
unsigned int gridSize = blockSize*2*gridDim.x;
sdata[tid] = 0;
while (i < n)
{
sdata[tid] += g_idata[i] + g_idata[i+blockSize];
i += gridSize;
}
__syncthreads();
if (blockSize >= 512) { if (tid < 256) { sdata[tid] += sdata[tid + 256]; } __syncthreads(); }
if (blockSize …Run Code Online (Sandbox Code Playgroud) 我被一些烦人的事情绊倒了。我知道 haskell 与弱头部范式 (WHNF) 一起工作,我知道这是什么。将以下代码输入 ghci(我正在使用命令 :sprint 将表达式简化为 WHNF,据我所知。):
let intlist = [[1,2],[2,3]]
:sprint intlist
Run Code Online (Sandbox Code Playgroud)
给intlist = _这使得完全意义的我。
let stringlist = ["hi","there"]
:sprint stringlist
Run Code Online (Sandbox Code Playgroud)
给stringlist = [_,_]
这个已经让我困惑。但是之后:
let charlist = [['h','i'], ['t','h','e','r','e']]
:sprint charlist
Run Code Online (Sandbox Code Playgroud)
出人意料地给出 charlist = ["hi","there"]
据我了解 Haskell,字符串只不过是字符列表,这似乎是通过检查类型"hi" :: [Char]和['h','i'] :: [Char].
我很困惑,因为根据我的理解,上面的所有三个示例或多或少都相同(列表列表),因此应该减少到相同的 WHNF,即 _。我错过了什么?
谢谢
haskell functional-programming reduction ghci weak-head-normal-form
假设我有一个f接受一些输入并产生数字的函数.在该函数内f,根据输入创建列表,然后减少(例如使用foldl' g)以产生最终输出数.因为毕竟要减少中间列表,是否可以应用reduce函数g 而不表示中间列表.这里的目标是限制用于存储(或表达,如果'存储'不太准确的单词)列表的存储器.
为了说明这个,这个函数foldPairProduct占用O(N1 * N2)了中间列表的空间(由于表达和惰性评估,消耗的空间可能更复杂,但我认为它是成比例的或更糟).以下N1, N2是两个输入列表的大小.
foldPairProduct :: (Num a, Ord a) => (a -> a -> a) -> [a] -> [a] -> a
foldPairProduct f xs ys = foldl1 f [ x*y | x <- xs, y <- ys]
Run Code Online (Sandbox Code Playgroud)
逻辑的另一种实现是foldPairProduct',它占用O(2 * 2)空间.
foldPairProduct' :: Num a => (Maybe a -> Maybe a -> Maybe a) -> [a] -> [a] -> Maybe a …Run Code Online (Sandbox Code Playgroud) 如何使用sse intrinsics获得浮点向量的和元素(减少)?
简单的串口代码:
void(float *input, float &result, unsigned int NumElems)
{
result = 0;
for(auto i=0; i<NumElems; ++i)
result += input[i];
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个OpenCL版本来减少一个float数组.
为实现这一目标,我在网上找到了以下代码段:
__kernel void sumGPU ( __global const double *input,
__global double *partialSums,
__local double *localSums)
{
uint local_id = get_local_id(0);
uint group_size = get_local_size(0);
// Copy from global memory to local memory
localSums[local_id] = input[get_global_id(0)];
// Loop for computing localSums
for (uint stride = group_size/2; stride>0; stride /=2)
{
// Waiting for each 2x2 addition into given workgroup
barrier(CLK_LOCAL_MEM_FENCE);
// Divide WorkGroup into 2 parts and add elements 2 by 2
// between local_id and local_id + stride
if …Run Code Online (Sandbox Code Playgroud) 我试了很长时间来减少haskell中的这个功能,我想举例如:
mySum x y = x + y
mySum x y = (+) x y
mySum x = (+) x
mySum = (+) -- it's Messi's goal!
Run Code Online (Sandbox Code Playgroud)
我的功能有点复杂,但我真的不能这样做,我一直在寻找,我知道有一些技术,比如修改右侧,并使用flip.我试过了,我在这里堆积:
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f x y = map (uncurry f) (zip x y)
Run Code Online (Sandbox Code Playgroud)
脚步:
zipWith' f x y = map (uncurry f) (zip x y)
zipWith' f x y = flip map (zip x y) (uncurry f)
zipWith' f …Run Code Online (Sandbox Code Playgroud) 这是我想要转换为openCL的循环.
for(n=0; n < LargeNumber; ++n) {
for (n2=0; n2< SmallNumber; ++n2) {
A[n]+=B[n2][n];
}
Re+=A[n];
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我所拥有的,但我知道这是不正确的,并且缺少一些东西.
__kernel void openCL_Kernel( __global int *A,
__global int **B,
__global int *C,
__global _int64 Re,
int D)
{
int i=get_global_id(0);
int ii=get_global_id(1);
A[i]+=B[ii][i];
//barrier(..); ?
Re+=A[i];
}
Run Code Online (Sandbox Code Playgroud)
我是这类事的初学者.首先我知道我无法将全局双指针传递给openCL内核.如果可以的话,在发布解决方案之前等待几天左右,我想为自己解决这个问题,但如果你能帮我指出正确的方向,我将不胜感激.