Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 压缩稀疏列矩阵的并行构造_Python_Matrix_Parallel Processing_Scipy_Sparse Matrix - Fatal编程技术网

Python 压缩稀疏列矩阵的并行构造

Python 压缩稀疏列矩阵的并行构造,python,matrix,parallel-processing,scipy,sparse-matrix,Python,Matrix,Parallel Processing,Scipy,Sparse Matrix,定义为m列的压缩稀疏列矩阵(csc) 它有三个数组:数据、索引和Indptr indptr是一个1D阵列,大小为m+1 索引是矩阵中所有非零项的行索引 索引[indptr[i]:indptr[i+1]]是第i列的所有非零项的行索引。这些非零项的值在数据[indptr[i]:indptr[i+1]中定义 具有n行的压缩稀疏行(csr)矩阵具有相似的性能 问题: Cpu处理n个作业。第p个作业为具有n行和m列的稀疏矩阵(csc或csr)的第q行生成数据。p和q不必相等,只要记录的是哪一行对应的作

定义为m列的压缩稀疏列矩阵(csc)

它有三个数组:数据、索引和Indptr

  • indptr是一个1D阵列,大小为m+1
  • 索引是矩阵中所有非零项的行索引
  • 索引[indptr[i]:indptr[i+1]]是第i列的所有非零项的行索引。这些非零项的值在数据[indptr[i]:indptr[i+1]中定义
具有n行的压缩稀疏行(csr)矩阵具有相似的性能

问题:

Cpu处理n个作业。第p个作业为具有n行和m列的稀疏矩阵(csc或csr)的第q行生成数据。p和q不必相等,只要记录的是哪一行对应的作业

如何有效地从作业中收集数据并生成csc矩阵

目前的解决办法:

方法A

  • 创建了名为shared_data、shared_index、shared_indptr(它们定义了csr矩阵)和shared_ordering的空数组。共享_数据和共享_索引的大小取决于对非零条目的数量的估计。将共享索引设置为[0]=0。这些数组由作业共享
  • 非零条目数(count_nz)和输入csr矩阵的行数(count_row)的计数器也由作业共享
  • 访问1和2中描述的资源需要获取锁
  • 每个作业都知道它试图放入csr矩阵的非零项的列索引(作业索引)。它还知道非零条目的值(job_data)和非零条目的数量(job_nz)
  • 每个作业都试图获得锁
  • 获取锁后,作业将执行以下操作。然后释放锁
  • 通过包装共享数组(如scipy.sparse.csr_矩阵((共享_数据、共享_索引、共享_indptr))来创建csr矩阵对象

  • 将csr转换为csc矩阵(目标是生成csc矩阵,而不是csr矩阵…)

  • 这种方法的问题在于,锁确实会降低性能,就像十几个人试图使用同一个工具来处理项目的不同部分一样

    方法B

    每个cpu处理m个作业,并使用a中描述的方法构建csc矩阵。这种方法使用更多内存,但矩阵生成速度更快

    方法C

    一个cpu处理m作业并构建csc矩阵。这比12个cpu机器上的a方法花费的时间多大约两倍

    方法D(2016年5月6日更新)

    共有个cpu核。最终csc矩阵的共享_数据、共享_indptr和共享_索引数组以及共享_排序数组由所有cpu核共享。无需锁定。每个cpu核运行单个子进程(而不是一直启动和停止子进程)每个cpu核心处理m个作业中的1/s,每个cpu使用a中描述的方法构造一个小型csc矩阵。cpu完成所有作业后,它将三种大小的数据广播到其他cpu,这些数据放入其小型csc矩阵的三个阵列中。一旦cpu从所有其他cpu接收到该信息(有s-1信息可从其他CPU接收),它计算其小csc矩阵的三个数组在最终csc矩阵的三个数组中的位置。然后将其小csc矩阵复制到共享csc矩阵

    之后,cpu向另一个cpu发送一个信号。一旦一个cpu接收到s-1信号,它就开始下一个周期(可能不需要第二次同步)

    希望同步会比A中的锁浪费更少的时间。并且这种方法可以从1个cpu核心线性扩展到12个cpu核心。如果有人有这方面的经验,请随时提供建议

    方法D的一个缺点是,它使用的内存量是保存最终csc矩阵所需内存量的两倍。一半的内存用于共享阵列。另一半用于小型csc矩阵的所有阵列…这似乎没问题。在方法B中,每个cpu只有大约1/s的整个内存可供使用。方法D更好

    可以保留小矩阵的数组作为缓冲区,这样就不会浪费时间重新创建numpy数组

    我正试图与B一起工作,并优化每个作业的每个cpu核心的内存使用率。但如果方法A可以避免通过更智能的锁设计破坏性能,我会使用A…我想我会选择D。 相关问题:

    听起来你已经创建了一个
    csr
    矩阵,然后直接修改了3个属性数组。你可以通过附加到现有数组来完成。虽然我已经操作了csr的
    数据属性,但我没有直接更改其他属性的经验。似乎这很难可靠地完成,而且没有你t稀疏代码反对

    另一种方法是先构造3个数组,然后构造
    csr
    。而不是使用
    np。对每一行追加
    ,追加到列表,然后使用
    np。连接
    ,将它们连接起来

    如果使用
    coo
    输入样式,则可以按任意顺序追加行。一个作业不必知道前几行中有多少项

    coo
    样式输入对于有限元刚度矩阵特别好,其中元素的矩阵重叠。并且
    coo
    输入可以直接转到
    csc

    我最近在这里讨论了从块构造稀疏矩阵:


    lil
    适合增量工作,因为属性是两个列表的对象数组-每行一个列表。因此更新只需要用新列表替换两个空列表-一个指针操作。但是我认为
    lil
    csc
    coo
    csc
    要慢(但我还没有测试过它).

    不分析您的设置:您确定这不是迭代的概念吗
    after acquiring lock
    shared_data[counter_nz:(counter_nz + job_nz)] = job_data
    shared_indices[counter_nz:(counter_nz + job_nz)] = job_indices
    shared_indptr[count_row + 1] = shared_indptr[count_row] + job_nz
    shared_ordering[counter_row] = job_id
    counter_nz  += job_nz
    counter_row += 1
    release lock.