1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/*
Copyright (c) 2009-2017, UT-Battelle, LLC
All rights reserved
[PsimagLite, Version 1.]
*********************************************************
THE SOFTWARE IS SUPPLIED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED.
Please see full open source license included in file LICENSE.
*********************************************************
*/
#include "../src/Concurrency.h"
#include <cstdlib>
#include <iostream>
#define USE_PTHREADS_OR_NOT_NG
#include "../src/Parallelizer.h"
class InnerHelper
{
typedef PsimagLite::Concurrency ConcurrencyType;
typedef PsimagLite::Vector<SizeType>::Type VectorSizeType;
public:
InnerHelper(SizeType ntasks, SizeType nthreads, int outerTask)
: ntasks_(ntasks)
, x_(nthreads, 0)
, offset_(outerTask * ntasks)
{
}
SizeType tasks() const { return ntasks_; }
int result() const { return x_[0]; }
void doTask(SizeType taskNumber, SizeType threadNum)
{
x_[threadNum] += taskNumber + offset_;
}
void sync()
{
for (SizeType i = 1; i < x_.size(); ++i)
x_[0] += x_[i];
}
private:
SizeType ntasks_;
VectorSizeType x_;
SizeType offset_;
}; // class InnerHelper
class MyHelper
{
typedef PsimagLite::Concurrency ConcurrencyType;
typedef PsimagLite::Vector<SizeType>::Type VectorSizeType;
public:
MyHelper(SizeType ntasks, SizeType nthreadsOuter, SizeType ntasksInner, SizeType nthreadsInner)
: ntasks_(ntasks)
, x_(nthreadsOuter, 0)
, ntasksInner_(ntasksInner)
, nthreadsInner_(nthreadsInner)
{
}
SizeType tasks() const { return ntasks_; }
int result() const { return x_[0]; }
void doTask(SizeType taskNumber, SizeType threadNum)
{
typedef PsimagLite::Parallelizer<InnerHelper> ParallelizerType;
PsimagLite::CodeSectionParams cs(nthreadsInner_);
ParallelizerType threadObject(cs);
InnerHelper helper(ntasksInner_, nthreadsInner_, taskNumber);
threadObject.loopCreate(helper);
helper.sync();
x_[threadNum] += helper.result();
}
void sync()
{
for (SizeType i = 1; i < x_.size(); ++i)
x_[0] += x_[i];
}
private:
SizeType ntasks_;
VectorSizeType x_;
SizeType ntasksInner_;
SizeType nthreadsInner_;
}; // class MyHelper
int main(int argc, char* argv[])
{
typedef PsimagLite::Concurrency ConcurrencyType;
if (argc != 5) {
std::cout << "USAGE: " << argv[0]
<< " threadsOuter tasksOuter threadsInner tasksInner\n";
return 1;
}
SizeType nthreadsOuter = atoi(argv[1]);
SizeType ntasks = atoi(argv[2]);
SizeType nthreadsInner = atoi(argv[3]);
SizeType ntasksInner = atoi(argv[4]);
ConcurrencyType concurrency(&argc, &argv, 1);
typedef MyHelper HelperType;
typedef PsimagLite::Parallelizer<HelperType> ParallelizerType;
PsimagLite::CodeSectionParams cs(nthreadsOuter);
ParallelizerType threadObject(cs);
HelperType helper(ntasks, nthreadsOuter, ntasksInner, nthreadsInner);
std::cout << "Using " << threadObject.name();
std::cout << " with " << nthreadsOuter << " threads.\n";
threadObject.loopCreate(helper);
helper.sync();
std::cout << "Sum of all tasks= " << helper.result() << "\n";
}
|