00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #ifndef TEST_PATTERN_H
00025 #define TEST_PATTERN_H
00026 #include <cppunit/extensions/HelperMacros.h>
00027 #include <cppunit/TestAssert.h>
00028 #include "baseTest.h"
00029 
00030 #include <amino/cstdatomic>
00031 #include <amino/thread.h>
00032 #include <amino/foreach.h>
00033 #include <amino/tp_exec.h>
00034 #include <amino/accumulate.h>
00035 #include <amino/transform.h>
00036 
00037 #include <iostream>
00038 #include <assert.h>
00039 #include <unistd.h>
00040 
00041 namespace test {
00042 using namespace amino;
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 template<typename ParaType>
00053 class UnaryFunc {
00054 public:
00055         ParaType operator()(ParaType element) {
00056                 return 2 * element;
00057         }
00058 };
00059 template<typename ParaType>
00060 class BinaryFunc {
00061 public:
00062         ParaType operator()(ParaType ele1, ParaType ele2) {
00063                 return ele1 * ele2;
00064         }
00065 };
00066 template<typename ElementT, const char * CLASS_NAME>
00067 class PatternTest: public CppUnit::TestFixture, public BaseTest<ElementT> {
00068     CPPUNIT_TEST_SUITE(PatternTest);
00069         CPPUNIT_TEST(testForeach);
00070         CPPUNIT_TEST(testAccumulate);
00071         CPPUNIT_TEST(testTransform);
00072         CPPUNIT_TEST_SUITE_END()
00073         ;
00074 public:
00075         PatternTest() {
00076         }
00077 
00078         void setUp() {
00079         }
00080 
00081         void reset() {
00082         }
00083 
00084         void tearDown() {
00085         }
00086 
00087         void testForeach() {
00088                 UnaryFunc<ElementT> uf;
00089                 Logger log(stderr);
00090                 vector<int> thread_v = TestConfig::getInstance()->getThreadNum();
00091                 for (unsigned int i = 0; i < thread_v.size(); i++) {
00092                         ThreadPoolExecutor exec;
00093                         ElementT* verify = new ElementT[this->NELEMENT * thread_v[i]];
00094                         std::copy(this->data, this->data + this->NELEMENT * thread_v[i],
00095                                         verify);
00096 
00097                         struct timeval t1, t2, t3;
00098                         gettimeofday(&t1, NULL);
00099 
00100                         for_each(exec, thread_v[i], this->data, this->data + this->NELEMENT
00101                                         * thread_v[i], uf);
00102                         exec.shutdown();
00103                         exec.waitTermination();
00104 
00105                         gettimeofday(&t2, NULL);
00106 
00107                         for_each(verify, verify + this->NELEMENT * thread_v[i], uf);
00108 
00109                         gettimeofday(&t3, NULL);
00110 
00111                         int takes1 = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec
00112                         - t1.tv_usec;
00113                         log.log(
00114                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00115                                         "ParallelSort", thread_v[i], this->NELEMENT,
00116                                         "testSort", takes1);
00117 
00118                         int takes2 = (t3.tv_sec - t2.tv_sec) * 1000000 + t3.tv_usec
00119                         - t2.tv_usec;
00120                         log.log(
00121                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00122                                         "SerialSort", 1, this->NELEMENT * thread_v[i],
00123                                         "testSort", takes2);
00124 
00125                         for (int i = 0; i < this->NELEMENT * thread_v[i]; i++) {
00126                                 CPPUNIT_ASSERT(this->data[i]==verify[i]);
00127                         }
00128 
00129                         delete[] verify;
00130                 }
00131         }
00132 
00133         void testAccumulate() {
00134                 Logger log(stderr);
00135                 vector<int> thread_v = TestConfig::getInstance()->getThreadNum();
00136                 for (unsigned int i = 0; i < thread_v.size(); i++) {
00137                         ThreadPoolExecutor exec;
00138 
00139                         struct timeval t1, t2, t3, t4, t5;
00140                         gettimeofday(&t1, NULL);
00141 
00142                         ElementT myResult1 = accumulate<ElementT*, ElementT,
00143                         ThreadPoolExecutor> (exec, thread_v[i], this->data,
00144                                         this->data + this->NELEMENT * thread_v[i]);
00145                         
00146                         
00147 
00148                         gettimeofday(&t2, NULL);
00149 
00150                         ElementT verifyResult1 = accumulate(this->data + 1, this->data
00151                                         + this->NELEMENT * thread_v[i], *(this->data));
00152 
00153                         gettimeofday(&t3, NULL);
00154 
00155                         ElementT myResult2 = accumulate<ElementT*, ElementT,BinaryFunc<ElementT>,
00156                         ThreadPoolExecutor> (exec, thread_v[i], this->data,
00157                                         this->data + this->NELEMENT * thread_v[i],BinaryFunc<ElementT>());
00158                         exec.shutdown();
00159                         exec.waitTermination();
00160                         gettimeofday(&t4, NULL);
00161 
00162                         ElementT verifyResult2 = accumulate(this->data + 1, this->data
00163                                         + this->NELEMENT * thread_v[i], *(this->data),BinaryFunc<ElementT>());
00164 
00165                         gettimeofday(&t5, NULL);
00166 
00167                         int takes1 = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec
00168                         - t1.tv_usec;
00169                         log.log(
00170                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00171                                         "ParallelAccumulate", thread_v[i], this->NELEMENT,
00172                                         "testAccumulate", takes1);
00173 
00174                         int takes2 = (t3.tv_sec - t2.tv_sec) * 1000000 + t3.tv_usec
00175                         - t2.tv_usec;
00176                         log.log(
00177                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00178                                         "SerialAccumulate", 1, this->NELEMENT * thread_v[i],
00179                                         "testAccumulate", takes2);
00180 
00181                         int takes3 = (t4.tv_sec - t3.tv_sec) * 1000000 + t4.tv_usec
00182                         - t3.tv_usec;
00183                         log.log(
00184                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00185                                         "ParallelAccumulateFunc", thread_v[i], this->NELEMENT,
00186                                         "testAccumulateFunc", takes3);
00187 
00188                         int takes4 = (t5.tv_sec - t4.tv_sec) * 1000000 + t5.tv_usec
00189                         - t4.tv_usec;
00190                         log.log(
00191                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00192                                         "SerialAccumulateFunc", 1, this->NELEMENT * thread_v[i],
00193                                         "testAccumulateFunc", takes4);
00194 
00195                         for (int i = 0; i < this->NELEMENT * thread_v[i]; i++) {
00196                                 CPPUNIT_ASSERT(myResult1==verifyResult1);
00197                                 CPPUNIT_ASSERT(myResult2==verifyResult2);
00198                         }
00199 
00200                 }
00201         }
00202 
00203         void testTransform() {
00204                 Logger log(stderr);
00205                 vector<int> thread_v = TestConfig::getInstance()->getThreadNum();
00206                 for (unsigned int i = 0; i < thread_v.size(); i++) {
00207                         ThreadPoolExecutor exec;
00208 
00209                         ElementT* result1 = new ElementT[this->NELEMENT * thread_v[i]];
00210                         ElementT* result2 = new ElementT[this->NELEMENT * thread_v[i]];
00211                         ElementT* result3 = new ElementT[this->NELEMENT * thread_v[i]];
00212                         ElementT* result4 = new ElementT[this->NELEMENT * thread_v[i]];
00213 
00214                         struct timeval t1, t2, t3, t4, t5;
00215                         gettimeofday(&t1, NULL);
00216 
00217                         transform(exec, thread_v[i], this->data, this->data+this->NELEMENT*thread_v[i], result1, UnaryFunc<ElementT>());
00218                         
00219                         
00220 
00221                         gettimeofday(&t2, NULL);
00222 
00223                         transform(this->data, this->data + this->NELEMENT * thread_v[i], result2, UnaryFunc<ElementT>());
00224 
00225                         gettimeofday(&t3, NULL);
00226 
00227                         transform(exec, thread_v[i], this->data, this->data+this->NELEMENT*thread_v[i], result1, result3, BinaryFunc<ElementT>());
00228                         exec.shutdown();
00229                         exec.waitTermination();
00230 
00231                         gettimeofday(&t4, NULL);
00232 
00233                         std::transform(this->data, this->data + this->NELEMENT * thread_v[i], result1, result4, BinaryFunc<ElementT>());
00234 
00235                         gettimeofday(&t5, NULL);
00236 
00237                         int takes1 = (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec
00238                         - t1.tv_usec;
00239                         log.log(
00240                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00241                                         "ParallelTransformUnary", thread_v[i], this->NELEMENT,
00242                                         "testTransformUnary", takes1);
00243 
00244                         int takes2 = (t3.tv_sec - t2.tv_sec) * 1000000 + t3.tv_usec
00245                         - t2.tv_usec;
00246                         log.log(
00247                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00248                                         "SerialTransformUnary", 1, this->NELEMENT * thread_v[i],
00249                                         "testTransformUnary", takes2);
00250                         int takes3 = (t4.tv_sec - t3.tv_sec) * 1000000 + t4.tv_usec
00251                         - t3.tv_usec;
00252                         log.log(
00253                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00254                                         "ParallelTransformBinary", thread_v[i], this->NELEMENT,
00255                                         "testTransformBinary", takes3);
00256 
00257                         int takes4 = (t5.tv_sec - t4.tv_sec) * 1000000 + t5.tv_usec
00258                         - t4.tv_usec;
00259                         log.log(
00260                                         "INFO: class:   %s\tnThread:\t%d\tnElement:\t%d\ttestName:\t%s\tTakes:\t%d\tmicroseconds\n",
00261                                         "SerialTransformBinary", 1, this->NELEMENT * thread_v[i],
00262                                         "testTransformBinary", takes4);
00263 
00264                         for (int i = 0; i < this->NELEMENT * thread_v[i]; i++) {
00265                                 CPPUNIT_ASSERT(result1[i] == result2[i]);
00266                                 CPPUNIT_ASSERT(result3[i] == result4[i]);
00267                         }
00268 
00269                         delete[] result1;
00270                         delete[] result2;
00271                         delete[] result3;
00272                         delete[] result4;
00273                 }
00274 
00275         }
00276 };
00277 }
00278 #endif