Ejemplo n.º 1
0
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;
    
}
Ejemplo n.º 3
0
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); 
    }
}
Ejemplo n.º 4
0
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;
    
}
Ejemplo n.º 5
0
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;
}