void *rk4_kernel( void *args ) { kernel_args arguments = *( (kernel_args *) args ); vector k1, k2, k3, k4, initial, direction; vector *points_aux = NULL; size_t n_points_aux = 0, j = 0; set( &initial, arguments.v0[arguments.id] ); set( &direction, arguments.field[DataSet::offset( arguments.n_x, arguments.n_y, initial.x, initial.y, initial.z )] ); points_aux = (vector *) malloc( arguments.max_points * sizeof(vector) ); while ( module( direction ) > 0 && n_points_aux < arguments.max_points ) { n_points_aux++; set( &(points_aux[n_points_aux - 1]), initial); set( &k1, mult_scalar( direction, arguments.h ) ); set( &k2, mult_scalar( trilinear_interpolation( sum( initial, mult_scalar( k1, 0.5 ) ), arguments.n_x, arguments.n_y, arguments.n_z, arguments.field ), arguments.h ) ); set( &k3, mult_scalar( trilinear_interpolation( sum( initial, mult_scalar( k2, 0.5 ) ), arguments.n_x, arguments.n_y, arguments.n_z, arguments.field ), arguments.h ) ); set( &k4, mult_scalar( trilinear_interpolation( sum( initial, k3 ), arguments.n_x, arguments.n_y, arguments.n_z, arguments.field ), arguments.h ) ); set( &initial, sum( initial, sum( mult_scalar( k1 , 0.166666667 ), sum( mult_scalar( k2, 0.333333333 ), sum( mult_scalar( k3, 0.333333333 ), mult_scalar( k4, 0.166666667 ) ) ) ) ) ); set( &direction, trilinear_interpolation( initial, arguments.n_x, arguments.n_y, arguments.n_z, arguments.field ) ); } (arguments.fibers)[arguments.id] = Fiber( n_points_aux ); for ( j = 0; j < n_points_aux; j++ ) { (arguments.fibers)[arguments.id].setPoint( j, points_aux[j] ); } free( points_aux ); return NULL; }
void AdaptiveWaterline::adaptive_sampling_run() { minx = surf->bb.minpt.x - 2*cutter->getRadius(); maxx = surf->bb.maxpt.x + 2*cutter->getRadius(); miny = surf->bb.minpt.y - 2*cutter->getRadius(); maxy = surf->bb.maxpt.y + 2*cutter->getRadius(); Line* line = new Line( Point(minx,miny,zh) , Point(maxx,maxy,zh) ); Span* linespan = new LineSpan(*line); xfibers.clear(); Point xstart_p1 = Point( minx, linespan->getPoint(0.0).y, zh ); Point xstart_p2 = Point( maxx, linespan->getPoint(0.0).y, zh ); Point xstop_p1 = Point( minx, linespan->getPoint(1.0).y, zh ); Point xstop_p2 = Point( maxx, linespan->getPoint(1.0).y, zh ); Fiber xstart_f = Fiber( xstart_p1, xstart_p2 ) ; Fiber xstop_f = Fiber( xstop_p1, xstop_p2 ); subOp[0]->run(xstart_f); subOp[0]->run(xstop_f); xfibers.push_back(xstart_f); std::cout << " XFiber adaptive sample \n"; xfiber_adaptive_sample( linespan, 0.0, 1.0, xstart_f, xstop_f); yfibers.clear(); Point ystart_p1 = Point( linespan->getPoint(0.0).x, miny, zh ); Point ystart_p2 = Point( linespan->getPoint(0.0).x, maxy, zh ); Point ystop_p1 = Point( linespan->getPoint(1.0).x, miny, zh ); Point ystop_p2 = Point( linespan->getPoint(1.0).x, maxy, zh ); Fiber ystart_f = Fiber( ystart_p1, ystart_p2 ) ; Fiber ystop_f = Fiber( ystop_p1, ystop_p2 ); subOp[1]->run(ystart_f); subOp[1]->run(ystop_f); yfibers.push_back(ystart_f); std::cout << " YFiber adaptive sample \n"; yfiber_adaptive_sample( linespan, 0.0, 1.0, ystart_f, ystop_f); delete line; delete linespan; }
void AdaptiveWaterline::yfiber_adaptive_sample(const Span* span, double start_t, double stop_t, Fiber start_f, Fiber stop_f) { const double mid_t = start_t + (stop_t-start_t)/2.0; // mid point sample assert( mid_t > start_t ); assert( mid_t < stop_t ); //std::cout << "yfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; Point mid_p1 = Point( span->getPoint( mid_t ).x, miny, zh ); Point mid_p2 = Point( span->getPoint( mid_t ).x, maxy, zh ); Fiber mid_f = Fiber( mid_p1, mid_p2 ); subOp[1]->run( mid_f ); double fw_step = fabs( start_f.p1.x - stop_f.p1.x ) ; if ( fw_step > sampling ) { // above minimum step-forward, need to sample more yfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); yfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); } else if ( !flat(start_f,mid_f,stop_f) ) { if (fw_step > min_sampling) { // not a flat segment, and we have not reached maximum sampling yfiber_adaptive_sample( span, start_t, mid_t , start_f, mid_f ); yfiber_adaptive_sample( span, mid_t , stop_t, mid_f , stop_f ); } } else { yfibers.push_back(stop_f); } }
void AdaptiveWaterline::adaptive_sampling_run() { minx = surf->bb.minpt.x - 2*cutter->getRadius(); maxx = surf->bb.maxpt.x + 2*cutter->getRadius(); miny = surf->bb.minpt.y - 2*cutter->getRadius(); maxy = surf->bb.maxpt.y + 2*cutter->getRadius(); Line* line = new Line( Point(minx,miny,zh) , Point(maxx,maxy,zh) ); Span* linespan = new LineSpan(*line); #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP #pragma omp parallel sections { #pragma omp section // Replace OMP Task by Parallel sections { // first child #else #pragma omp parallel { #pragma omp single nowait { // initial root task #pragma omp task { // first child task #endif // _WIN32 xfibers.clear(); Point xstart_p1 = Point(minx, linespan->getPoint(0.0).y, zh); Point xstart_p2 = Point(maxx, linespan->getPoint(0.0).y, zh); Point xstop_p1 = Point(minx, linespan->getPoint(1.0).y, zh); Point xstop_p2 = Point(maxx, linespan->getPoint(1.0).y, zh); Fiber xstart_f = Fiber(xstart_p1, xstart_p2); Fiber xstop_f = Fiber(xstop_p1, xstop_p2); subOp[0]->run(xstart_f); subOp[0]->run(xstop_f); xfibers.push_back(xstart_f); std::cout << " XFiber adaptive sample \n"; xfiber_adaptive_sample(linespan, 0.0, 1.0, xstart_f, xstop_f); #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP } #pragma omp section { // second child #else } # pragma omp task { // second child task #endif // _WIN32 yfibers.clear(); Point ystart_p1 = Point(linespan->getPoint(0.0).x, miny, zh); Point ystart_p2 = Point(linespan->getPoint(0.0).x, maxy, zh); Point ystop_p1 = Point(linespan->getPoint(1.0).x, miny, zh); Point ystop_p2 = Point(linespan->getPoint(1.0).x, maxy, zh); Fiber ystart_f = Fiber(ystart_p1, ystart_p2); Fiber ystop_f = Fiber(ystop_p1, ystop_p2); subOp[1]->run(ystart_f); subOp[1]->run(ystop_f); yfibers.push_back(ystart_f); std::cout << " YFiber adaptive sample \n"; yfiber_adaptive_sample(linespan, 0.0, 1.0, ystart_f, ystop_f); #ifdef _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP } } // end omp parallel #else } } } // end omp parallel #endif // _WIN32 delete line; delete linespan; }
void TaskScheduler::Run(uint fiberPoolSize, TaskFunction mainTask, void *mainTaskArg) { // Create and populate the fiber pool m_fiberPoolSize = fiberPoolSize; m_fibers = new Fiber[fiberPoolSize]; m_freeFibers = new std::atomic<bool>[fiberPoolSize]; m_waitingFibers = new std::atomic<bool>[fiberPoolSize]; for (uint i = 0; i < fiberPoolSize; ++i) { m_fibers[i] = std::move(Fiber(512000, FiberStart, reinterpret_cast<std::intptr_t>(this))); m_freeFibers[i].store(true, std::memory_order_release); m_waitingFibers[i].store(false, std::memory_order_release); } m_waitingBundles.resize(fiberPoolSize); // 1 thread for each logical processor m_numThreads = FTLGetNumHardwareThreads(); // Initialize all the things m_quit.store(false, std::memory_order_release); m_threads.resize(m_numThreads); m_tls.resize(m_numThreads); // Set the properties for the current thread FTLSetCurrentThreadAffinity(1); m_threads[0] = FTLGetCurrentThread(); // Create the remaining threads for (uint i = 1; i < m_numThreads; ++i) { ThreadStartArgs *threadArgs = new ThreadStartArgs(); threadArgs->taskScheduler = this; threadArgs->threadIndex = i; if (!FTLCreateThread(524288, ThreadStart, threadArgs, i, &m_threads[i])) { printf("Error: Failed to create all the worker threads"); return; } } // Start the main task // Get a free fiber std::size_t freeFiberIndex = GetNextFreeFiberIndex(); Fiber *freeFiber = &m_fibers[freeFiberIndex]; // Repurpose it as the main task fiber and switch to it MainFiberStartArgs mainFiberArgs; mainFiberArgs.taskScheduler = this; mainFiberArgs.MainTask = mainTask; mainFiberArgs.Arg = mainTaskArg; freeFiber->Reset(MainFiberStart, reinterpret_cast<std::intptr_t>(&mainFiberArgs)); m_tls[0].CurrentFiberIndex = freeFiberIndex; m_tls[0].ThreadFiber.SwitchToFiber(freeFiber); // And we're back // Wait for the worker threads to finish for (std::size_t i = 1; i < m_numThreads; ++i) { FTLJoinThread(m_threads[i]); } return; }