【问题标题】:cusp::io::write_matrix_market_file() gives Access Violation Exceptioncusp::io::write_matrix_market_file() 给出访问冲突异常
【发布时间】:2013-02-07 09:11:46
【问题描述】:

我正在尝试使用 CUSP 将 Matlab 中的 272 x 544 双矩阵读入 ELLPACK 格式的稀疏矩阵。到目前为止,我能找到的唯一方法是将数据读入 mxArray,将 mxArray 读入 double* 数组(使用 mxGetPr()),然后将值复制到 cusp::array2d。在那里,我需要将 array2d 写入 .mtx 文件,然后将文件读入 coo_matrix,最后将其转换为 ell_matrix。对我来说这听起来很傻,但鉴于 CUSP 的文档很少,这是我能想到的最好的。如果有人推荐一种更好的方法,我将非常感激。

无论如何,我现在面临的问题是,在我读取 array2d 中的数据并尝试使用 cusp::write_matrix_market_file() 将其写入 .mtx 文件后,我得到一个“未处理的异常:写入位置的访问冲突“ 错误信息。在尝试将它们写入文件之前,我尝试从 array2d 打印一些值,只是为了确保一切就绪并且这些值似乎存储在 array2d 中。我也尝试将类型更改为浮动,但错误仍然存​​在。 这是我执行此任务的代码:

     #include <thrust/version.h>
     #include <cusp/version.h>
     #include <cusp/ell_matrix.h>
     #include <cusp/print.h>
     #include <cusp/io/matrix_market.h>
     #include <cusp/array2d.h>
     #include <cusp/coo_matrix.h>

     int main(int argc, char** argv)
     {
      const mxArray* mx_g_tra;
      //Reading data from Matlab   
       mx_g_tra = openMatFile2("C:\\out.mat", ndir, "out.tra");
   double* g_tra = mxGetPr(mx_g_tra);
   sizeG_tra=(int)mxGetNumberOfElements(mx_g_tra);
   const mwSize* traDims= mxGetDimensions(mx_g_tra);

      //get matrix dimensions
       tra_W= traDims[0];
   tra_H= traDims[1];
   printf("\nAcquired %d TRA elements as %d x %d from Maltab.\n", sizeG_tra, tra_W, tra_H);
       cusp::array2d<float, cusp::host_memory> TRA(traDims[0], traDims[1]);
       if(g_tra != NULL)
       {
       for(int i=0; i< traDims[0]; i++)
        {
         for(int j=0; j<traDims[1]; j++) 
          {TRA(i,j) = (float)g_tra[i*traDims[1]+j];
           if(TRA(i,j) != 0) printf("\nTRA(%d, %d) = %g", i, j, TRA(i,j));}
        }
       }

 cusp::io::write_matrix_market_file(TRA, "C:\\TRA.mtx"); 

当我得到异常时,调用堆栈指向: cusp::io::detail::write_value >,float>(std::basic_ofstream > & output={...}, const float & value=) 第 116 行 + 0x5 字节 C++

编辑: 快速更新:我通过修改文件“matrix_market.inl”摆脱了异常,他们有一个奇怪的嵌套循环,通过循环矩阵 cols 然后再次 cols 将值写入文件(从未考虑过 num_rows)显然因为我的矩阵不是正方形,代码试图访问不存在的位置。这是修改后的代码:

      for(size_t j = 0; j < mtx.num_cols; j++)
       {
    // Modified below: mtx.num_cols --> mtx.num_rows
         for(size_t i = 0; i < mtx.num_rows; i++)
         {
         write_value(output, mtx(i,j));
         output << "\n";
          }
         }

我不确定在读取这个 .mtx 文件时这会如何影响不同的格式构造函数

【问题讨论】:

  • 我很确定您可以从 array2d 转到 coo 矩阵或可能是 ell 矩阵。 coo 矩阵和ell matrix 的构造函数知道如何解释其他矩阵类型。这是一个 worked example 直接从 array2d 到 coo 矩阵。
  • 谢谢罗伯特。我刚刚编辑了我的问题以说明我摆脱了异常的事实,尽管我不确定以正确的方式。您提供的链接中的示例可以让我免于来回写入磁盘的麻烦。我会检查结果是否相同。谢谢。

标签: matlab matrix cuda cusp-library


【解决方案1】:

这段代码对我有用,演示了如何直接从 array2d 转到 coo 或 ell:

编辑:更新了代码示例以显示cusp::is_valid_matrix()的用法

 #include <stdio.h>
 #include <cusp/verify.h>
 #include <cusp/ell_matrix.h>
 #include <cusp/io/matrix_market.h>
 #include <cusp/array2d.h>
 #include <cusp/coo_matrix.h>

 int main(int argc, char** argv)
 {
  // initial matrix
   cusp::array2d<float, cusp::host_memory> E(4, 3);
   E(0,0) =  1.000e+00; E(0,1) =  0.000e+00; E(0,2) =  0.000e+00;
   E(1,0) =  0.000e+00; E(1,1) =  1.050e+01; E(1,2) =  0.000e+00;
   E(2,0) =  0.000e+00; E(2,1) =  0.000e+00; E(2,2) =  2.500e-01;
   E(3,0) =  0.000e+00; E(3,1) =  2.505e+02; E(3,2) =  0.000e+00;

   cusp::coo_matrix<int, float, cusp::host_memory> coo(E);
   cusp::ell_matrix<int, float, cusp::host_memory> ell(E);
   if (!cusp::is_valid_matrix(coo)) {printf("Invalid COO\n"); return 1;}
   if (!cusp::is_valid_matrix(ell)) {printf("Invalid ELL\n"); return 1;}

   cusp::io::write_matrix_market_file(coo, "COO.mtx");
   cusp::io::write_matrix_market_file(ell, "ELL.mtx");
   return 0;
 }

【讨论】:

    【解决方案2】:

    只要行数大于列数,没有异常,代码没有问题。我遇到的问题是因为行数是列数的一半。因此,当文件“matrix_market.inl”中的 write_value 假设我的矩阵是方阵并且在两个循环中只考虑 num_cols 时,我得到了错误。实际上,抛出异常时 i 的值是 273(我的 272 x 544 矩阵中不存在的第一行)。 我通过在“matrix_market.inl”代码中编辑 write_matrix_market_stream 来修复它,如下所示:

           template <typename Matrix, typename Stream>
           void write_matrix_market_stream(const Matrix& mtx, Stream& output, cusp::array2d_format)
           {
            typedef typename Matrix::value_type ValueType;
    
            bool is_complex = thrust::detail::is_same<ValueType, cusp::complex<typename                   norm_type<ValueType>::type> >::value;
    
            if (is_complex)
            output << "%%MatrixMarket matrix array complex general\n";
            else
            output << "%%MatrixMarket matrix array real general\n";
    
            output << "\t" << mtx.num_rows << "\t" << mtx.num_cols << "\n";
    
            for(size_t j = 0; j < mtx.num_cols; j++)
            {
             // EDIT needed here
         // Modified below: mtx.num_cols --> mtx.num_rows
            for(size_t i = 0; i < mtx.num_rows; i++)
              {
                 write_value(output, mtx(i,j));
                output << "\n";
              }
            }
            }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多