GPUMLib  0.2.2
GPU Machine Learning Library
BaseNMF.h
1 /*
2  Noel Lopes is an Assistant Professor at the Polytechnic Institute of Guarda, Portugal
3  Copyright (C) 2009, 2010, 2011, 2012 Noel de Jesus Mendonša Lopes
4 
5  This file is part of GPUMLib.
6 
7  GPUMLib is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef GPUMLib_BaseNMF_h
22 #define GPUMLib_BaseNMF_h
23 
24 #include "../common/CudaDefinitions.h"
25 #include "../common/CudaStreams.h"
26 #include "../common/Utilities.h"
27 #include "../memory/DeviceArray.h"
28 #include "../memory/DeviceMatrix.h"
29 #include "../memory/DeviceAccessibleVariable.h"
30 #include "NMFkernels.h"
31 
32 #define SIZE_BLOCKS_NMF (512)
33 
34 namespace GPUMLib {
35 
38 
40 class NMF {
41  private:
42  CudaStream streamQuality;
43 
44  int timesQualityWasObtained;
45  cudafloat lastValueQuality;
47  cudafloat deltaImprovement;
48  DeviceArray<cudafloat> d_quality;
49 
50 
51  static void Randomize(HostMatrix<cudafloat> & m) {
52  int ne = m.Elements();
53  cudafloat * p = m.Pointer();
54 
55  for(int e = 0; e < ne; e++) p[e] = ((cudafloat) rand()) / RAND_MAX + SMALL_VALUE_TO_ADD_DENOMINATOR;
56  }
57 
58  protected:
63 
64 
65  void DetermineQualityImprovement(bool calculateWH) {
66  if (cudaStreamQuery(streamQuality) == cudaSuccess) {
67  cudafloat quality = vquality.Value();
68 
69  if (timesQualityWasObtained++ > 2) {
70  deltaImprovement = quality - lastValueQuality;
71  } else {
72  timesQualityWasObtained++;
73  }
74 
75  lastValueQuality = quality;
76 
77  if (calculateWH) DeviceMatrix<cudafloat>::Multiply(W, H, WH);
78 
79  int elements = WH.Elements();
80  KernelNMFquality(NumberThreadsPerBlockThatBestFit(elements), V.Pointer(), WH.Pointer(), elements, d_quality.Pointer());
81 
82  vquality.UpdateValueAsync(d_quality.Pointer(), streamQuality);
83  }
84  }
85 
86  NMF(HostMatrix<cudafloat> & v, int r) : V(v), WH(v.Rows(), v.Columns(), ColumnMajor), d_quality(1) {
87  assert(!v.IsRowMajor());
88 
89  timesQualityWasObtained = 0;
90  deltaImprovement = CUDA_VALUE(1.0);
91  lastValueQuality = CUDA_VALUE(-1.0);
92  vquality.Value() = CUDA_VALUE(0.0);
93 
94  HostMatrix<cudafloat> aux(v.Rows(), r, ColumnMajor);
95  Randomize(aux);
96  W = aux;
97 
99  Randomize(aux);
100  H = aux;
101  }
102 
103  NMF(HostMatrix<cudafloat> & v, HostMatrix<cudafloat> & w, HostMatrix<cudafloat> & h) : V(v), W(w), H(h), WH(v.Rows(), v.Columns(), ColumnMajor), d_quality(1) {
104  assert(!v.IsRowMajor());
105  assert(!w.IsRowMajor());
106  assert(!h.IsRowMajor());
107 
108  assert(v.Rows() == w.Rows() && v.Columns() == h.Columns());
109  assert(w.Columns() == h.Rows());
110 
111  timesQualityWasObtained = 0;
112  deltaImprovement = CUDA_VALUE(1.0);
113  lastValueQuality = CUDA_VALUE(-1.0);
114  vquality.Value() = CUDA_VALUE(0.0);
115  }
116 
117  public:
121  return HostMatrix<cudafloat>(W);
122  }
123 
127  return HostMatrix<cudafloat>(H);
128  }
129 
134 
135  return HostMatrix<cudafloat>(WH);
136  }
137 
140  virtual void DoIteration(bool updateW = true) = 0;
141 
144  return deltaImprovement;
145  }
146 };
147 
149 
150 }
151 
152 #endif
void UpdateValueAsync(Type *deviceValue, cudaStream_t stream)
int NumberThreadsPerBlockThatBestFit(int threads, int maxThreadsPerBlock=MAX_THREADS_PER_BLOCK)
Definition: Utilities.h:37
HostMatrix< cudafloat > GetW()
Definition: BaseNMF.h:120
HostMatrix< cudafloat > GetH()
Definition: BaseNMF.h:126
void KernelNMFquality(int blockSize, cudafloat *V, cudafloat *WH, int n, cudafloat *quality)
Definition: NMFquality.cu:72
int Elements() const
Definition: BaseMatrix.h:94
Type * Pointer() const
Definition: BaseArray.h:70
Represents a CUDA stream.
Definition: CudaStreams.h:32
#define SMALL_VALUE_TO_ADD_DENOMINATOR
Small value added to the denominator of a fraction to prevent division by zero.
Definition: NMFkernels.h:32
cudafloat QualityImprovement() const
Gets the quality improvement caused by the last iteration.
Definition: BaseNMF.h:143
Type * Pointer() const
Definition: BaseMatrix.h:88
int Columns() const
Definition: BaseMatrix.h:80
bool IsRowMajor() const
Definition: BaseMatrix.h:100
virtual void DoIteration(bool updateW=true)=0
static void Multiply(DeviceMatrix< Type > &A, DeviceMatrix< Type > &B, DeviceMatrix< Type > &C, cudafloat alpha=CUDA_VALUE(1.0), cudafloat beta=CUDA_VALUE(0.0))
Definition: DeviceMatrix.h:192
int ResizeWithoutPreservingData(int rows, int columns)
Definition: BaseMatrix.h:119
int Rows() const
Definition: BaseMatrix.h:74
Base class for all Non-Negative Matrix Factorization classes.
Definition: BaseNMF.h:40
#define CUDA_VALUE(X)
HostMatrix< cudafloat > GetWH()
Definition: BaseNMF.h:132
float cudafloat