Browse code

parallelization appears to be working

Tom Sherman authored on 09/05/2018 21:27:17
Showing 12 changed files

... ...
@@ -45,7 +45,7 @@ CoGAPS <- function(D, S, nFactor=7, nEquil=1000, nSample=1000, nOutputs=1000,
45 45
 nSnapshots=0, alphaA=0.01, alphaP=0.01, maxGibbmassA=100, maxGibbmassP=100,
46 46
 seed=-1, messages=TRUE, singleCellRNASeq=FALSE, whichMatrixFixed='N',
47 47
 fixedPatterns=matrix(0), checkpointInterval=0, 
48
-checkpointFile="gaps_checkpoint.out", ...)
48
+checkpointFile="gaps_checkpoint.out", nCores=1, ...)
49 49
 {
50 50
     # get v2 arguments
51 51
     oldArgs <- list(...)
... ...
@@ -100,7 +100,8 @@ checkpointFile="gaps_checkpoint.out", ...)
100 100
     result <- cogaps_cpp(D, S, nFactor, nEquil, nEquil/10, nSample, nOutputs,
101 101
         nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages,
102 102
         singleCellRNASeq, whichMatrixFixed, fixedPatterns, checkpointInterval,
103
-        checkpointFile, which(thresholdEnum==pumpThreshold), nPumpSamples)
103
+        checkpointFile, which(thresholdEnum==pumpThreshold), nPumpSamples,
104
+        nCores)
104 105
     
105 106
     # label matrices and return list
106 107
     patternNames <- paste('Patt', 1:nFactor, sep='')
... ...
@@ -1,8 +1,8 @@
1 1
 # Generated by using Rcpp::compileAttributes() -> do not edit by hand
2 2
 # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
3 3
 
4
-cogaps_cpp <- function(D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples) {
5
-    .Call('_CoGAPS_cogaps_cpp', PACKAGE = 'CoGAPS', D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples)
4
+cogaps_cpp <- function(D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples, nCores) {
5
+    .Call('_CoGAPS_cogaps_cpp', PACKAGE = 'CoGAPS', D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples, nCores)
6 6
 }
7 7
 
8 8
 cogapsFromCheckpoint_cpp <- function(D, S, nFactor, nEquil, nSample, fileName, cptFile) {
... ...
@@ -9,7 +9,7 @@ CoGAPS(D, S, nFactor = 7, nEquil = 1000, nSample = 1000,
9 9
   maxGibbmassA = 100, maxGibbmassP = 100, seed = -1, messages = TRUE,
10 10
   singleCellRNASeq = FALSE, whichMatrixFixed = "N",
11 11
   fixedPatterns = matrix(0), checkpointInterval = 0,
12
-  checkpointFile = "gaps_checkpoint.out", ...)
12
+  checkpointFile = "gaps_checkpoint.out", nCores = 1, ...)
13 13
 }
14 14
 \arguments{
15 15
 \item{D}{data matrix}
... ...
@@ -2,9 +2,17 @@
2 2
 #include "AtomicDomain.h"
3 3
 #include "math/Random.h"
4 4
 
5
+#include <omp.h>
5 6
 #include <stdint.h>
6 7
 #include <utility>
7 8
 
9
+//omp_lock_t lock;
10
+
11
+AtomicDomain::AtomicDomain()
12
+{
13
+    //omp_init_lock(&lock);
14
+}
15
+
8 16
 // O(1)
9 17
 Atom AtomicDomain::front() const
10 18
 {
... ...
@@ -76,6 +84,8 @@ bool AtomicDomain::hasRight(const Atom &atom) const
76 84
 // O(logN)
77 85
 Atom AtomicDomain::insert(uint64_t pos, float mass)
78 86
 {
87
+    //omp_set_lock(&lock);
88
+
79 89
     // insert position into map
80 90
     std::map<uint64_t, uint64_t>::iterator iter, iterLeft, iterRight;
81 91
     iter = mAtomPositions.insert(std::pair<uint64_t, uint64_t>(pos, size())).first;
... ...
@@ -100,6 +110,9 @@ Atom AtomicDomain::insert(uint64_t pos, float mass)
100 110
     // add atom to vector
101 111
     mAtoms.push_back(atom);
102 112
     mUsedPositions.insert(pos);
113
+
114
+    //omp_unset_lock(&lock);
115
+
103 116
     return atom;
104 117
 }
105 118
 
... ...
@@ -108,6 +121,8 @@ Atom AtomicDomain::insert(uint64_t pos, float mass)
108 121
 // swap with last atom in vector, pop off the back
109 122
 void AtomicDomain::erase(uint64_t pos)
110 123
 {
124
+    //omp_set_lock(&lock);
125
+
111 126
     // get vector index of this atom and erase it
112 127
     uint64_t index = mAtomPositions.at(pos);
113 128
 
... ...
@@ -146,10 +161,14 @@ void AtomicDomain::erase(uint64_t pos)
146 161
     mAtomPositions.erase(pos);
147 162
     mAtoms.pop_back();
148 163
     mUsedPositions.erase(pos);
164
+
165
+    //omp_unset_lock(&lock);
149 166
 }
150 167
 
151 168
 // O(logN)
152 169
 void AtomicDomain::updateMass(uint64_t pos, float newMass)
153 170
 {
171
+    //omp_set_lock(&lock);
154 172
     mAtoms[mAtomPositions.at(pos)].mass = newMass;
173
+    //omp_unset_lock(&lock);
155 174
 }
156 175
\ No newline at end of file
... ...
@@ -60,6 +60,8 @@ private:
60 60
 
61 61
 public:
62 62
 
63
+    AtomicDomain();
64
+
63 65
     void setDomainSize(uint64_t size) { mDomainSize = size; }
64 66
 
65 67
     // access atoms
... ...
@@ -10,13 +10,14 @@ unsigned nEquilCool, unsigned nSample, unsigned nOutputs, unsigned nSnapshots,
10 10
 float alphaA, float alphaP, float maxGibbmassA, float maxGibbmassP,
11 11
 unsigned seed, bool messages, bool singleCellRNASeq, char whichMatrixFixed,
12 12
 const Rcpp::NumericMatrix &FP, unsigned checkpointInterval,
13
-const std::string &cptFile, unsigned pumpThreshold, unsigned nPumpSamples)
13
+const std::string &cptFile, unsigned pumpThreshold, unsigned nPumpSamples,
14
+unsigned nCores)
14 15
 {
15 16
     // create internal state from parameters and run from there
16 17
     GapsRunner runner(D, S, nFactor, nEquil, nEquilCool, nSample,
17 18
         nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed,
18 19
         messages, singleCellRNASeq, checkpointInterval, cptFile,
19
-        whichMatrixFixed, FP);
20
+        whichMatrixFixed, FP, nCores);
20 21
     return runner.run();
21 22
 }
22 23
 
... ...
@@ -5,7 +5,7 @@ unsigned nFactor, unsigned nEquil, unsigned nCool, unsigned nSample,
5 5
 unsigned nOutputs, unsigned nSnapshots, float alphaA, float alphaP,
6 6
 float maxGibbsMassA, float maxGibbsMassP, uint32_t seed, bool messages,
7 7
 bool singleCellRNASeq, unsigned cptInterval, const std::string &cptFile,
8
-char whichMatrixFixed, const Rcpp::NumericMatrix &FP)
8
+char whichMatrixFixed, const Rcpp::NumericMatrix &FP, unsigned nCores)
9 9
     :
10 10
 mChiSqEquil(nEquil), mNumAAtomsEquil(nEquil), mNumPAtomsEquil(nEquil),
11 11
 mChiSqSample(nSample), mNumAAtomsSample(nSample), mNumPAtomsSample(nSample),
... ...
@@ -16,7 +16,8 @@ mCheckpointInterval(cptInterval), mCheckpointFile(cptFile),
16 16
 mNumUpdatesA(0), mNumUpdatesP(0),
17 17
 mASampler(D, S, nFactor, alphaA, maxGibbsMassA),
18 18
 mPSampler(D, S, nFactor, alphaP, maxGibbsMassP),
19
-mStatistics(D.nrow(), D.ncol(), nFactor)
19
+mStatistics(D.nrow(), D.ncol(), nFactor),
20
+mNumCores(nCores)
20 21
 {
21 22
     mASampler.sync(mPSampler);
22 23
     mPSampler.sync(mASampler);
... ...
@@ -137,11 +138,11 @@ void GapsRunner::runSampPhase()
137 138
 void GapsRunner::updateSampler()
138 139
 {
139 140
     mNumUpdatesA += mIterA;
140
-    mASampler.update(mIterA);
141
+    mASampler.update(mIterA, mNumCores);
141 142
     mPSampler.sync(mASampler);
142 143
 
143 144
     mNumUpdatesP += mIterP;
144
-    mPSampler.update(mIterP);
145
+    mPSampler.update(mIterP, mNumCores);
145 146
     mASampler.sync(mPSampler);
146 147
 }
147 148
 
... ...
@@ -63,6 +63,8 @@ public:
63 63
     PatternGibbsSampler mPSampler;
64 64
     GapsStatistics mStatistics;
65 65
 
66
+    unsigned mNumCores;
67
+
66 68
     void createCheckpoint();
67 69
     void makeCheckpointIfNeeded();
68 70
     void displayStatus(const std::string &type, unsigned nIterTotal);
... ...
@@ -80,7 +82,7 @@ public:
80 82
         unsigned nOutputs, unsigned nSnapshots, float alphaA, float alphaP,
81 83
         float maxGibbsMassA, float maxGibbsMassP, uint32_t seed, bool messages,
82 84
         bool singleCellRNASeq, unsigned cptInterval, const std::string &cptFile,
83
-        char whichMatrixFixed, const Rcpp::NumericMatrix &FP);
85
+        char whichMatrixFixed, const Rcpp::NumericMatrix &FP, unsigned nCores);
84 86
     
85 87
     // construct from checkpoint file
86 88
     GapsRunner(const Rcpp::NumericMatrix &D, const Rcpp::NumericMatrix &S,
... ...
@@ -77,7 +77,7 @@ protected:
77 77
 
78 78
 public:
79 79
 
80
-    void update(unsigned nSteps);
80
+    void update(unsigned nSteps, unsigned nCores);
81 81
     void setAnnealingTemp(float temp);
82 82
     float getAvgQueue() const { return mAvgQueue; }
83 83
     
... ...
@@ -171,19 +171,23 @@ T* GibbsSampler<T, MatA, MatB>::impl()
171 171
 }
172 172
 
173 173
 template <class T, class MatA, class MatB>
174
-void GibbsSampler<T, MatA, MatB>::update(unsigned nSteps)
174
+void GibbsSampler<T, MatA, MatB>::update(unsigned nSteps, unsigned nCores)
175 175
 {
176
+    static unsigned count = 0;
176 177
     unsigned n = 0;
177 178
     while (n < nSteps)
178 179
     {
179 180
         GAPS_ASSERT(nSteps - (mQueue.size() + n) >= 0);
180 181
         mQueue.populate(mDomain, nSteps - (mQueue.size() + n));
181
-        //mQueue.populate(mDomain, 1);
182
+        
183
+        //mQueue.populate(mDomain, std::min(2u, nSteps - (mQueue.size() + n)));
182 184
         GAPS_ASSERT(mQueue.size() > 0);
183 185
         mNumQueues += 1.f;
184 186
         mAvgQueue = mQueue.size() / mNumQueues + mAvgQueue * (mNumQueues - 1.f) / mNumQueues;
185 187
         n += mQueue.size();
186
-        //#pragma omp parallel for
188
+        //Rprintf("round: %d\n", count++);
189
+
190
+        #pragma omp parallel for num_threads(nCores)
187 191
         for (unsigned i = 0; i < mQueue.size(); ++i)
188 192
         {
189 193
             processProposal(mQueue[i]);
... ...
@@ -199,6 +203,7 @@ void GibbsSampler<T, MatA, MatB>::processProposal(const AtomicProposal &prop)
199 203
     unsigned r1 = impl()->getRow(prop.pos1);
200 204
     unsigned c1 = impl()->getCol(prop.pos1);
201 205
     unsigned r2 = 0, c2 = 0;
206
+    //Rprintf("type: %c pos1: %lu\n", prop.type, prop.pos1);
202 207
     switch (prop.type)
203 208
     {
204 209
         case 'B':
... ...
@@ -213,6 +218,7 @@ void GibbsSampler<T, MatA, MatB>::processProposal(const AtomicProposal &prop)
213 218
             move(prop.pos1, prop.mass1, prop.pos2, r1, c1, r2, c2);
214 219
             break;
215 220
         case 'E':
221
+            //Rprintf("pos2: %lu\n", prop.pos2);
216 222
             r2 = impl()->getRow(prop.pos2);
217 223
             c2 = impl()->getCol(prop.pos2);
218 224
             exchange(prop.pos1, prop.mass1, prop.pos2, prop.mass2, r1, c1, r2, c2);
... ...
@@ -223,17 +229,23 @@ void GibbsSampler<T, MatA, MatB>::processProposal(const AtomicProposal &prop)
223 229
 template <class T, class MatA, class MatB>
224 230
 void GibbsSampler<T, MatA, MatB>::addMass(uint64_t pos, float mass, unsigned row, unsigned col)
225 231
 {
226
-    mDomain.insert(pos, mass);
227
-    mMatrix(row, col) += mass;
228
-    impl()->updateAPMatrix(row, col, mass);
232
+    #pragma omp critical(gibbs)
233
+    {
234
+        mDomain.insert(pos, mass);
235
+        mMatrix(row, col) += mass;
236
+        impl()->updateAPMatrix(row, col, mass);
237
+    }
229 238
 }
230 239
 
231 240
 template <class T, class MatA, class MatB>
232 241
 void GibbsSampler<T, MatA, MatB>::removeMass(uint64_t pos, float mass, unsigned row, unsigned col)
233 242
 {
234
-    mDomain.erase(pos);
235
-    mMatrix(row, col) += -mass;
236
-    impl()->updateAPMatrix(row, col, -mass);
243
+    #pragma omp critical(gibbs)
244
+    {
245
+        mDomain.erase(pos);
246
+        mMatrix(row, col) += -mass;
247
+        impl()->updateAPMatrix(row, col, -mass);
248
+    }
237 249
 }
238 250
 
239 251
 // add an atom at pos, calculate mass either with an exponential distribution
... ...
@@ -244,16 +256,19 @@ unsigned col)
244 256
 {
245 257
     float mass = impl()->canUseGibbs(row, col) ? gibbsMass(row, col, mass)
246 258
         : gaps::random::exponential(mLambda);
247
-    if (mass >= gaps::algo::epsilon)
259
+    #pragma omp critical(gibbs)
248 260
     {
249
-        mDomain.updateMass(pos, mass);
250
-        mMatrix(row, col) += mass;
251
-        impl()->updateAPMatrix(row, col, mass);
252
-    }
253
-    else
254
-    {
255
-        mDomain.erase(pos);
256
-        mQueue.rejectBirth();
261
+        if (mass >= gaps::algo::epsilon)
262
+        {
263
+            mDomain.updateMass(pos, mass);
264
+            mMatrix(row, col) += mass;
265
+            impl()->updateAPMatrix(row, col, mass);
266
+        }
267
+        else
268
+        {
269
+            mDomain.erase(pos);
270
+            mQueue.rejectBirth();
271
+        }
257 272
     }
258 273
 }
259 274
 
... ...
@@ -263,6 +278,7 @@ template <class T, class MatA, class MatB>
263 278
 void GibbsSampler<T, MatA, MatB>::death(uint64_t pos, float mass, unsigned row,
264 279
 unsigned col)
265 280
 {
281
+    GAPS_ASSERT(mass > 0.f);
266 282
     removeMass(pos, mass, row, col);
267 283
     float newMass = impl()->canUseGibbs(row, col) ? gibbsMass(row, col, -mass) : 0.f;
268 284
     mass = newMass < gaps::algo::epsilon ? mass : newMass;
... ...
@@ -283,6 +299,7 @@ template <class T, class MatA, class MatB>
283 299
 void GibbsSampler<T, MatA, MatB>::move(uint64_t src, float mass, uint64_t dest,
284 300
 unsigned r1, unsigned c1, unsigned r2, unsigned c2)
285 301
 {
302
+    GAPS_ASSERT(mass > 0.f);
286 303
     if (r1 != r2 || c1 != c2) // automatically reject if change in same bin
287 304
     {
288 305
         float deltaLL = impl()->computeDeltaLL(r1, c1, -mass, r2, c2, mass);
... ...
@@ -301,6 +318,8 @@ template <class T, class MatA, class MatB>
301 318
 void GibbsSampler<T, MatA, MatB>::exchange(uint64_t p1, float m1, uint64_t p2,
302 319
 float m2, unsigned r1, unsigned c1, unsigned r2, unsigned c2)
303 320
 {
321
+    GAPS_ASSERT(m1 > 0.f);
322
+    GAPS_ASSERT(m2 > 0.f);
304 323
     float pUpper = gaps::random::p_gamma(m1 + m2, 2.f, 1.f / mLambda);
305 324
     float newMass = gaps::random::inverseGammaSample(0.f, pUpper, 2.f, 1.f / mLambda);
306 325
     if (r1 != r2 || c1 != c2) // automatically reject if change in same bin
... ...
@@ -355,17 +374,22 @@ template <class T, class MatA, class MatB>
355 374
 float GibbsSampler<T, MatA, MatB>::updateAtomMass(uint64_t pos, float mass,
356 375
 float delta)
357 376
 {
358
-    if (mass + delta < gaps::algo::epsilon)
359
-    {
360
-        mDomain.erase(pos);
361
-        mQueue.acceptDeath();
362
-        return false;
363
-    }
364
-    else
377
+    bool ret_val = false;
378
+    #pragma omp critical(gibbs)
365 379
     {
366
-        mDomain.updateMass(pos, mass + delta);
367
-        return true;
380
+        if (mass + delta < gaps::algo::epsilon)
381
+        {
382
+            mDomain.erase(pos);
383
+            mQueue.acceptDeath();
384
+            ret_val = false;
385
+        }
386
+        else
387
+        {
388
+            mDomain.updateMass(pos, mass + delta);
389
+            ret_val = true;
390
+        }
368 391
     }
392
+    return ret_val;
369 393
 }
370 394
 
371 395
 // helper function for exchange step, updates the atomic domain, matrix, and
... ...
@@ -375,6 +399,7 @@ void GibbsSampler<T, MatA, MatB>::acceptExchange(uint64_t p1, float m1,
375 399
 float d1, uint64_t p2, float m2, float d2, unsigned r1, unsigned c1,
376 400
 unsigned r2, unsigned c2)
377 401
 {
402
+    //Rprintf("p1: %lu p2: %lu\n", p1, p2);
378 403
     bool b1 = updateAtomMass(p1, m1, d1);
379 404
     bool b2 = updateAtomMass(p2, m2, d2);
380 405
     GAPS_ASSERT(b1 || b2);
... ...
@@ -387,10 +412,13 @@ unsigned r2, unsigned c2)
387 412
         mQueue.rejectDeath();
388 413
     }
389 414
 
390
-    mMatrix(r1, c1) += d1;
391
-    mMatrix(r2, c2) += d2;
392
-    impl()->updateAPMatrix(r1, c1, d1);
393
-    impl()->updateAPMatrix(r2, c2, d2);
415
+    #pragma omp critical(gibbs)
416
+    {
417
+        mMatrix(r1, c1) += d1;
418
+        mMatrix(r2, c2) += d2;
419
+        impl()->updateAPMatrix(r1, c1, d1);
420
+        impl()->updateAPMatrix(r2, c2, d2);
421
+    }
394 422
 }
395 423
 
396 424
 template <class T, class MatA, class MatB>
... ...
@@ -52,17 +52,22 @@ const AtomicProposal& ProposalQueue::operator[](int n) const
52 52
 
53 53
 void ProposalQueue::acceptDeath()
54 54
 {
55
+    #pragma omp atomic
55 56
     mMaxAtoms--;
56 57
 }
57 58
 
58 59
 void ProposalQueue::rejectDeath()
59 60
 {
61
+    #pragma omp atomic
60 62
     mMinAtoms++;
61 63
 }
62 64
 
63 65
 void ProposalQueue::rejectBirth()
64 66
 {
67
+    #pragma omp atomic
65 68
     mMinAtoms--;
69
+
70
+    #pragma omp atomic
66 71
     mMaxAtoms--;
67 72
 }
68 73
 
... ...
@@ -6,8 +6,8 @@
6 6
 using namespace Rcpp;
7 7
 
8 8
 // cogaps_cpp
9
-Rcpp::List cogaps_cpp(const Rcpp::NumericMatrix& D, const Rcpp::NumericMatrix& S, unsigned nFactor, unsigned nEquil, unsigned nEquilCool, unsigned nSample, unsigned nOutputs, unsigned nSnapshots, float alphaA, float alphaP, float maxGibbmassA, float maxGibbmassP, unsigned seed, bool messages, bool singleCellRNASeq, char whichMatrixFixed, const Rcpp::NumericMatrix& FP, unsigned checkpointInterval, const std::string& cptFile, unsigned pumpThreshold, unsigned nPumpSamples);
10
-RcppExport SEXP _CoGAPS_cogaps_cpp(SEXP DSEXP, SEXP SSEXP, SEXP nFactorSEXP, SEXP nEquilSEXP, SEXP nEquilCoolSEXP, SEXP nSampleSEXP, SEXP nOutputsSEXP, SEXP nSnapshotsSEXP, SEXP alphaASEXP, SEXP alphaPSEXP, SEXP maxGibbmassASEXP, SEXP maxGibbmassPSEXP, SEXP seedSEXP, SEXP messagesSEXP, SEXP singleCellRNASeqSEXP, SEXP whichMatrixFixedSEXP, SEXP FPSEXP, SEXP checkpointIntervalSEXP, SEXP cptFileSEXP, SEXP pumpThresholdSEXP, SEXP nPumpSamplesSEXP) {
9
+Rcpp::List cogaps_cpp(const Rcpp::NumericMatrix& D, const Rcpp::NumericMatrix& S, unsigned nFactor, unsigned nEquil, unsigned nEquilCool, unsigned nSample, unsigned nOutputs, unsigned nSnapshots, float alphaA, float alphaP, float maxGibbmassA, float maxGibbmassP, unsigned seed, bool messages, bool singleCellRNASeq, char whichMatrixFixed, const Rcpp::NumericMatrix& FP, unsigned checkpointInterval, const std::string& cptFile, unsigned pumpThreshold, unsigned nPumpSamples, unsigned nCores);
10
+RcppExport SEXP _CoGAPS_cogaps_cpp(SEXP DSEXP, SEXP SSEXP, SEXP nFactorSEXP, SEXP nEquilSEXP, SEXP nEquilCoolSEXP, SEXP nSampleSEXP, SEXP nOutputsSEXP, SEXP nSnapshotsSEXP, SEXP alphaASEXP, SEXP alphaPSEXP, SEXP maxGibbmassASEXP, SEXP maxGibbmassPSEXP, SEXP seedSEXP, SEXP messagesSEXP, SEXP singleCellRNASeqSEXP, SEXP whichMatrixFixedSEXP, SEXP FPSEXP, SEXP checkpointIntervalSEXP, SEXP cptFileSEXP, SEXP pumpThresholdSEXP, SEXP nPumpSamplesSEXP, SEXP nCoresSEXP) {
11 11
 BEGIN_RCPP
12 12
     Rcpp::RObject rcpp_result_gen;
13 13
     Rcpp::RNGScope rcpp_rngScope_gen;
... ...
@@ -32,7 +32,8 @@ BEGIN_RCPP
32 32
     Rcpp::traits::input_parameter< const std::string& >::type cptFile(cptFileSEXP);
33 33
     Rcpp::traits::input_parameter< unsigned >::type pumpThreshold(pumpThresholdSEXP);
34 34
     Rcpp::traits::input_parameter< unsigned >::type nPumpSamples(nPumpSamplesSEXP);
35
-    rcpp_result_gen = Rcpp::wrap(cogaps_cpp(D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples));
35
+    Rcpp::traits::input_parameter< unsigned >::type nCores(nCoresSEXP);
36
+    rcpp_result_gen = Rcpp::wrap(cogaps_cpp(D, S, nFactor, nEquil, nEquilCool, nSample, nOutputs, nSnapshots, alphaA, alphaP, maxGibbmassA, maxGibbmassP, seed, messages, singleCellRNASeq, whichMatrixFixed, FP, checkpointInterval, cptFile, pumpThreshold, nPumpSamples, nCores));
36 37
     return rcpp_result_gen;
37 38
 END_RCPP
38 39
 }
... ...
@@ -75,7 +76,7 @@ END_RCPP
75 76
 }
76 77
 
77 78
 static const R_CallMethodDef CallEntries[] = {
78
-    {"_CoGAPS_cogaps_cpp", (DL_FUNC) &_CoGAPS_cogaps_cpp, 21},
79
+    {"_CoGAPS_cogaps_cpp", (DL_FUNC) &_CoGAPS_cogaps_cpp, 22},
79 80
     {"_CoGAPS_cogapsFromCheckpoint_cpp", (DL_FUNC) &_CoGAPS_cogapsFromCheckpoint_cpp, 7},
80 81
     {"_CoGAPS_getBuildReport_cpp", (DL_FUNC) &_CoGAPS_getBuildReport_cpp, 0},
81 82
     {"_CoGAPS_run_catch_unit_tests", (DL_FUNC) &_CoGAPS_run_catch_unit_tests, 0},
... ...
@@ -10,7 +10,7 @@ TEST_CASE("Test Top Level CoGAPS Call")
10 10
 
11 11
     GapsRunner runner(D, S, 3, 500, 100, 500, 250, 0, 0.01f, 0.01f, 100.f,
12 12
         100.f, 123, false, false, 0, "gaps_checkpoint.out", 'N',
13
-        Rcpp::NumericMatrix(1,1));
13
+        Rcpp::NumericMatrix(1,1), 1);
14 14
     REQUIRE_NOTHROW(runner.run());
15 15
 }
16 16