Cuda C 上任意大小的矩阵转置(具有共享内存)

2024-02-11

我无法找到在 CUDA C 中使用共享内存转置非方矩阵的方法。(我是 CUDA C 和 C 的新手)

In 这篇博文 https://developer.nvidia.com/blog/efficient-matrix-transpose-cuda-cc/展示了如何转置矩阵的有效方法(通过共享内存合并转置)。但它只适用于方阵。

还提供了代码github https://github.com/NVIDIA-developer-blog/code-samples/blob/master/series/cuda-cpp/transpose/transpose.cu(与博客上的相同)。

StackOverflow 上有一个类似的question https://stackoverflow.com/questions/13208982/non-square-matrix-transpose-with-shared-mem-in-cuda. There TILE_DIM = 16已设置。但通过该实现,每个线程只需将矩阵的一个元素复制到结果矩阵。

这是我当前的实现:

__global__ void transpose(double* matIn, double* matTran, int n, int m){
    __shared__ double tile[TILE_DIM][TILE_DIM];
    int i_n = blockIdx.x*TILE_DIM + threadIdx.x;
    int i_m = blockIdx.y*TILE_DIM + threadIdx.y; // <- threadIdx.y only between 0 and 7

    // Load matrix into tile
    // Every Thread loads in this case 4 elements into tile.
    int i;
    for (i = 0; i < TILE_DIM; i += BLOCK_ROWS){
        if(i_n < n  && (i_m+i) < m){
            tile[threadIdx.y+i][threadIdx.x] = matIn[n*(i_m+i) + i_n];
        } else {
            tile[threadIdx.y+i][threadIdx.x] = -1; 
        }
    }
    __syncthreads();

    for (i = 0; i < TILE_DIM; i += BLOCK_ROWS){
        if(tile[threadIdx.x][threadIdx.y+i] != -1){ // <- is there a better way?
            if(true){      // <- what should be checked here?
                matTran[n*(i_m+i) + i_n] = tile[threadIdx.x][threadIdx.y+i];
            } else {
                matTran[m*i_n + (i_m+i)] = tile[threadIdx.x][threadIdx.y+i];
            }
        }
    }
}

其中 4 个元素从线程复制到图块中。此外,图块中的四个元素也被复制回结果矩阵中。

这里是内核配置<<<a, b>>>:

where a: (ceil(n/TILE_DIM), ceil(n/TILE_DIM))  (-> is casted to doubles) and 
      b: (TILE_DIM, BLOCK_ROWS) (-> (32, 8))

我目前正在使用if(tile[threadIdx.x][threadIdx.y+i] != -1)- 确定哪个线程应该复制到结果矩阵的语句(可能还有另一种方法)。就我目前的知识而言,其行为如下:在一个块中,线程索引(x, y)将数据复制到图块和线程索引中(y, x)将数据复制回结果矩阵。

我插入了另一个if- 确定将数据复制到哪里的语句,因为有 2(?) 个可能的目的地,具体取决于线程索引。现在true插入那里,但我尝试了很多不同的东西。我能想到的最好的办法是if(threadIdx.x+1 < threadIdx.y+i),它转置3x2- 矩阵成功。

有人可以解释一下,我通过写回到结果矩阵中缺少什么吗?显然只有一个目的地是正确的。使用

matTran[n*(i_m+i) + i_n] = tile[threadIdx.x][threadIdx.y+i];

正如博客中提到的应该是正确的,但我不明白,为什么它不适用于非平方矩阵?


我把问题过于复杂化了。Here https://devblogs.nvidia.com/efficient-matrix-transpose-cuda-cc/,索引并没有像我想象的那样交换。它们是使用线程/块的 Y 坐标和 X 坐标重新计算的。这是片段:

i_n = blockIdx.y * TILE_DIM + threadIdx.x;  
i_m = blockIdx.x * TILE_DIM + threadIdx.y

这是更正后的代码:

__global__ void transposeGPUcoalescing(double* matIn, int n, int m, double* matTran){
    __shared__ double tile[TILE_DIM][TILE_DIM];
    int i_n = blockIdx.x * TILE_DIM + threadIdx.x;
    int i_m = blockIdx.y * TILE_DIM + threadIdx.y; // <- threadIdx.y only between 0 and 7

    // Load matrix into tile
    // Every Thread loads in this case 4 elements into tile.
    int i;
    for (i = 0; i < TILE_DIM; i += BLOCK_ROWS){
        if(i_n < n  && (i_m+i) < m){
            tile[threadIdx.y+i][threadIdx.x] = matIn[(i_m+i)*n + i_n];
        }
    }
    __syncthreads();

    i_n = blockIdx.y * TILE_DIM + threadIdx.x; 
    i_m = blockIdx.x * TILE_DIM + threadIdx.y;

    for (i = 0; i < TILE_DIM; i += BLOCK_ROWS){
        if(i_n < m  && (i_m+i) < n){
            matTran[(i_m+i)*m + i_n] = tile[threadIdx.x][threadIdx.y + i]; // <- multiply by m, non-squared!

        }
    }
}

谢谢this https://stackoverflow.com/questions/53950966/matrix-transpose-with-shared-memory-with-arbitary-size-on-cuda-c#comment94741856_53950966评论发现错误:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cuda C 上任意大小的矩阵转置(具有共享内存) 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • 使用 Unity 在构造函数中使用属性依赖注入

    好的 我在基类中定义了一个依赖属性 我尝试在其派生类的构造函数内部使用它 但这不起作用 该属性显示为 null Unity 在使用 container Resolve 解析实例后解析依赖属性 我的另一种选择是将 IUnityContaine
  • 使用Physics.Raycast 和Physics2D.Raycast 检测对象上的点击

    我的场景中有一个空的游戏对象 带有 2D 组件盒碰撞器 我将脚本附加到该游戏对象 void OnMouseDown Debug Log clic 但是当我点击我的游戏对象时 没有任何效果 你有什么想法 如何检测我的盒子碰撞器上的点击 使用光
  • 为 Visual Studio 2013 编译 Tesseract

    我正在尝试使用tesseract在 Visual Studio 2013 中 我在链接器 gt 输入 不是 libtesseract302 static lib 中使用 libtesseract302 lib 一切都正常 并且已编译并运行
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 在 C# 中循环遍历文件文件夹的最简单方法是什么?

    我尝试编写一个程序 使用包含相关文件路径的配置文件来导航本地文件系统 我的问题是 在 C 中执行文件 I O 这将是从桌面应用程序到服务器并返回 和文件系统导航时使用的最佳实践是什么 我知道如何谷歌 并且找到了几种解决方案 但我想知道各种功
  • C# Dns.GetHostEntry 不返回连接到 WiFi 的移动设备的名称

    我有一个 C 中的 Windows 窗体应用程序 我试图获取列表中所有客户端的主机名 下面给出的是 ra00l 来自此链接的代码示例 GetHostEntry 非常慢 https stackoverflow com questions 99
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 使用 JNI 从 Java 代码中检索 String 值的内存泄漏

    我使用 GetStringUTFChars 从使用 JNI 的 java 代码中检索字符串的值 并使用 ReleaseStringUTFChars 释放该字符串 当代码在 JRE 1 4 上运行时 不会出现内存泄漏 但如果相同的代码在 JR
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • Server.MapPath - 给定的物理路径,预期的虚拟路径

    我正在使用这行代码 var files Directory GetFiles Server MapPath E ftproot sales 在文件夹中查找文件 但是我收到错误消息说 给定物理路径但虚拟路径 预期的 我对在 C 中使用 Sys
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 堆栈里面有什么?

    如果我运行一个程序 就像 include
  • 使用 JavaScript 上传文件夹及其所有内容

    如何使用 JavaScript 客户端 上传文件夹的内容 FileSystem API尚未被Chrome以外的浏览器采用 我只得到一个带有文件夹名称的文件项 这应该是可能的 因为 Google Drive 允许删除文件夹 所有内容 文件夹和
  • 为视频添加标签

    我必须编写一个简单的视频播放器 可以在特定时间显示一些字幕 链接或图片 如 YouTube 上的图片 我不知道如何使用 QVideoWidget 显示任何内容 我找不到任何有用的课程来做到这一点 您能给我一些建议吗 我按照你的方式做了 但是
  • 更改数据框的列类型

    我有一个包含大量值的数据框 数据框如下 gt datedPf date ticker quantity 96828 2013 01 11 ABT 700 96829 2013 01 11 AMD 9600 96830 2013 01 11
  • Android删除SIM卡联系人的方法

    下面是我从手机中删除联系人的代码 Uri contactUri Uri withAppendedPath PhoneLookup CONTENT FILTER URI Uri encode phone Cursor cur mContext
  • 单击外部链接时更改谷歌地图标记图标?

    我有一个谷歌地图 上面有很多标记 从 MySQL 数据库收集 我当前正在使用以下代码在单击标记时更改标记的图标 var redbikeicon images bike red png marker new google maps Marke
  • 即时应用程序功能模块中的资源合并

    在即时应用程序功能模块中 我导入一个 aar 使用来自 Maven 存储库的 api 语句 其中包含其清单中的活动声明以及此声明中使用的 样式 资源 由于在基本功能项目中找不到样式资源 因此清单合并失败 功能模块中导入的 aar 的资源似乎
  • IE 11 添加类 + 删除类

    我无法让此代码在 Internet Explorer 11 上运行 我知道此段导致了问题 如果我在激活此代码的情况下上传文件 IE 11 会将我网站的整个部分完全显示为空白 没有它 它会在我的网站上显示信息 但它的功能显然不一样 我查过各种
  • select2 动态改变项目

    我有两个链接的选择 第一个选择的每个值决定哪些项目将显示在第二个选择中 第二个选择的值存储在二维数组中 id 1 text a id 2 text b id 1a text aa id 1b text ba 第一个选择值确定用于填充第二个选
  • LDA Mallet 调用进程错误

    我正在尝试实现以下代码 import os os environ update MALLET HOME r c mallet 2 0 8 mallet path C mallet 2 0 8 bin mallet ldamallet gen
  • seasonal_decompose:操作数无法与系列上的形状一起广播

    我知道关于这个话题有很多问题 但没有一个能帮助我解决这个问题 我真的很坚持这个 用一个简单的系列 0 2016 01 31 266 2016 02 29 235 2016 03 31 347 2016 04 30 514 2016 05 3
  • 带有外部图像的 box2d-js 元素

    到目前为止 在各种 box2d js 实现的示例中 我只能找到形状 球 盒子 等 中定义的元素 有没有办法创建由图像定义的元素 例如一块巨石 您可以使用b2PolyDef and b2PolyShape对象来创建多边形 本文档 http w
  • Haskell - 简单构造函数比较(?)函数

    在我的项目中 我创建了一种数据类型 它可以保存几种类型的值之一 data PhpValue VoidValue IntValue Integer BoolValue Bool 我现在想做的是有一种简单的方法来检查两个值是否PhpValue类
  • Google 身份验证器作为公共服务提供吗?

    是否有公共 API 可以使用 双因素身份验证 在自运行 例如 LAMP 堆栈 Web 应用程序上 The project http code google com p google authenticator 是开源的 我没用过 但它使用记
  • vertx 应用程序中的 CORS 问题无法正常工作

    我的 Vertx 服务器驻留在服务器 A 中 客户端驻留在服务器 B 中 当我尝试访问 vertx 服务器时 弹出 CORS 错误 我添加了一些服务器端代码来处理 CORS 问题 但它不起作用 我们是否需要在客户端添加一些标头 我在这里缺少
  • Yii:需要 .php 文件

    我用 Yii 开发一个项目 我需要一个普通的 php 文件 不是组件 不是类 只是 PHP 函数定义的常规序列 在 Yii 框架下执行此操作的正确方法是什么 我应该使用普通的 require once 吗 require once Yii
  • 如何从雅虎财经下载仅限 100 行的数据

    所以我正在做这个项目 我必须从雅虎财经下载历史股票数据 得到了这个代码 它工作正常 但最多只能下载 100 行 我尝试在网上扫描答案或不同的代码 这个只是从 Excel 中录制的宏 但我在 YouTube 上看到了一些使用他的解决方案的教程
  • ...联合问题中不允许使用构造函数

    我迫切需要找到以下问题的解决方案 namespace test template
  • C#:相当于 python try/catch/else 块

    在Python中 有这样有用的异常处理代码 try Code that could raise an exception except Exception Exception handling else Code to execute if
  • Cuda C 上任意大小的矩阵转置(具有共享内存)

    我无法找到在 CUDA C 中使用共享内存转置非方矩阵的方法 我是 CUDA C 和 C 的新手 In 这篇博文 https developer nvidia com blog efficient matrix transpose cuda