From: Benjamin Segovia Date: Sun, 22 Jan 2012 07:00:33 +0000 (+0000) Subject: Removed unused tests X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0eafdfac2af7b4e7bc7eda61990eb5b6215b0e83;p=contrib%2Fbeignet.git Removed unused tests --- diff --git a/backend/src/utest/utest_console.cpp b/backend/src/utest/utest_console.cpp deleted file mode 100644 index 5c5c4ce..0000000 --- a/backend/src/utest/utest_console.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Benjamin Segovia - */ - -#include "utest/utest.hpp" -#include "sys/command.hpp" -#include "sys/console.hpp" -#include "sys/logging.hpp" -#include "sys/windowing.hpp" -#include "sys/script.hpp" -#include - -namespace pf -{ - /*! Output everything in the terminal */ - class UTestConsoleDisplay : public ConsoleDisplay - { - public: - UTestConsoleDisplay (void) { - last = lastBlink = getSeconds(); - cursor = 0; - } - virtual void line(Console &console, const std::string &line) { - const double curr = getSeconds(); - std::string patched = line; - if (curr - lastBlink > .5) { - cursor ^= 1; - lastBlink = curr; - } - const uint32 pos = console.cursorPosition(); - if (cursor) { - if (pos >= patched.size()) - patched.push_back('_'); - else - patched[pos] = '_'; - } - if (curr - last > 0.02) { - std::cout << '\r' << "> " << patched; - for (int i = 0; i < 80; ++i) std::cout << ' '; - std::cout << '\r'; - fflush(stdout); - last = curr; - } - } - virtual void out(Console &console, const std::string &str) { - std::cout << str << std::endl; - } - double last; - double lastBlink; - uint32 cursor; - }; -} /* namespace pf */ - -void utest_console(void) -{ - using namespace pf; - WinOpen(640, 480); - ScriptSystem *scriptSystem = LuaScriptSystemCreate(); - CommandSystemStart(*scriptSystem); - UTestConsoleDisplay *display = GBE_NEW(UTestConsoleDisplay); - Console *console = ConsoleNew(*scriptSystem, *display); - console->addCompletion("while"); - console->addCompletion("whilewhile"); - for (;;) { - Ref input = GBE_NEW(InputControl); - input->processEvents(); - if (input->getKey(GBE_KEY_ASCII_ESC)) - break; - console->update(*input); - WinSwapBuffers(); - } - CommandSystemEnd(); - GBE_DELETE(console); - GBE_DELETE(scriptSystem); - GBE_DELETE(display); - WinClose(); -} - -UTEST_REGISTER(utest_console); - diff --git a/backend/src/utest/utest_font.cpp b/backend/src/utest/utest_font.cpp deleted file mode 100644 index cf00280..0000000 --- a/backend/src/utest/utest_font.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Benjamin Segovia - */ - -#include "renderer/font.hpp" -#include "sys/default_path.hpp" -#include "utest/utest.hpp" - -#include - -using namespace pf; -static const std::string fontName = "font.fnt"; - -void utest_font(void) -{ - Font font; - size_t i = 0; - for (; i < defaultPathNum; ++i) { - const FileName path(std::string(defaultPath[i]) + fontName); - if (font.load(path)) break; - } - GBE_ASSERT(i < defaultPathNum); -} - -UTEST_REGISTER(utest_font); - diff --git a/backend/src/utest/utest_lua.cpp b/backend/src/utest/utest_lua.cpp deleted file mode 100644 index f1a0182..0000000 --- a/backend/src/utest/utest_lua.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Benjamin Segovia - */ - -#include "sys/script.hpp" -#include "sys/command.hpp" -#include "sys/logging.hpp" -#include "sys/tasking.hpp" -#include "utest/utest.hpp" - -using namespace pf; - -VARI(coucou, 0, 2, 3, "coucou"); -VARS(player0, "ben", "player name"); - -#define _RUN_SCRIPT(STR, RUN_MODE) do {\ - ScriptStatus status;\ - scriptSystem->RUN_MODE(STR, status);\ - if (!status.success) GBE_ERROR(status.msg);\ -} while (0) -#define RUN(STR) _RUN_SCRIPT(STR,run) -#define RUN_NON_PROTECTED(STR) _RUN_SCRIPT(STR,runNonProtected) - -void utest_lua(void) -{ - ScriptSystem *scriptSystem = LuaScriptSystemCreate(); - ScriptStatus status; - scriptSystem->run("local x = 0", status); - CommandSystemStart(*scriptSystem); - - // Run some code. This may modify console variables - RUN("cv.coucou = 1"); - RUN_NON_PROTECTED("print(pf.cv.coucou)"); - RUN("cv.player0 = \"hop\""); - RUN_NON_PROTECTED("print(pf.cv.player0)"); - if (coucou() == 1) GBE_MSG("coucou is equal to 1"); - - CommandSystemEnd(); - GBE_DELETE(scriptSystem); -} - -UTEST_REGISTER(utest_lua) - diff --git a/backend/src/utest/utest_rt.cpp b/backend/src/utest/utest_rt.cpp deleted file mode 100644 index c9bdc0c..0000000 --- a/backend/src/utest/utest_rt.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Benjamin Segovia - */ - -#include "renderer/renderer_obj.hpp" -#include "renderer/renderer.hpp" -#include "rt/bvh2_traverser.hpp" -#include "rt/bvh2.hpp" -#include "rt/rt_triangle.hpp" -#include "rt/rt_camera.hpp" -#include "models/obj.hpp" -#include "game/camera.hpp" -#include "image/stb_image.hpp" - -#include "sys/alloc.hpp" -#include "sys/tasking.hpp" -#include "sys/tasking_utility.hpp" -#include "sys/logging.hpp" -#include "sys/default_path.hpp" - -#include "utest/utest.hpp" - -#include -#include -#include -#include - -namespace pf -{ - static Ref intersector = NULL; - static const int CAMW = 1024, CAMH = 1024; - - static const FileName objName("f000.obj"); - //static const FileName objName("arabic_city_II.obj"); - //static const FileName objName("conference.obj"); - //static const FileName objName("sibenik.obj"); - //static const FileName objName("sponza.obj"); - - static RTTriangle *ObjComputeTriangle(const Obj &obj) { - RTTriangle *tris = GBE_NEW_ARRAY(RTTriangle, obj.triNum); - for (size_t i = 0; i < obj.triNum; ++i) { - const vec3f &v0 = obj.vert[obj.tri[i].v[0]].p; - const vec3f &v1 = obj.vert[obj.tri[i].v[1]].p; - const vec3f &v2 = obj.vert[obj.tri[i].v[2]].p; - tris[i] = RTTriangle(v0,v1,v2); - } - return tris; - } - - /*! Task set that computes a frame buffer with ray tracing */ - template - class TaskRayTrace : public TaskSet - { - public: - INLINE TaskRayTrace(const Intersector &intersector, - const RTCamera &cam, - const uint32 *c, - uint32 *rgba, - uint32 w, uint32 jobNum) : - TaskSet(jobNum, "TaskRayTrace"), - intersector(intersector), cam(cam), c(c), rgba(rgba), - w(w), h(jobNum * RayPacket::height) {} - - virtual void run(size_t jobID) - { - if (singleRay) { - RTCameraRayGen gen; - cam.createGenerator(gen, w, h); - for (uint32 row = 0; row < RayPacket::height; ++row) { - const uint32 y = row + jobID * RayPacket::height; - for (uint32 x = 0; x < w; ++x) { - Ray ray; - Hit hit; - gen.generate(ray, x, y); - intersector.traverse(ray, hit); - rgba[x + y*w] = hit ? c[hit.id0] : 0u; - } - } - } else { - RTCameraPacketGen gen; - cam.createGenerator(gen, w, h); - const uint32 y = jobID * RayPacket::height; - for (uint32 x = 0; x < w; x += RayPacket::width) { - RayPacket pckt; - PacketHit hit; - gen.generate(pckt, x, y); - intersector.traverse(pckt, hit); - const int32 *IDs = (const int32 *) &hit.id0[0][0]; - uint32 curr = 0; - for (uint32 j = 0; j < pckt.height; ++j) { - for (uint32 i = 0; i < pckt.width; ++i, ++curr) { - const uint32 offset = x + i + (y + j) * w; - rgba[offset] = IDs[curr] != -1 ? c[IDs[curr]] : 0u; - } - } - } - } - } - - const Intersector &intersector; //!< To traverse the scene - const RTCamera &cam; //!< Parameterize the view - const uint32 *c; //!< One color per triangle - uint32 *rgba; //!< Frame buffer - uint32 w, h; //!< Frame buffer dimensions - }; - - /*! Ray trace the loaded scene */ - template - static void rayTrace(int w, int h, const uint32 *c) { - FPSCamera fpsCam; - const RTCamera cam(fpsCam.org, fpsCam.up, fpsCam.view, fpsCam.fov, fpsCam.ratio); - uint32 *rgba = GBE_NEW_ARRAY(uint32, w * h); - std::memset(rgba, 0, sizeof(uint32) * w * h); - GBE_COMPILER_READ_WRITE_BARRIER; - const double t = getSeconds(); - Task *rayTask = GBE_NEW(TaskRayTrace, *intersector, - cam, c, rgba, w, h/RayPacket::height); - Task *returnToMain = GBE_NEW(TaskInterruptMain); - rayTask->starts(returnToMain); - rayTask->scheduled(); - returnToMain->scheduled(); - TaskingSystemEnter(); - const double dt = getSeconds() - t; - GBE_MSG_V(dt * 1000. << " msec - " << CAMW * CAMH / dt << " rays/s"); - if (singleRay) - stbi_write_bmp("single.bmp", w, h, 4, rgba); - else - stbi_write_bmp("packet.bmp", w, h, 4, rgba); - GBE_DELETE_ARRAY(rgba); - } - - static void RTStart(void) - { - Obj obj; - size_t path = 0; - for (path = 0; path < defaultPathNum; ++path) - if (obj.load(FileName(defaultPath[path]) + objName)) { - GBE_MSG_V("Obj: " << objName << " loaded from " << defaultPath[path]); - break; - } - if (path == defaultPathNum) - GBE_WARNING_V("Obj: " << objName << " not found"); - - // Build the BVH - RTTriangle *tris = ObjComputeTriangle(obj); - Ref> bvh = GBE_NEW(BVH2); - buildBVH2(tris, obj.triNum, *bvh); - GBE_DELETE_ARRAY(tris); - - // Now we have an intersector on the triangle soup - intersector = GBE_NEW(BVH2Traverser, bvh); - - // Compute some triangle color - uint32 *c = GBE_NEW_ARRAY(uint32, bvh->primNum); - for (uint32 i = 0; i < bvh->primNum; ++i) { - c[i] = rand(); - c[i] |= 0xff000000; - } - - // Ray trace now - GBE_MSG_V("Packet ray tracing"); - for (int i = 0; i < 16; ++i) rayTrace(CAMW, CAMH, c); - GBE_MSG_V("Single ray tracing"); - for (int i = 0; i < 16; ++i) rayTrace(CAMW, CAMH, c); - GBE_DELETE_ARRAY(c); - } - - static void RTEnd(void) { intersector = NULL; } -} - -void utest_rt(void) -{ - using namespace pf; - RTStart(); - RTEnd(); -} - -UTEST_REGISTER(utest_rt); diff --git a/backend/src/utest/utest_tasking.cpp b/backend/src/utest/utest_tasking.cpp deleted file mode 100644 index 97797f3..0000000 --- a/backend/src/utest/utest_tasking.cpp +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: Benjamin Segovia - */ - -#include "sys/tasking.hpp" -#include "sys/tasking_utility.hpp" -#include "sys/ref.hpp" -#include "sys/thread.hpp" -#include "sys/mutex.hpp" -#include "sys/sysinfo.hpp" -#include "math/random.hpp" - -#include "utest/utest.hpp" - -#define START_UTEST(TEST_NAME) \ -void TEST_NAME(void) \ -{ \ - std::cout << std::endl << "starting " << \ - #TEST_NAME << std::endl; - -#define END_UTEST(TEST_NAME) \ - std::cout << "ending " << #TEST_NAME << std::endl; \ -} - -using namespace pf; - -/////////////////////////////////////////////////////////////////////////////// -// Very simple test which basically does nothing -/////////////////////////////////////////////////////////////////////////////// -class TaskDone : public Task { -public: - virtual Task* run(void) { - TaskingSystemInterruptMain(); - return NULL; - } -}; - -START_UTEST(TestDummy) - Task *done = GBE_NEW(TaskDone); - Task *nothing = GBE_NEW(TaskDummy); - nothing->starts(done); - done->scheduled(); - nothing->scheduled(); - TaskingSystemEnter(); -END_UTEST(TestDummy) - -/////////////////////////////////////////////////////////////////////////////// -// Simplest taskset test. An array is filled by each worker -/////////////////////////////////////////////////////////////////////////////// -class TaskSetSimple : public TaskSet { -public: - INLINE TaskSetSimple(size_t elemNum, uint32 *array_) : - TaskSet(elemNum), array(array_) {} - virtual void run(size_t elemID) { array[elemID] = 1u; } - uint32 *array; -}; - -START_UTEST(TestTaskSet) - const size_t elemNum = 1 << 20; - uint32 *array = GBE_NEW_ARRAY(uint32, elemNum); - for (size_t i = 0; i < elemNum; ++i) array[i] = 0; - double t = getSeconds(); - Task *done = GBE_NEW(TaskDone); - Task *taskSet = GBE_NEW(TaskSetSimple, elemNum, array); - taskSet->starts(done); - done->scheduled(); - taskSet->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; - for (size_t i = 0; i < elemNum; ++i) - FATAL_IF(array[i] == 0, "TestTaskSet failed"); - GBE_DELETE_ARRAY(array); -END_UTEST(TestTaskSet) - -/////////////////////////////////////////////////////////////////////////////// -// We create a binary tree of tasks here. Each task spawn a two children upto a -// given maximum level. Then, a atomic value is updated per leaf. In that test, -// all tasks complete the ROOT directly -/////////////////////////////////////////////////////////////////////////////// -enum { maxLevel = 20u }; - -/*! One node task per node in the tree. Task completes the root */ -class TaskNode : public Task { -public: - INLINE TaskNode(Atomic &value_, uint32 lvl_, Task *root_=NULL) : - value(value_), lvl(lvl_) { - this->root = root_ == NULL ? this : root_; - } - virtual Task* run(void); - Atomic &value; - Task *root; - uint32 lvl; -}; - -Task* TaskNode::run(void) { - if (this->lvl == maxLevel) - this->value++; - else { - Task *left = GBE_NEW(TaskNode, this->value, this->lvl+1, this->root); - Task *right = GBE_NEW(TaskNode, this->value, this->lvl+1, this->root); - left->ends(this->root); - right->ends(this->root); - left->scheduled(); - right->scheduled(); - } - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -// Same as TaskNode but we use a continuation passing style strategy to improve -// the system throughtput -/////////////////////////////////////////////////////////////////////////////// - -/*! One node task per node in the tree. Task completes the root */ -class TaskNodeOpt : public Task { -public: - INLINE TaskNodeOpt(Atomic &value_, uint32 lvl_, Task *root_=NULL) : - value(value_), lvl(lvl_) { - this->root = root_ == NULL ? this : root_; - } - virtual Task* run(void); - Atomic &value; - Task *root; - uint32 lvl; -}; - -Task* TaskNodeOpt::run(void) { - if (this->lvl == maxLevel) { - this->value++; - return NULL; - } else { - Task *left = GBE_NEW(TaskNode, this->value, this->lvl+1, this->root); - Task *right = GBE_NEW(TaskNode, this->value, this->lvl+1, this->root); - left->ends(this->root); - right->ends(this->root); - left->scheduled(); - return right; - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Same as TaskNode but here each task completes its parent task directly. This -// stresses the completion system but strongly limits cache line contention -/////////////////////////////////////////////////////////////////////////////// - -/*! One node task per node in the tree. Task completes its parent */ -class TaskCascadeNode : public Task { -public: - INLINE TaskCascadeNode(Atomic &value_, uint32 lvl_, Task *root_=NULL) : - value(value_), lvl(lvl_) {} - virtual Task* run(void); - Atomic &value; - uint32 lvl; -}; - -Task *TaskCascadeNode::run(void) { - if (this->lvl == maxLevel) - this->value++; - else { - Task *left = GBE_NEW(TaskCascadeNode, this->value, this->lvl+1); - Task *right = GBE_NEW(TaskCascadeNode, this->value, this->lvl+1); - left->ends(this); - right->ends(this); - left->scheduled(); - right->scheduled(); - } - return NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -// Same as TaskCascadeNode but with continuation passing style tasks -/////////////////////////////////////////////////////////////////////////////// -class TaskCascadeNodeOpt : public Task { -public: - INLINE TaskCascadeNodeOpt(Atomic &value_, uint32 lvl_, Task *root_=NULL) : - value(value_), lvl(lvl_) {} - virtual Task* run(void); - Atomic &value; - uint32 lvl; -}; - -Task *TaskCascadeNodeOpt::run(void) { - if (this->lvl == maxLevel) { - this->value++; - return NULL; - } else { - Task *left = GBE_NEW(TaskCascadeNode, this->value, this->lvl+1); - Task *right = GBE_NEW(TaskCascadeNode, this->value, this->lvl+1); - left->ends(this); - right->ends(this); - left->scheduled(); - return right; - } -} - -/*! For all tree tests */ -template -START_UTEST(TestTree) - Atomic value(0u); - std::cout << "nodeNum = " << (2 << maxLevel) - 1 << std::endl; - double t = getSeconds(); - Task *done = GBE_NEW(TaskDone); - Task *root = GBE_NEW(NodeType, value, 0); - root->starts(done); - done->scheduled(); - root->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; - FATAL_IF(value != (1 << maxLevel), "TestTree failed"); -END_UTEST(TestTree) - -/////////////////////////////////////////////////////////////////////////////// -// We try to stress the internal allocator here -/////////////////////////////////////////////////////////////////////////////// -class TaskAllocate : public TaskSet { -public: - TaskAllocate(size_t elemNum) : TaskSet(elemNum) {} - virtual void run(size_t elemID); - enum { allocNum = 1 << 10 }; - enum { iterNum = 1 << 5 }; -}; - -void TaskAllocate::run(size_t elemID) { - Task *tasks[allocNum]; - for (int j = 0; j < iterNum; ++j) { - const int taskNum = rand() % allocNum; - for (int i = 0; i < taskNum; ++i) tasks[i] = GBE_NEW(TaskDummy); - for (int i = 0; i < taskNum; ++i) GBE_DELETE(tasks[i]); - } -} - -START_UTEST(TestAllocator) - Task *done = GBE_NEW(TaskDone); - Task *allocate = GBE_NEW(TaskAllocate, 1 << 10); - double t = getSeconds(); - allocate->starts(done); - done->scheduled(); - allocate->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; -END_UTEST(TestAllocator) - -/////////////////////////////////////////////////////////////////////////////// -// We are making the queue full to make the system recurse to empty it -/////////////////////////////////////////////////////////////////////////////// -class TaskFull : public Task { -public: - enum { taskToSpawn = 1u << 16u }; - TaskFull(const char *name, Atomic &counter, int lvl = 0) : - Task(name), counter(counter), lvl(lvl) {} - virtual Task* run(void) { - if (lvl == 0) - for (size_t i = 0; i < taskToSpawn; ++i) { - Task *task = GBE_NEW(TaskFull, "TaskFullLvl1", counter, 1); - task->ends(this); - task->scheduled(); - } - else - counter++; - return NULL; - } - Atomic &counter; - int lvl; -}; - -START_UTEST(TestFullQueue) - Atomic counter(0u); - double t = getSeconds(); - Task *done = GBE_NEW(TaskDone); - for (size_t i = 0; i < 64; ++i) { - Task *task = GBE_NEW(TaskFull, "TaskFull", counter); - task->starts(done); - task->scheduled(); - } - done->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; - FATAL_IF (counter != 64 * TaskFull::taskToSpawn, "TestFullQueue failed"); -END_UTEST(TestFullQueue) - -/////////////////////////////////////////////////////////////////////////////// -// We spawn a lot of affinity jobs to saturate the affinity queues -/////////////////////////////////////////////////////////////////////////////// -class TaskAffinity : public Task { -public: - enum { taskToSpawn = 2048u }; - TaskAffinity(Task *done, Atomic &counter, int lvl = 0) : - Task("TaskAffinity"), counter(counter), lvl(lvl) {} - virtual Task *run(void) { - if (lvl == 1) - counter++; - else { - const uint32 threadNum = TaskingSystemGetThreadNum(); - for (uint32 i = 0; i < taskToSpawn; ++i) { - Task *task = GBE_NEW(TaskAffinity, done.ptr, counter, 1); - task->setAffinity(i % threadNum); - task->ends(this); - task->scheduled(); - } - } - return NULL; - } - Atomic &counter; - Ref done; - int lvl; -}; - -START_UTEST(TestAffinity) - enum { batchNum = 512 }; - for (int i = 0; i < 8; ++i) { - Atomic counter(0u); - double t = getSeconds(); - Ref done = GBE_NEW(TaskDone); - for (size_t i = 0; i < batchNum; ++i) { - Task *task = GBE_NEW(TaskAffinity, done.ptr, counter); - task->starts(done.ptr); - task->scheduled(); - } - done->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; - std::cout << counter << std::endl; - FATAL_IF (counter != batchNum * TaskAffinity::taskToSpawn, "TestAffinity failed"); - } -END_UTEST(TestAffinity) - -/////////////////////////////////////////////////////////////////////////////// -// Exponential Fibonnaci to stress the task spawning and the completions -/////////////////////////////////////////////////////////////////////////////// -static Atomic fiboNum(0u); -class TaskFiboSpawn : public Task { -public: - TaskFiboSpawn(uint64 rank, uint64 *root = NULL) : - Task("TaskFiboSpawn"), rank(rank), root(root) {fiboNum++;} - virtual Task* run(void); - uint64 rank, sumLeft, sumRight; - uint64 *root; -}; - -class FiboSumTask : public Task { -public: - FiboSumTask(TaskFiboSpawn *fibo) : Task("FiboSumTask"), fibo(fibo) {} - virtual Task* run(void); - TaskFiboSpawn *fibo; -}; - -Task *TaskFiboSpawn::run(void) { - if (rank > 1) { - TaskFiboSpawn *left = GBE_NEW(TaskFiboSpawn, rank-1, &this->sumLeft); - TaskFiboSpawn *right = GBE_NEW(TaskFiboSpawn, rank-2, &this->sumRight); - FiboSumTask *sum = GBE_NEW(FiboSumTask, this); - left->starts(sum); - right->starts(sum); - sum->ends(this); - sum->scheduled(); - left->scheduled(); - return right; - } else if (rank == 1) { - if (root) *root = 1; - return NULL; - } else { - if (root) *root = 0; - return NULL; - } -} - -Task *FiboSumTask::run(void) { - assert(fibo); - if (fibo->root) *fibo->root = fibo->sumLeft + fibo->sumRight; - return NULL; -} - -static uint64 fiboLinear(uint64 rank) -{ - uint64 rn0 = 0, rn1 = 1; - if (rank == 0) return rn0; - if (rank == 1) return rn1; - for (uint64 i = 2; i <= rank; ++i) { - uint64 sum = rn0 + rn1; - rn0 = rn1; - rn1 = sum; - } - return rn1; -} - -START_UTEST(TestFibo) -{ - const uint64 rank = rand() % 32; - uint64 sum; - double t = getSeconds(); - fiboNum = 0u; - Ref fibo = GBE_NEW(TaskFiboSpawn, rank, &sum); - Task *done = GBE_NEW(TaskDone); - fibo->starts(done); - fibo->scheduled(); - done->scheduled(); - TaskingSystemEnter(); - t = getSeconds() - t; - std::cout << t * 1000. << " ms" << std::endl; - std::cout << "Fibonacci Task Num: "<< fiboNum << std::endl; - FATAL_IF (sum != fiboLinear(rank), "TestFibonacci failed"); -} -END_UTEST(TestFibo) - -/////////////////////////////////////////////////////////////////////////////// -// Task with multiple dependencies -/////////////////////////////////////////////////////////////////////////////// -class TaskMultiTrigger : public Task, - public MultiDependencyPolicy -{ -public: - TaskMultiTrigger(int32 *valueToSet) : valueToSet(valueToSet) {} - virtual Task *run(void) { *valueToSet = 1; return NULL; } -private: - int32 *valueToSet; -}; - -class TaskTriggered : public Task -{ -public: - TaskTriggered(const int32 *valueToRead, Atomic32 &dst) : - valueToRead(valueToRead), dst(dst) {} - virtual Task *run(void) { dst += *valueToRead; return NULL; } -private: - const int32 *valueToRead; - Atomic32 &dst; -}; - -START_UTEST(TestMultiDependency) -{ - static const uint32 multiTaskToSpawn = 512; - static const uint32 triggeredTaskToSpawn = 512; - static const uint32 valueToSetNum = multiTaskToSpawn; - - int32 *toSet = GBE_NEW_ARRAY(int32, valueToSetNum); - Atomic32 dst(0); - Task *doneTask = GBE_NEW(TaskDone); - for (uint32 i = 0; i < valueToSetNum; ++i) toSet[i] = 0; - for (uint32 i = 0; i < multiTaskToSpawn; ++i) { - Ref task = GBE_NEW(TaskMultiTrigger, toSet + i); - for (uint32 j = 0; j < triggeredTaskToSpawn; ++j) { - Ref triggered = GBE_NEW(TaskTriggered, toSet + i, dst); - Ref dummy = GBE_NEW(TaskDummy); - task->multiStarts(dummy); - dummy->starts(triggered); - triggered->starts(doneTask); - triggered->scheduled(); - dummy->scheduled(); - } - task->scheduled(); - } - doneTask->scheduled(); - TaskingSystemEnter(); - GBE_DELETE_ARRAY(toSet); - const uint32 result = dst; - std::cout << "result: " << result << std::endl; - FATAL_IF(result != multiTaskToSpawn * triggeredTaskToSpawn, - "MultiDependency failed"); -} -END_UTEST(TestMultiDependency) - -START_UTEST(TestMultiDependencyTwoStage) -{ - static const uint32 multiTaskToSpawn = 512; - static const uint32 triggeredTaskToSpawn = 512; - static const uint32 valueToSetNum = multiTaskToSpawn; - - int32 *toSet = GBE_NEW_ARRAY(int32, valueToSetNum); - Atomic32 dst(0); - Task *doneTask = GBE_NEW(TaskDone); - for (uint32 i = 0; i < valueToSetNum; ++i) toSet[i] = 0; - for (uint32 i = 0; i < multiTaskToSpawn; ++i) { - Ref task = GBE_NEW(TaskMultiTrigger, toSet + i); - for (uint32 j = 0; j < triggeredTaskToSpawn; ++j) { - Ref triggered = GBE_NEW(TaskTriggered, toSet + i, dst); - task->multiStarts(triggered); - triggered->starts(doneTask); - triggered->scheduled(); - } - task->scheduled(); - } - doneTask->scheduled(); - TaskingSystemEnter(); - GBE_DELETE_ARRAY(toSet); - const uint32 result = dst; - std::cout << "result: " << result << std::endl; - FATAL_IF(result != multiTaskToSpawn * triggeredTaskToSpawn, - "MultiDependency failed"); -} -END_UTEST(TestMultiDependencyTwoStage) - -START_UTEST(TestMultiDependencyRandomStart) -{ - static const uint32 multiTaskToSpawn = 512; - static const uint32 triggeredTaskToSpawn = 512; - static const uint32 valueToSetNum = multiTaskToSpawn; - static const uint32 repeatNum = 8; - Random rand; - for (uint32 i = 0; i < repeatNum; ++i) { - int32 *toSet = GBE_NEW_ARRAY(int32, valueToSetNum); - Atomic32 dst(0); - Ref doneTask = GBE_NEW(TaskDone); - for (uint32 i = 0; i < valueToSetNum; ++i) toSet[i] = 0; - for (uint32 i = 0; i < multiTaskToSpawn; ++i) { - Ref task = GBE_NEW(TaskMultiTrigger, toSet + i); - bool isScheduled = false; - for (uint32 j = 0; j < triggeredTaskToSpawn; ++j) { - Ref triggered = GBE_NEW(TaskTriggered, toSet + i, dst); - task->multiStarts(triggered); - triggered->starts(doneTask); - triggered->scheduled(); - if (rand.getFloat() < 0.8 && isScheduled == false) { - task->scheduled(); - isScheduled = true; - } - } - if (isScheduled == false) task->scheduled(); - } - doneTask->scheduled(); - TaskingSystemEnter(); - GBE_DELETE_ARRAY(toSet); - const uint32 result = dst; - std::cout << "result: " << result << std::endl; - FATAL_IF(result != multiTaskToSpawn * triggeredTaskToSpawn, - "MultiDependencyRandomStart failed"); - } -} -END_UTEST(TestMultiDependencyRandomStart) - -/////////////////////////////////////////////////////////////////////////////// -// Test tasking lock and unlock -/////////////////////////////////////////////////////////////////////////////// -class TaskLockUnlock : public Task -{ -public: - TaskLockUnlock(int32 *shared) : shared(shared) {} - virtual Task *run(void) { - TaskingSystemLock(); - *shared = *shared + 1; - TaskingSystemUnlock(); - return NULL; - } - int32 *shared; -}; - -START_UTEST(TestLockUnlock) -{ - static const uint32 taskNum = 1024; - int32 shared = 0; - Ref doneTask = GBE_NEW(TaskDone); - for (uint32 i = 0; i < taskNum; ++i) { - Task *updateTask = GBE_NEW(TaskLockUnlock, &shared); - updateTask->starts(doneTask); - updateTask->scheduled(); - } - doneTask->scheduled(); - TaskingSystemEnter(); - FATAL_IF(shared != int32(taskNum), "TestLockUnlock failed"); -} -END_UTEST(TestLockUnlock) - -/////////////////////////////////////////////////////////////////////////////// -// Test tasking profiler -/////////////////////////////////////////////////////////////////////////////// -#if GBE_TASK_PROFILER -class UTestProfiler : public TaskProfiler -{ -public: - UTestProfiler(void) : - sleepNum(0), wakeUpNum(0), - lockNum(0), unlockNum(0), - runStartNum(0), runEndNum(0), endNum(0) {} - virtual void onSleep(uint32 threadID) {sleepNum++;} - virtual void onWakeUp(uint32 threadID) {wakeUpNum++;} - virtual void onLock(uint32 threadID) {lockNum++;} - virtual void onUnlock(uint32 threadID) {unlockNum++;} - virtual void onRunStart(const char *taskName, uint32 threadID) {runStartNum++;} - virtual void onRunEnd(const char *taskName, uint32 threadID) {runEndNum++;} - virtual void onEnd(const char *taskName, uint32 threadID) {endNum++;} - Atomic sleepNum; - Atomic wakeUpNum; - Atomic lockNum; - Atomic unlockNum; - Atomic runStartNum; - Atomic runEndNum; - Atomic endNum; -}; - -START_UTEST(TestProfiler) -{ - UTestProfiler *profiler = GBE_NEW(UTestProfiler); - TaskingSystemSetProfiler(profiler); - TestFibo(); - TestTaskSet(); - TestMultiDependency(); - TestLockUnlock(); -#define OUTPUT_FIELD(FIELD) \ - std::cout << #FIELD ": " << profiler->FIELD << std::endl - OUTPUT_FIELD(sleepNum); - OUTPUT_FIELD(wakeUpNum); - OUTPUT_FIELD(lockNum); - OUTPUT_FIELD(unlockNum); - OUTPUT_FIELD(runStartNum); - OUTPUT_FIELD(runEndNum); - OUTPUT_FIELD(endNum); -#undef OUTPUT_FIELD - TaskingSystemSetProfiler(NULL); - GBE_DELETE(profiler); -} -END_UTEST(TestProfiler) -#endif /* GBE_TASK_PROFILER */ - -/*! Run all tasking tests */ -void utest_tasking(void) -{ - TestDummy(); - TestTree(); - TestTree(); - TestTree(); - TestTree(); - TestTaskSet(); - TestAllocator(); - TestFullQueue(); - TestAffinity(); - TestFibo(); - TestMultiDependency(); - TestMultiDependencyTwoStage(); - TestMultiDependencyRandomStart(); - TestLockUnlock(); - TestProfiler(); -} - -UTEST_REGISTER(utest_tasking);