1 /****************************************************************/
2 /* Parallel Combinatorial BLAS Library (for Graph Computations) */
3 /* version 1.6 -------------------------------------------------*/
4 /* date: 6/15/2017 ---------------------------------------------*/
5 /* authors: Ariful Azad, Aydin Buluc  --------------------------*/
6 /****************************************************************/
7 /*
8  Copyright (c) 2010-2017, The Regents of the University of California
9 
10  Permission is hereby granted, free of charge, to any person obtaining a copy
11  of this software and associated documentation files (the "Software"), to deal
12  in the Software without restriction, including without limitation the rights
13  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  copies of the Software, and to permit persons to whom the Software is
15  furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included in
18  all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  THE SOFTWARE.
27  */
28 
29 
30 #ifndef _SP_MAT_H
31 #define _SP_MAT_H
32 
33 #include <iostream>
34 #include <vector>
35 #include <utility>
36 #include "CombBLAS.h"
37 #include "SpDefs.h"
38 #include "promote.h"
39 #include "LocArr.h"
40 
41 namespace combblas {
42 
43 // Forward declaration (required since a friend function returns a SpTuples object)
44 template <class IU, class NU>
45 class SpTuples;
46 
47 
48 /**
49  ** The abstract base class for all derived sequential sparse matrix classes
50  ** Contains no data members, hence no copy constructor/assignment operator
51  ** Uses static polymorphism through curiously recurring templates (CRTP)
52  ** Template parameters: IT (index type), NT (numerical type), DER (derived class type)
53  **/
54 template < class IT, class NT, class DER >
55 class SpMat
56 {
57 public:
58 	//! Standard destructor, copy ctor and assignment are generated by compiler, they all do nothing !
59 	//! Default constructor also exists, and does nothing more than creating Base<Derived>() and Derived() objects
60 	//! One has to call one of the overloaded create functions to get an nonempty object
Create(const std::vector<IT> & essentials)61 	void Create(const std::vector<IT> & essentials)
62 	{
63 		static_cast<DER*>(this)->CreateImpl(essentials);
64 	}
65 
Create(IT size,IT nRow,IT nCol,std::tuple<IT,IT,NT> * mytuples)66 	void Create(IT size, IT nRow, IT nCol, std::tuple<IT, IT, NT> * mytuples)
67 	{
68 		static_cast<DER*>(this)->CreateImpl(size, nRow, nCol, mytuples);
69 	}
70 
71 	SpMat< IT,NT,DER >  operator() (const std::vector<IT> & ri, const std::vector<IT> & ci) const;
72 
73 	template <typename SR>
74 	void SpGEMM( SpMat< IT,NT,DER > & A, SpMat< IT,NT,DER > & B, bool isAT, bool isBT);
75 
76 	// ABAB: A semiring elementwise operation with automatic type promotion is required for completeness (should cover +/- and .* ?)
77 	// ABAB: A neat version of ConvertNumericType should be in base class (an operator SpMat<NIT,NNT,NDER>())
78 
79 	void Split( SpMat< IT,NT,DER > & partA, SpMat< IT,NT,DER > & partB);
80 	void Merge( SpMat< IT,NT,DER > & partA, SpMat< IT,NT,DER > & partB);
81 
GetArrays()82 	Arr<IT,NT> GetArrays() const
83 	{
84 		return static_cast<const DER*>(this)->GetArrays();
85 	}
GetEssentials()86 	std::vector<IT> GetEssentials() const
87 	{
88 		return static_cast<const DER*>(this)->GetEssentials();
89 	}
90 
GetInternal()91     auto GetInternal() const
92     {
93         return static_cast<const DER*>(this)->GetInternal();
94     }
GetInternal(int i)95     auto GetInternal(int i) const
96     {
97         return static_cast<const DER*>(this)->GetInternal(i);
98     }
getnsplit()99     int getnsplit() const // \TODO: Normalize the interface so that nsplit = 1 for serial cases
100     {
101         return static_cast<const DER*>(this)->getnsplit();
102     }
103 
Transpose()104 	void Transpose()
105 	{
106 		static_cast<DER*>(this)->Transpose();
107 	}
begcol()108     auto begcol()  // serial version
109     {
110         return static_cast<DER*>(this)->begcol();
111     }
endcol()112     auto endcol()  //serial version
113     {
114         return static_cast<DER*>(this)->endcol();
115     }
begcol(int i)116     auto begcol(int i)  // multithreaded version
117     {
118         return static_cast<DER*>(this)->begcol(i);
119     }
endcol(int i)120     auto endcol(int i)  //multithreaded version
121     {
122         return static_cast<DER*>(this)->endcol(i);
123     }
124 
125     template <typename X = DER>  // <-- (requires C++0x to have a default)
begnz(const typename X::SpColIter & ccol)126     auto begnz(const typename X::SpColIter & ccol)	//!< Return the beginning iterator for the nonzeros of the current column
127     {
128         return static_cast<DER*>(this)->begnz(ccol);
129     }
130 
131     template <typename X = DER>  // <-- (requires C++0x to have a default)
endnz(const typename X::SpColIter & ccol)132     auto endnz(const typename X::SpColIter & ccol)	//!< Return the ending iterator for the nonzeros of the current column
133     {
134          return static_cast<DER*>(this)->endnz(ccol);
135     }
136 
137     template <typename X = DER>  // <-- (requires C++0x to have a default)
begnz(const typename X::SpColIter & ccol,int i)138     auto begnz(const typename X::SpColIter & ccol, int i)	//!< multithreaded version
139     {
140         return static_cast<DER*>(this)->begnz(ccol, i);
141     }
142 
143     template <typename X = DER>  // <-- (requires C++0x to have a default)
endnz(const typename X::SpColIter & ccol,int i)144     auto endnz(const typename X::SpColIter & ccol, int i)	//!< multithreaded version
145     {
146         return static_cast<DER*>(this)->endnz(ccol, i);
147     }
148 
149 
150 	bool operator== (const SpMat< IT,NT,DER > & rhs) const;
151 
152 	std::ofstream& put(std::ofstream& outfile) const;
153 	std::ifstream& get(std::ifstream& infile);
154 
isZero()155 	bool isZero() const { return static_cast<const DER*>(this)->isZero(); }
getnrow()156 	IT getnrow() const { return static_cast<const DER*>(this)->getnrow(); }
getncol()157 	IT getncol() const { return static_cast<const DER*>(this)->getncol(); }
getnnz()158 	IT getnnz() const  { return static_cast<const DER*>(this)->getnnz(); }
159 
160 protected:
161 
162 	template < typename UIT, typename UNT, typename UDER >
163 	friend std::ofstream& operator<< (std::ofstream& outfile, const SpMat< UIT,UNT,UDER > & s);
164 
165 	template < typename UIT, typename UNT, typename UDER >
166 	friend std::ifstream& operator>> (std::ifstream& infile, SpMat< UIT,UNT,UDER > & s);
167 
168 	//! Returns a pointer to SpTuples, in order to avoid temporaries
169 	//! It is the caller's responsibility to delete the returned pointer afterwards
170 	template< class SR, class NUO, class IU, class NU1, class NU2, class DER1, class DER2 >
171 	friend SpTuples< IU, NUO > *
172 	MultiplyReturnTuples (const SpMat< IU, NU1, DER1 > & A, const SpMat< IU, NU2, DER2 > & B, bool isAT, bool isBT, bool clearA, bool clearB);
173 
174 };
175 
176 }
177 
178 #include "SpMat.cpp"
179 
180 #endif
181 
182