1 // =============================================================================
2 // === GPUQREngine/Include/GPUQREngine_Front.hpp ===============================
3 // =============================================================================
4 //
5 // The Front is a principal class in the GPUQREngine.
6 //
7 // Fronts wrap all metadata required to complete its factorization.
8 // When involved in a sparse factorization, additional metadata is present in
9 // the SparseMeta member, "sparseMeta."
10 //
11 // =============================================================================
12 
13 #ifndef GPUQRENGINE_FRONT_HPP
14 #define GPUQRENGINE_FRONT_HPP
15 
16 #include "GPUQREngine_Common.hpp"
17 #include "GPUQREngine_SparseMeta.hpp"
18 #include "GPUQREngine_FrontState.hpp"
19 
20 class Front
21 {
22 public:
23     Int fids;           // Front id within a stage
24     Int pids;           // Parent front id within a stage
25     Int fidg;           // Front id global to problem
26     Int pidg;           // Parent id global to problem
27 
28     Int fm;             // # rows
29     Int fn;             // # cols
30     Int rank;           // (derived) MIN(fm, fn)
31 
32     // adv layout options
33     bool isColMajor;    // default:F
34     Int ldn;            // user-specified desired leading dim
35 
36     double *F;          // Front data
37     double *gpuF;       // The frontal matrix on the GPU.
38     double *cpuR;       // The cpu location of the R factor.
39 
40     FrontState state;   // The front factorization state
41 
42     Int *Stair;         // The staircase allows us to exploit block zeroes.
43 
44     /* Extension to support sparse factorization. */
45     SparseMeta sparseMeta;
46 
47     /* Debug Fields */
48     bool printMe;
49 
operator new(long unsigned int reqMem,Front * ptr)50     void* operator new(long unsigned int reqMem, Front* ptr){ return ptr; }
51 
Front(Int fids_arg,Int pids_arg,Int fm_arg,Int fn_arg,bool isColMajor_arg=false,Int ldn_arg=EMPTY)52     Front(
53         Int fids_arg,                   // the front identifier
54         Int pids_arg,                   // the parent identifier
55         Int fm_arg,                     // the # of rows in the front
56         Int fn_arg,                     // the # of cols in the front
57         bool isColMajor_arg=false,      // whether the front is col-major
58         Int ldn_arg=EMPTY)              // the leading dimension
59     {
60         fids = fids_arg ;
61         pids = pids_arg ;
62         fidg = EMPTY;
63         pidg = EMPTY;
64 
65         fm = fm_arg ;
66         fn = fn_arg ;
67         rank = MIN(fm, fn);
68 
69         isColMajor = isColMajor_arg ;
70         ldn = (ldn_arg == EMPTY ? fn : ldn_arg) ;
71 
72         F = NULL;
73         gpuF = NULL;
74         cpuR = NULL;
75 
76         state = ALLOCATE_WAIT;
77 
78         Stair = NULL;
79 
80         sparseMeta = SparseMeta();
81 
82         printMe = false;
83     }
84 
~Front()85     ~Front()
86     {
87         // for the sparse case, F is NULL on the CPU
88         F = (double *) SuiteSparse_free (F) ;
89     }
90 
isAllocated(void)91     bool isAllocated
92     (
93         void
94     )
95     {
96         return gpuF != NULL;
97     }
98 
isDense(void)99     bool isDense
100     (
101         void
102     )
103     {
104         // NOTE: this code is tested by the SPQR/Tcov test, but that test does
105         // not flag this line as being tested in the coverage output.  This is
106         // determined by commenting out the following line, and seeing it
107         // trigger under 'make' in SPQR/Tcov:
108         //      { fprintf (stderr, "statement tested!\n") ; exit (0) ; }
109         // This same problem occurs elsewhere in GPUQREngine/Include/*
110         // and thus only affects *.hpp files #include'd in other files.
111         // The optimizer must be getting in the way, or some related effect.
112         return (!sparseMeta.isSparse);
113     }
114 
isSparse(void)115     bool isSparse
116     (
117         void
118     )
119     {
120         // NOTE: also tested by SPQR/Tcov, but not flagged as such in cov output
121         return (sparseMeta.isSparse);
122     }
123 
isStaged(void)124     bool isStaged
125     (
126         void
127     )
128     {
129         // NOTE: also tested by SPQR/Tcov, but not flagged as such in cov output
130         return (isSparse() && sparseMeta.isStaged);
131     }
132 
isPushOnly(void)133     bool isPushOnly
134     (
135         void
136     )
137     {
138         return (isSparse() && sparseMeta.pushOnly);
139     }
140 
getNumFrontValues(void)141     size_t getNumFrontValues
142     (
143         void
144     )
145     {
146         return fm * fn;
147     }
148 
getNumRValues(void)149     size_t getNumRValues
150     (
151         void
152     )
153     {
154         return rank * fn;
155     }
156 
isTooBigForSmallQR(void)157     bool isTooBigForSmallQR
158     (
159         void
160     )
161     {
162         return (fm > 96 || fn > 32);
163     }
164 
165 };
166 
167 #endif
168