2017-08-13 8 views
0

Ich möchte eine Eigen-dynamische Größe Array nach Spalten gleichmäßig über OpenMP-Threads aufteilen.Eigen: Split-Array für OpenMP

      thread 0 | thread 1 | thread 2 
[[0, 1, 2],    [[0], | [[1], | [[2], 
[3, 4, 5], becomes:  [3], | [4], | [5], 
[6, 7, 8]]     [6]] | [7]] | [8]] 

kann ich die block Methode verwenden, das zu tun, aber ich bin nicht sicher, ob der Eigen Subarray für jeden Thread zusammenhängende Speicher belegt erkennen würde.

Wenn ich die documentation von Blocktyp zu lesen, hat einen InnerPanel Template-Parameter mit der folgenden Beschreibung:

InnerPanel wahr ist, wenn die Block-Karten auf einen Satz von Zeilen einer Zeilenhaupt Matrix oder Satz von Spalten einer Spaltenhauptmatrix (optional). Der Parameter ermöglicht es, zur Kompilierzeit zu bestimmen, ob der ausgerichtete Zugriff auf den Blockausdruck möglich ist.

Does Eigen weiß, dass Vektorisierung über den Sub-Array für jedes OpenMP Gewinde möglich ist, weil jeder eigentlich Subarray zusammenhängende Speicher belegt?

Wenn nicht, wie kann ich dies wissen?

Programm:

#include <Eigen/Eigen> 
#include <iostream> 
int main() { 
    // The dimensions of the matrix is not necessary 8 x 8. 
    // The dimension is only known at run time. 
    Eigen::MatrixXi x(8,8); 
    x.fill(0); 
    int n_parts = 3; 
    #pragma omp parallel for 
    for (int i = 0; i < n_parts; ++i) { 
     int st = i * x.cols()/n_parts; 
     int en = (i + 1) * x.cols()/n_parts; 
     x.block(0, st, x.rows(), en - st).fill(i); 
    } 
    std::cout << x << "\n"; 
} 

Ergebnis (g++ test.cpp -I<path to eigen includes> -fopenmp -lgomp):

0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
0 0 1 1 1 2 2 2 
+0

SO muss schlafen. –

Antwort

1

Um sicherzustellen, dass ein Block Ausdruck in der Tat zusammenhängenden Speicher besetzt, verwenden middleCols (oder leftCols oder rightCols) statt:

#include <Eigen/Core> 
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 
void inspectBlock(const Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>& block) 
{ 
    std::cout << __PRETTY_FUNCTION__ << '\n'; 
} 

int main() { 
    Eigen::MatrixXi x(8,8); 
    inspectBlock(x.block(0, 1, x.rows(), 2)); 
    inspectBlock(x.middleCols(1, 2)); 
} 

Res ult:

void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = false] 
void inspectBlock(const Eigen::Block<ArgType, BlockRows, BlockCols, InnerPanel>&) [with XprType = Eigen::Matrix<int, -1, -1>; int BlockRows = -1; int BlockCols = -1; bool InnerPanel = true] 

Hinweis: -1 ist der Wert von Eigen::Dynamic, das heißt, nicht bei der Kompilierung festgelegt.

Und natürlich, wenn Ihre Matrix Zeile Haupt war, können Sie stattdessen Int topRows, middleRows oder bottomRows teilen.

+0

Kann damit Eigen die Speicherausrichtung der Subarrays erfahren? –

+0

Hmm. InnerPanel ist wahr. Lassen Sie mich testen, was passieren wird, wenn die Dimension/Grenze der Matrix der Arrays nicht ein Vielfaches der Größe von simd-Registern ist. –

+0

Ich bin mir nicht bewusst, dass Eigen gesagt werden kann, dass Teilblöcke tatsächlich ausgerichtet sind. (Ich hätte gedacht, 'Ref 'kann nur gesagt werden, um ausgerichtete Blöcke zu akzeptieren, aber ich schaffte es nicht, ein funktionierendes Beispiel zu erstellen) - Wenn Sie das wirklich dringend brauchen, können Sie eine manuelle Konstruktion mit einer' AlignedMap 'machen. – chtz