首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >金属计算核的库达核等价

金属计算核的库达核等价
EN

Stack Overflow用户
提问于 2019-01-18 23:09:17
回答 1查看 479关注 0票数 0

我有一个简单的金属计算内核,我试图使一个Cuda等价。金属内核的源代码是

代码语言:javascript
复制
#include <metal_stdlib>
using namespace metal;

constant uint stride [[function_constant(0)]];
constant float dt    [[function_constant(1)]];
constant float a     [[function_constant(2)]];
constant float b     [[function_constant(3)]];

float2 f(const float2 x) {
    return float2(a, -b)*x.yx;
}

kernel void harmonic_occilator_stride(device float2 *x [[buffer(0)]],
                                             uint    i [[thread_position_in_grid]]) {
    for (uint j = 0; j < stride; j++) {
        x[i] += dt*f(x[i]);
    }
}

我第一次尝试将其转换为Cuda,在编译ptx文件时会导致大量错误。

代码语言:javascript
复制
__constant__ uint  stride;
__constant__ float dt;
__constant__ float a;
__constant__ float b;

__device__ float2 f(const float2 x) {
    return float2(a, -b)*x.yx;
}

extern "C" __global__ void harmonic_occilator_stride(float2 *x) {
    size_t i = blockIdx.x*blockDim.x + threadIdx.x;
    for (uint j = 0; j < stride; j++) {
        x[i] += dt*f(x[i]);
    }
}

它首先不喜欢的是x.yx。在金属中,这将颠倒float2内容的顺序。如何在Cuda中反转或更改向量的访问顺序?

接下来,它也不喜欢float2(a, -b)。这就产生了一个错误“没有合适的构造函数在floatfloat2之间进行转换”。如何构造向量文字?

它抱怨的最后一件事是,float没有float运算符,dt*f(x[i])没有float2。如果删除dt*并将其设置为x[i] += f(x[i]),它会抱怨float2float2没有+=操作符。如何对这些类型执行操作,以及如何将向量和标量相乘?

在Metal中,当我将函数定义为function_constant时,当内核函数在运行时加载时,金属内核编译器将JIT是内核的一个特定的优化版本。Cuda有这个功能吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-18 23:36:50

我现在只看了一眼金属规范。我不打算完全回答你的最后一个问题。但我认为,只要处理各种组件,遵循由金属定义的算术规则,就可以从概念上回答语法问题。

它也不喜欢float2(a,-b)。这就产生了一个错误“没有合适的构造函数在浮点数和float2之间进行转换”。如何构造向量文字?

为此,请使用头文件vector_functions.h (或.hpp)中定义的函数。(参见下面的示例)在vector_types.h中为CUDA定义的向量类型没有构造函数。

它首先不喜欢的是x.yx。在金属中,这将颠倒float2内容的顺序。如何在Cuda中反转或更改向量的访问顺序?

CUDA没有这种内置的多向量元素处理/swizzling功能。只需使用元素类型对元素执行操作即可。

代码语言:javascript
复制
metal:  return float2(a, -b)*x.yx;

CUDA:   #include <vector_functions.h>
        ...
        return make_float2(a*x.y, -b*x.x);

它抱怨的最后一件事是,行dtf(xi)没有*操作符,行dtf(Xi)没有float2。如果删除dt并将其设置为xi += f(xi),它会抱怨float2和float2没有+=运算符。如何对这些类型执行操作,以及如何将向量和标量相乘?

类似于上面的内容,您需要构造等价的算术元素。

代码语言:javascript
复制
metal:  x[i] += dt*f(x[i]);

CUDA:   float2 temp1 = x[i];
        float2 temp2 = f(temp1);
        temp1.x += dt*temp2.x;
        temp1.y += dt*temp2.y;
        x[i] = temp1;

应该可以定义一组你自己的向量类型,如果你想这样做的话,可以匹配金属的大部分功能。我在这里描述的东西使用的是“内建”,如果您想用构造器、算术运算符等来创建自己的类型,可以是一个模型。

关于最后一个问题,CUDA并不总是像你描述金属的那样在运行时使用JIT。最接近您所描述的东西可能是使用C++模板的东西,这是由数据自动化系统支持的。一般来说,如果您可以将金属操作转换为等效的C++操作,那么您应该能够直接实现数据自动化系统中的操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54262581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档