Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiply sparse matrices #132

Merged
merged 29 commits into from
Aug 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
46a0501
started a branch for multiplying sparse matrices against vectors.
rhl- Jan 27, 2016
ecab33b
added values removed MultiplyCSR.
rhl- Feb 3, 2016
114ea14
implemented multiply for graphs and distgraphs.
rhl- Feb 4, 2016
e08607b
implemented multiply for graphs and distgraphs.
rhl- Jan 27, 2016
babba77
fixed this.
rhl- Feb 7, 2016
8e04d35
compiles finally.
rhl- Feb 8, 2016
70c8108
Merge branch 'master' into multiply_sparse_matrices
rhl- Feb 19, 2016
83812d9
Merge branch 'multiply_sparse_matrices' of github.com:rhl-/Elemental …
rhl- Feb 19, 2016
c78c650
Merge branch 'master' into multiply_sparse_matrices
rhl- Aug 1, 2016
2dbc810
I believe things will now compile.
rhl- Aug 1, 2016
17ef6b6
Merge branch 'master' of git://github.com/elemental/Elemental into mu…
rhl- Aug 1, 2016
8b85694
towards multiplying sparse matrices
rhl- Aug 3, 2016
b18c7e5
towards multiplying sparse matrices
rhl- Aug 3, 2016
418f3b6
Merge branch 'master' of git://github.com/elemental/Elemental into mu…
rhl- Aug 20, 2016
dbb84c8
temporarily disabling one new function as I cant figure out macro sys…
rhl- Aug 20, 2016
e07bcdb
Merge branch 'master' of git://github.com/elemental/Elemental into mu…
rhl- Aug 20, 2016
8cd5636
merged in jacks changes. need to figure out whats wrong with template…
rhl- Aug 20, 2016
9842229
hm still broken.
rhl- Aug 20, 2016
a43cb33
put back multivec.
rhl- Aug 20, 2016
edfda9e
trying to get unit test compiling.
rhl- Aug 20, 2016
adf8f2c
added a basic unit test.
rhl- Aug 20, 2016
32571ce
fixed introduced bug Y not x.
rhl- Aug 20, 2016
c762c2a
addresses review.
rhl- Aug 21, 2016
04e78df
fixed errors.
rhl- Aug 21, 2016
2f6048e
address review.
rhl- Aug 21, 2016
0a15f61
Odd that I missed a multMeta.
rhl- Aug 22, 2016
1a83151
fix Get v GetLocal weirdness.
rhl- Aug 22, 2016
a1e8579
fix Get v GetLocal weirdness.
rhl- Aug 22, 2016
2ead9d5
Addresses review.
rhl- Aug 23, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions include/El/blas_like/level1/DiagonalScale.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,7 @@ void DiagonalScale
LogicError("The size of d must match the width of A");
)
A.InitializeMultMeta();
const auto& meta = A.multMeta;

const auto& meta = A.LockedDistGraph().multMeta;
// Pack the send values
const Int numSendInds = meta.sendInds.size();
vector<T> sendVals;
Expand Down
6 changes: 2 additions & 4 deletions include/El/blas_like/level1/DiagonalSolve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,7 @@ void DiagonalSolve
else
{
A.InitializeMultMeta();
const auto& meta = A.multMeta;

const auto& meta = A.LockedDistGraph().multMeta;
// Pack the send values
const Int numSendInds = meta.sendInds.size();
vector<F> sendVals;
Expand Down Expand Up @@ -308,8 +307,7 @@ void SymmetricDiagonalSolve
const Int firstLocalRow = d.FirstLocalRow();

A.InitializeMultMeta();
const auto& meta = A.multMeta;

const auto& meta = A.LockedDistGraph().multMeta;
// Pack the send values
const Int numSendInds = meta.sendInds.size();
vector<Real> sendVals( numSendInds );
Expand Down
1 change: 0 additions & 1 deletion include/El/blas_like/level1/EntrywiseMap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ void EntrywiseMap
B.remoteVals_.resize( numRemoteEntries );
for( Int k=0; k<numRemoteEntries; ++k )
B.remoteVals_[k] = func(A.remoteVals_[k]);
B.multMeta = A.multMeta;
B.ProcessQueues();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think because a few lines early we issue:

B.distGraph_ = A.distGraph_;

which assigns the multMeta objects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, agreed.

}

Expand Down
6 changes: 6 additions & 0 deletions include/El/blas_like/level3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ void Multiply
T alpha, const SparseMatrix<T>& A, const Matrix<T>& X,
T beta, Matrix<T>& Y );

template<typename T>
void Multiply
( Orientation orientation,
T alpha, const Graph& A, const Matrix<T>& X,
T beta, Matrix<T>& Y );

template<typename T>
void Multiply
( Orientation orientation,
Expand Down
44 changes: 43 additions & 1 deletion include/El/core/DistGraph/decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,45 @@

namespace El {

struct DistGraphMultMeta
{
bool ready;
// NOTE: The 'send' and 'recv' roles reverse for adjoint multiplication
Int numRecvInds;
vector<int> sendSizes, sendOffs,
recvSizes, recvOffs;
vector<Int> sendInds, colOffs;

DistGraphMultMeta() : ready(false), numRecvInds(0) { }

void Clear()
{
ready = false;
numRecvInds = 0;
SwapClear( sendSizes );
SwapClear( recvSizes );
SwapClear( sendOffs );
SwapClear( recvOffs );
SwapClear( sendInds );
SwapClear( colOffs );
}

const DistGraphMultMeta& operator=( const DistGraphMultMeta& meta )
{
ready = meta.ready;
numRecvInds = meta.numRecvInds;
sendSizes = meta.sendSizes;
sendOffs = meta.sendOffs;
recvSizes = meta.recvSizes;
recvOffs = meta.recvOffs;
sendInds = meta.sendInds;
colOffs = meta.colOffs;
return *this;
}
};



using std::set;

// Forward declare ldl::DistFront
Expand Down Expand Up @@ -134,6 +173,9 @@ class DistGraph
// total number of edges divided by the number of processes
double Imbalance() const EL_NO_RELEASE_EXCEPT;

mutable DistGraphMultMeta multMeta;
DistGraphMultMeta InitializeMultMeta() const;

void AssertConsistent() const;
void AssertLocallyConsistent() const;

Expand Down Expand Up @@ -170,4 +212,4 @@ class DistGraph

} // namespace El

#endif // ifndef EL_CORE_DISTGRAPH_DECL_HPP
#endif // ifndef EL_CORE_DISTGRAPH_HPP
41 changes: 2 additions & 39 deletions include/El/core/DistSparseMatrix/decl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,8 @@
#ifndef EL_CORE_DISTSPARSEMATRIX_DECL_HPP
#define EL_CORE_DISTSPARSEMATRIX_DECL_HPP

namespace El {
namespace El {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the extra single space?


struct DistSparseMultMeta
{
bool ready;
// NOTE: The 'send' and 'recv' roles reverse for adjoint multiplication
Int numRecvInds;
vector<int> sendSizes, sendOffs,
recvSizes, recvOffs;
vector<Int> sendInds, colOffs;

DistSparseMultMeta() : ready(false), numRecvInds(0) { }

void Clear()
{
ready = false;
numRecvInds = 0;
SwapClear( sendSizes );
SwapClear( recvSizes );
SwapClear( sendOffs );
SwapClear( recvOffs );
SwapClear( sendInds );
SwapClear( colOffs );
}

const DistSparseMultMeta& operator=( const DistSparseMultMeta& meta )
{
ready = meta.ready;
numRecvInds = meta.numRecvInds;
sendSizes = meta.sendSizes;
sendOffs = meta.sendOffs;
recvSizes = meta.recvSizes;
recvOffs = meta.recvOffs;
sendInds = meta.sendInds;
colOffs = meta.colOffs;
return *this;
}
};

// Use a simple 1d distribution where each process owns a fixed number of rows,
// if last process, height - (commSize-1)*floor(height/commSize)
Expand Down Expand Up @@ -194,8 +158,7 @@ class DistSparseMatrix
// total number of nonzeros divided by the number of processes
double Imbalance() const EL_NO_RELEASE_EXCEPT;

mutable DistSparseMultMeta multMeta;
DistSparseMultMeta InitializeMultMeta() const;
DistGraphMultMeta InitializeMultMeta() const;

void MappedSources
( const DistMap& reordering, vector<Int>& mappedSources ) const;
Expand Down
101 changes: 7 additions & 94 deletions include/El/core/DistSparseMatrix/impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
which can be found in the LICENSE file in the root directory, or at
http://opensource.org/licenses/BSD-2-Clause
*/
#ifndef EL_CORE_DISTSPARSEMATRIX_IMPL_HPP
#define EL_CORE_DISTSPARSEMATRIX_IMPL_HPP

#include <El/blas_like/level1/Axpy.hpp>
#include <El/blas_like/level1/Scale.hpp>
Expand Down Expand Up @@ -70,7 +72,7 @@ void DistSparseMatrix<T>::Empty( bool freeMemory )
SwapClear( vals_ );
else
vals_.resize( 0 );
multMeta.Clear();
distGraph_.multMeta.Clear();

SwapClear( remoteVals_ );
}
Expand Down Expand Up @@ -199,7 +201,7 @@ EL_NO_RELEASE_EXCEPT
{
distGraph_.QueueLocalConnection( localRow, col );
vals_.push_back( value );
multMeta.ready = false;
distGraph_.multMeta.ready = false;
}
}

Expand Down Expand Up @@ -234,7 +236,7 @@ EL_NO_RELEASE_EXCEPT
else
{
distGraph_.QueueLocalDisconnection( localRow, col );
multMeta.ready = false;
distGraph_.multMeta.ready = false;
}
}

Expand Down Expand Up @@ -404,7 +406,6 @@ DistSparseMatrix<T>::operator=( const DistSparseMatrix<T>& A )
distGraph_ = A.distGraph_;
vals_ = A.vals_;
remoteVals_ = A.remoteVals_;
multMeta = A.multMeta;
return *this;
}

Expand Down Expand Up @@ -716,97 +717,8 @@ void DistSparseMatrix<T>::AssertLocallyConsistent() const
if( !LocallyConsistent() )
LogicError("Distributed sparse matrix must be consistent");
}

template<typename T>
DistSparseMultMeta DistSparseMatrix<T>::InitializeMultMeta() const
{
DEBUG_CSE
if( multMeta.ready )
return multMeta;
mpi::Comm comm = Comm();
const int commSize = distGraph_.commSize_;
auto& meta = multMeta;

// Compute the set of row indices that we need from X in a normal
// multiply or update of Y in the adjoint case
const Int* colBuffer = LockedTargetBuffer();
const Int numLocalEntries = NumLocalEntries();
vector<ValueInt<Int>> uniqueCols(numLocalEntries);
for( Int e=0; e<numLocalEntries; ++e )
uniqueCols[e] = ValueInt<Int>{colBuffer[e],e};
std::sort( uniqueCols.begin(), uniqueCols.end(), ValueInt<Int>::Lesser );
meta.colOffs.resize(numLocalEntries);
{
Int uniqueOff=-1, lastUnique=-1;
for( Int e=0; e<numLocalEntries; ++e )
{
if( lastUnique != uniqueCols[e].value )
{
++uniqueOff;
lastUnique = uniqueCols[e].value;
uniqueCols[uniqueOff] = uniqueCols[e];
}
meta.colOffs[uniqueCols[e].index] = uniqueOff;
}
uniqueCols.resize( uniqueOff+1 );
}
const Int numRecvInds = uniqueCols.size();
meta.numRecvInds = numRecvInds;
vector<Int> recvInds( numRecvInds );
meta.recvSizes.clear();
meta.recvSizes.resize( commSize, 0 );
meta.recvOffs.resize( commSize );
Int vecBlocksize = Width() / commSize;
if( vecBlocksize*commSize < Width() || Width() == 0 )
++vecBlocksize;

{
Int off=0, lastOff=0, qPrev=0;
for( ; off<numRecvInds; ++off )
{
const Int j = uniqueCols[off].value;
const int q = j / vecBlocksize;
while( qPrev != q )
{
meta.recvSizes[qPrev] = off - lastOff;
meta.recvOffs[qPrev+1] = off;

lastOff = off;
++qPrev;
}
recvInds[off] = j;
}
while( qPrev != commSize-1 )
{
meta.recvSizes[qPrev] = off - lastOff;
meta.recvOffs[qPrev+1] = off;
lastOff = off;
++qPrev;
}
meta.recvSizes[commSize-1] = off - lastOff;
}

// Coordinate
meta.sendSizes.resize( commSize );
mpi::AllToAll( meta.recvSizes.data(), 1, meta.sendSizes.data(), 1, comm );
Int numSendInds=0;
meta.sendOffs.resize( commSize );
for( int q=0; q<commSize; ++q )
{
meta.sendOffs[q] = numSendInds;
numSendInds += meta.sendSizes[q];
}
meta.sendInds.resize( numSendInds );
mpi::AllToAll
( recvInds.data(), meta.recvSizes.data(), meta.recvOffs.data(),
meta.sendInds.data(), meta.sendSizes.data(), meta.sendOffs.data(),
comm );

meta.numRecvInds = numRecvInds;
meta.ready = true;

return meta;
}
DistGraphMultMeta DistSparseMatrix<T>::InitializeMultMeta() const { return distGraph_.InitializeMultMeta(); }

template<typename T>
void DistSparseMatrix<T>::MappedSources
Expand Down Expand Up @@ -908,3 +820,4 @@ bool DistSparseMatrix<T>::CompareEntries( const Entry<T>& a, const Entry<T>& b )
#undef EL_EXTERN

} // namespace El
#endif //EL_CORE_DISTSPARSEMATRIX_IMPL_HPP
4 changes: 2 additions & 2 deletions src/blas_like/level1/ColumnMinAbs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ void ColumnMinAbs
mins.Resize( A.Width(), 1 );
Fill( mins, limits::Max<Real>() );
A.InitializeMultMeta();
const auto& meta = A.multMeta;
const auto& meta = A.LockedDistGraph().multMeta;

// Pack the send values
// --------------------
Expand Down Expand Up @@ -243,7 +243,7 @@ void ColumnMinAbsNonzero
// =========================================================
mins = upperBounds;
A.InitializeMultMeta();
const auto& meta = A.multMeta;
const auto& meta = A.LockedDistGraph().multMeta;

// Pack the send values
// --------------------
Expand Down
5 changes: 2 additions & 3 deletions src/blas_like/level1/ColumnNorms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ void ColumnTwoNorms
norms.Resize( A.Width(), 1 );
Zero( norms );
A.InitializeMultMeta();
const auto& meta = A.multMeta;

const auto& meta = A.LockedDistGraph().multMeta;
// Pack the send values
// --------------------
vector<Real> sendScales( meta.numRecvInds, 0 ),
Expand Down Expand Up @@ -263,7 +262,7 @@ void ColumnMaxNorms
norms.Resize( A.Width(), 1 );
Zero( norms );
A.InitializeMultMeta();
const auto& meta = A.multMeta;
const auto& meta = A.LockedDistGraph().multMeta;

// Pack the send values
// --------------------
Expand Down
1 change: 1 addition & 0 deletions src/blas_like/level1/Copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ void Copy( const DistGraph& A, DistGraph& B )
// Directly assign instead of queueing up the individual edges
B.sources_ = A.sources_;
B.targets_ = A.targets_;
B.multMeta = A.multMeta;
B.locallyConsistent_ = A.locallyConsistent_;
B.localSourceOffsets_ = A.localSourceOffsets_;
B.ProcessLocalQueues();
Expand Down
Loading