Exemple #1
0
void TCPSendRawNode::inputsUpdated( qint64 pTimeStamp )
{
	if( mPinHost->isUpdated( pTimeStamp ) || mPinPort->isUpdated( pTimeStamp ) )
	{
		if( mSocket.state() == QAbstractSocket::ConnectedState )
		{
			mSocket.disconnectFromHost();
		}

		if( mSocket.state() != QAbstractSocket::UnconnectedState )
		{
			return;
		}

		mNode->setStatus( fugio::NodeInterface::Initialising );
		mNode->setStatusMessage( "Connecting" );

		mSocket.connectToHost( variant( mPinHost ).toString(), variant( mPinPort ).toInt() );

		return;
	}

	if( mSocket.state() != QAbstractSocket::ConnectedState )
	{
		return;
	}

	fugio::Performance	Perf( mNode, "inputsUpdated", pTimeStamp );

	sendData( pTimeStamp );
}
void TCPReceiveRawNode::frameStart( qint64 pTimeStamp )
{
	if( !mStream )
	{
		return;
	}

	QTcpSocket		*S = qobject_cast<QTcpSocket *>( mStream->device() );

	if( !S->isOpen() )
	{
		delete mStream;
		delete S;

		mStream = nullptr;

		return;
	}

	if( !S->bytesAvailable() )
	{
		return;
	}

	fugio::Performance	Perf( mNode, "frameStart", pTimeStamp );

	mValOutputBuffer->setVariant( S->readAll() );

	pinUpdated( mPinOutputBuffer );
}
void ImagePreviewNode::inputsUpdated( qint64 pTimeStamp )
{
	fugio::Performance	Perf( mNode, "inputsUpdated", pTimeStamp );

	NodeControlBase::inputsUpdated( pTimeStamp );

	if( mPinImage->isConnectedToActiveNode() && mPinImage->isUpdated( pTimeStamp ) )
	{
		fugio::ImageInterface		*SrcImg = input<fugio::ImageInterface *>( mPinImage );

		if( SrcImg && !SrcImg->size().isEmpty() )
		{
			mGUI->setPixmap( QPixmap::fromImage( SrcImg->image() ).scaled( 512, 512, Qt::KeepAspectRatio ) );
		}
	}
}
Exemple #4
0
void OculusRiftNode::render( qint64 pTimeStamp, QUuid pSourcePinId )
{
	Q_UNUSED( pSourcePinId )

#if !defined( OCULUS_PLUGIN_SUPPORTED )
	Q_UNUSED( pTimeStamp )
#else
	fugio::Performance	Perf( mNode, "drawGeometry", pTimeStamp );

	if( !mNode->isInitialised() )
	{
		return;
	}

	if( !mOculusRift->hmd() )
	{
		return;
	}

	// We need to keep a reference to ourselves here as ovr_SubmitFrame can
	// call the main app event loop, which can close the context and delete us!

	QSharedPointer<fugio::NodeControlInterface>	C = mNode->control();

	mOculusRift->drawStart();

	const float		NearPlane = variant( mPinNearPlane ).toFloat();
	const float		FarPlane  = variant( mPinFarPlane ).toFloat();

	//	float Yaw(3.141592f);
	//	Vector3f Pos2(0.0f,1.6f,-5.0f);
	//	Pos2.y = ovrHmd_GetFloat(mHMD, OVR_KEY_EYE_HEIGHT, Pos2.y);

	QMatrix4x4		MatEye = variant( mPinViewMatrix ).value<QMatrix4x4>();
	QVector3D		TrnEye = MatEye.column( 3 ).toVector3D();

	MatEye.setColumn( 3, QVector4D( 0, 0, 0, 1 ) );

	const Vector3f Pos2( TrnEye.x(), TrnEye.y(), TrnEye.z() );

	Matrix4f tempRollPitchYaw;

	memcpy( tempRollPitchYaw.M, MatEye.constData(), sizeof( float ) * 16 );

	const Matrix4f rollPitchYaw = tempRollPitchYaw;

	// Render Scene to Eye Buffers
	for (int eye = 0; eye < 2; eye++)
	{
		mOculusRift->drawEyeStart( eye );

		// Get view and projection matrices
		//Matrix4f rollPitchYaw = Matrix4f( MatEye.transposed().data() );
		Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f( mOculusRift->eyeRenderPos( eye ).Orientation);
		Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0, 1, 0));
		Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0, 0, -1));
		Vector3f shiftedEyePos = Pos2 + rollPitchYaw.Transform( mOculusRift->eyeRenderPos( eye ).Position );

		Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + finalForward, finalUp);
		Matrix4f proj = ovrMatrix4f_Projection( mOculusRift->defaultEyeFOV( eye ), NearPlane, FarPlane, ovrProjection_None );

		mProjection->setVariant( QMatrix4x4( &proj.M[ 0 ][ 0 ], 4, 4 ).transposed() );

		mView->setVariant( QMatrix4x4( &view.M[ 0 ][ 0 ], 4, 4 ).transposed() );

		fugio::OpenGLStateInterface		*CurrentState = 0;

		for( QSharedPointer<fugio::PinInterface> P : mNode->enumInputPins() )
		{
			if( !P->isConnected() )
			{
				continue;
			}

			if( P->connectedPin().isNull() )
			{
				continue;
			}

			if( P->connectedPin()->control().isNull() )
			{
				continue;
			}

			QObject					*O = P->connectedPin()->control()->qobject();

			if( !O )
			{
				continue;
			}

			if( true )
			{
				fugio::RenderInterface		*Geometry = qobject_cast<fugio::RenderInterface *>( O );

				if( Geometry )
				{
					Geometry->render( pTimeStamp );

					continue;
				}
			}

			if( true )
			{
				fugio::OpenGLStateInterface		*NextState = qobject_cast<fugio::OpenGLStateInterface *>( O );

				if( NextState != 0 )
				{
					if( CurrentState != 0 )
					{
						CurrentState->stateEnd();
					}

					CurrentState = NextState;

					CurrentState->stateBegin();

					continue;
				}
			}
		}

		if( CurrentState != 0 )
		{
			CurrentState->stateEnd();
		}

		mOculusRift->drawEyeEnd( eye );
	}

	mOculusRift->drawEnd();

	pinUpdated( mPinProjection );
	pinUpdated( mPinView );
#endif
}
Exemple #5
0
void ShaderNode::drawGeometry()
{
	fugio::Performance	Perf( mNode, "drawGeometry" );

	if( !mInitialised )
	{
		return;
	}

	if( !mProgramLinked )
	{
		return;
	}

	QList< QSharedPointer<InterfacePin> >	InpPinLst = mNode->enumInputPins();

	//-------------------------------------------------------------------------

	glUseProgram( mProgramId );

	OPENGL_PLUGIN_DEBUG;

	QList<ShaderBindData>		Bindings;

	bindInputTextures( Bindings );

	bindAttributes();

	//-------------------------------------------------------------------------

	InterfaceOpenGLState		*CurrentState = 0;
	InterfaceOpenGLState		*NextState;
	InterfaceGeometry			*Geometry;

	//-------------------------------------------------------------------------

	for( QList< QSharedPointer<InterfacePin> >::iterator it = InpPinLst.begin() ; it != InpPinLst.end() ; it++ )
	{
		QSharedPointer<InterfacePin>	InpPin = *it;

		if( !InpPin->isConnectedToActiveNode() )
		{
			continue;
		}

		QSharedPointer<InterfacePinControl>		 PinCtl = InpPin->connectedPin()->control();

		if( PinCtl.isNull() )
		{
			continue;
		}

		if( ( Geometry = qobject_cast<InterfaceGeometry *>( PinCtl->object() ) ) != 0 )
		{
			Geometry->drawGeometry();

			continue;
		}

		if( ( NextState = qobject_cast<InterfaceOpenGLState *>( PinCtl->object() ) ) != 0 )
		{
			if( CurrentState != 0 )
			{
				CurrentState->stateEnd();
			}

			CurrentState = NextState;

			CurrentState->stateBegin();
		}
	}

	if( CurrentState != 0 )
	{
		CurrentState->stateEnd();
	}

	releaseAttributes();

	//-------------------------------------------------------------------------

	glUseProgram( 0 );

	//-------------------------------------------------------------------------

	releaseInputTextures( Bindings );

	OPENGL_PLUGIN_DEBUG;
}
Exemple #6
0
void ShaderNode::inputsUpdated( qint64 pTimeStamp )
{
	fugio::Performance	Perf( mNode, "inputsUpdated" );

	if( !mInitialised )
	{
		return;
	}

	OPENGL_PLUGIN_DEBUG;

	if( mPinShaderVertex->isUpdated( mLastShaderLoad ) || mPinShaderGeometry->isUpdated( mLastShaderLoad ) || mPinShaderFragment->isUpdated( mLastShaderLoad ) )
	{
		loadShader();

		mLastShaderLoad = pTimeStamp;
	}

	OPENGL_PLUGIN_DEBUG;

	if( !mProgramLinked )
	{
		return;
	}

	//-------------------------------------------------------------------------

	int		W, H, D;

	QList< QSharedPointer<InterfacePin> >	OutPinLst = mNode->enumOutputPins();
	QList< QSharedPointer<InterfacePin> >	InpPinLst = mNode->enumInputPins();

	//-------------------------------------------------------------------------

	glUseProgram( mProgramId );

	OPENGL_PLUGIN_DEBUG;

	QList<ShaderBindData>		Bindings;

	updateUniforms( Bindings, pTimeStamp );

	if( mPinOutputGeometry->isConnectedToActiveNode() )
	{
		mNode->context()->pinUpdated( mPinOutputGeometry );
	}

	if( activeBufferCount( OutPinLst ) == 0 )
	{
		glUseProgram( 0 );

		return;
	}

	//-------------------------------------------------------------------------
	// Bind all output buffers

	QVector<GLenum>		Buffers;

	bindOutputBuffers( Buffers, OutPinLst, W, H, D );

	if( mFrameBufferId != 0 )
	{
		glBindFramebuffer( GL_FRAMEBUFFER, mFrameBufferId );

		if( !Buffers.empty() )
		{
			glDrawBuffers( Buffers.size(), Buffers.data() );

			OPENGL_PLUGIN_DEBUG;
		}

		if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
		{
			qDebug() << "glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE";
		}
	}

	//-------------------------------------------------------------------------

	InterfaceOpenGLState		*State = 0;

	if( mPinState->isConnected() )
	{
		State = qobject_cast<InterfaceOpenGLState *>( mPinState->connectedPin()->control()->object() );
	}

	if( State != 0 )
	{
		State->stateBegin();
	}

	//-------------------------------------------------------------------------

	if( true )
	{
		glViewport( 0, 0, W, H );

		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		QList<InterfaceGeometry*>		GeometryList;

		for( QList< QSharedPointer<InterfacePin> >::iterator it = InpPinLst.begin() ; it != InpPinLst.end() ; it++ )
		{
			QSharedPointer<InterfacePin>	InpPin = *it;

			if( !InpPin->isConnectedToActiveNode() )
			{
				continue;
			}

			QSharedPointer<InterfacePinControl>		 GeometryControl = InpPin->connectedPin()->control();

			InterfaceGeometry		*Geometry = ( GeometryControl.isNull() ? 0 : qobject_cast<InterfaceGeometry *>( GeometryControl->object() ) );

			if( Geometry != 0 )
			{
				GeometryList.append( Geometry );
			}
		}

		if( GeometryList.isEmpty() )
		{
			QMatrix4x4		pmvMatrix;

			pmvMatrix.setToIdentity();

			pmvMatrix.ortho( QRect( QPoint( 0, 0 ), QSize( W, H ) ) );

			glMatrixMode( GL_PROJECTION );
			glLoadIdentity();

			glLoadMatrixf( pmvMatrix.constData() );

			//Initialize Modelview Matrix
			glMatrixMode( GL_MODELVIEW );
			glLoadIdentity();

			glColor4f( 1.0, 1.0, 1.0, 1.0 );

			//glEnable( GL_BLEND );

			//glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

			//glActiveTexture( GL_TEXTURE0 );

			OPENGL_PLUGIN_DEBUG;

			GLint		x0 = 0;
			GLint		x1 = W;
			GLint		y0 = 0;
			GLint		y1 = H;

			glBegin( GL_QUADS );
				glMultiTexCoord2i( GL_TEXTURE0, x0, y1 );	glMultiTexCoord2f( GL_TEXTURE1, 0, 1 );		glVertex2i( x0, y0 );
				glMultiTexCoord2i( GL_TEXTURE0, x1, y1 );	glMultiTexCoord2f( GL_TEXTURE1, 1, 1 );		glVertex2i( x1, y0 );
				glMultiTexCoord2i( GL_TEXTURE0, x1, y0 );	glMultiTexCoord2f( GL_TEXTURE1, 1, 0 );		glVertex2i( x1, y1 );
				glMultiTexCoord2i( GL_TEXTURE0, x0, y0 );	glMultiTexCoord2f( GL_TEXTURE1, 0, 0 );		glVertex2i( x0, y1 );
			glEnd();
		}
		else
		{
			glMatrixMode( GL_PROJECTION );
			glLoadIdentity();

			//Initialize Modelview Matrix
			glMatrixMode( GL_MODELVIEW );
			glLoadIdentity();

			glColor4f( 1.0, 1.0, 1.0, 1.0 );

			//glEnable( GL_BLEND );

			//glBlendFunc( GL_ONE, GL_ONE );

			//glActiveTexture( GL_TEXTURE0 );

			OPENGL_PLUGIN_DEBUG;

			//glTranslatef( 0.0f, 0.0f, -5.0f );

			foreach( InterfaceGeometry *Geometry, GeometryList )
			{
				Geometry->drawGeometry();
			}
		}

		OPENGL_PLUGIN_DEBUG;
	}
Exemple #7
0
Perf fenl(
  MPI_Comm comm ,
  const int use_print ,
  const int use_trials ,
  const int use_atomic ,
  const int use_elems[] )
{
  typedef Kokkos::Example::BoxElemFixture< Space , ElemOrder > FixtureType ;

  typedef Kokkos::Example::CrsMatrix< double , Space >
    SparseMatrixType ;

  typedef typename SparseMatrixType::StaticCrsGraphType
    SparseGraphType ;

  typedef Kokkos::Example::FENL::NodeNodeGraph< typename FixtureType::elem_node_type , SparseGraphType , FixtureType::ElemNode >
     NodeNodeGraphType ;

  typedef Kokkos::Example::FENL::ElementComputation< FixtureType , SparseMatrixType >
    ElementComputationType ;

  typedef Kokkos::Example::FENL::DirichletComputation< FixtureType , SparseMatrixType >
    DirichletComputationType ;

  typedef NodeElemGatherFill< ElementComputationType >
    NodeElemGatherFillType ;

  typedef typename ElementComputationType::vector_type VectorType ;

  typedef Kokkos::Example::VectorImport<
     typename FixtureType::comm_list_type ,
     typename FixtureType::send_nodeid_type ,
     VectorType > ImportType ;

  //------------------------------------

  const unsigned newton_iteration_limit     = 10 ;
  const double   newton_iteration_tolerance = 1e-7 ;
  const unsigned cg_iteration_limit         = 200 ;
  const double   cg_iteration_tolerance     = 1e-7 ;

  //------------------------------------

  const int print_flag = use_print && std::is_same< Kokkos::HostSpace , typename Space::memory_space >::value ;

  int comm_rank ;
  int comm_size ;

  MPI_Comm_rank( comm , & comm_rank );
  MPI_Comm_size( comm , & comm_size );

  // Decompose by node to avoid mpi-communication for assembly

  const float bubble_x = 1.0 ;
  const float bubble_y = 1.0 ;
  const float bubble_z = 1.0 ;

  const FixtureType fixture( BoxElemPart::DecomposeNode , comm_size , comm_rank ,
                             use_elems[0] , use_elems[1] , use_elems[2] ,
                             bubble_x , bubble_y , bubble_z );


  {
    int global_error = ! fixture.ok();

#if defined( KOKKOS_ENABLE_MPI )
    int local_error = global_error ;
    global_error = 0 ;
    MPI_Allreduce( & local_error , & global_error , 1 , MPI_INT , MPI_SUM , comm );
#endif

    if ( global_error ) {
      throw std::runtime_error(std::string("Error generating finite element fixture"));
    }
  }

  //------------------------------------

  const ImportType comm_nodal_import(
    comm ,
    fixture.recv_node() ,
    fixture.send_node() ,
    fixture.send_nodeid() ,
    fixture.node_count_owned() ,
    fixture.node_count() - fixture.node_count_owned() );

  //------------------------------------

  const double bc_lower_value = 1 ;
  const double bc_upper_value = 2 ;

  const Kokkos::Example::FENL::ManufacturedSolution
    manufactured_solution( 0 , 1 , bc_lower_value , bc_upper_value  );

  //------------------------------------

  for ( int k = 0 ; k < comm_size && use_print ; ++k ) {
    if ( k == comm_rank ) {
      typename FixtureType::node_grid_type::HostMirror
        h_node_grid = Kokkos::create_mirror_view( fixture.node_grid() );

      typename FixtureType::node_coord_type::HostMirror
        h_node_coord = Kokkos::create_mirror_view( fixture.node_coord() );

      typename FixtureType::elem_node_type::HostMirror
        h_elem_node = Kokkos::create_mirror_view( fixture.elem_node() );

      Kokkos::deep_copy( h_node_grid , fixture.node_grid() );
      Kokkos::deep_copy( h_node_coord , fixture.node_coord() );
      Kokkos::deep_copy( h_elem_node , fixture.elem_node() );

      std::cout << "MPI[" << comm_rank << "]" << std::endl ;
      std::cout << "Node grid {" ;
      for ( unsigned inode = 0 ; inode < fixture.node_count() ; ++inode ) {
        std::cout << " (" << h_node_grid(inode,0)
                  << "," << h_node_grid(inode,1)
                  << "," << h_node_grid(inode,2)
                  << ")" ;
      }
      std::cout << " }" << std::endl ;

      std::cout << "Node coord {" ;
      for ( unsigned inode = 0 ; inode < fixture.node_count() ; ++inode ) {
        std::cout << " (" << h_node_coord(inode,0)
                  << "," << h_node_coord(inode,1)
                  << "," << h_node_coord(inode,2)
                  << ")" ;
      }
      std::cout << " }" << std::endl ;

      std::cout << "Manufactured solution"
                << " a[" << manufactured_solution.a << "]"
                << " b[" << manufactured_solution.b << "]"
                << " K[" << manufactured_solution.K << "]"
                << " {" ;
      for ( unsigned inode = 0 ; inode < fixture.node_count() ; ++inode ) {
        std::cout << " " << manufactured_solution( h_node_coord( inode , 2 ) );
      }
      std::cout << " }" << std::endl ;

      std::cout << "ElemNode {" << std::endl ;
      for ( unsigned ielem = 0 ; ielem < fixture.elem_count() ; ++ielem ) {
        std::cout << "  elem[" << ielem << "]{" ;
        for ( unsigned inode = 0 ; inode < FixtureType::ElemNode ; ++inode ) {
          std::cout << " " << h_elem_node(ielem,inode);
        }
        std::cout << " }{" ;
        for ( unsigned inode = 0 ; inode < FixtureType::ElemNode ; ++inode ) {
          std::cout << " (" << h_node_grid(h_elem_node(ielem,inode),0)
                    << "," << h_node_grid(h_elem_node(ielem,inode),1)
                    << "," << h_node_grid(h_elem_node(ielem,inode),2)
                    << ")" ;
        }
        std::cout << " }" << std::endl ;
      }
      std::cout << "}" << std::endl ;
    }
    std::cout.flush();
    MPI_Barrier( comm );
  }

  //------------------------------------

  Kokkos::Timer wall_clock ;

  Perf perf_stats = Perf() ;

  for ( int itrial = 0 ; itrial < use_trials ; ++itrial ) {

    Perf perf = Perf() ;

    perf.global_elem_count = fixture.elem_count_global();
    perf.global_node_count = fixture.node_count_global();

    //----------------------------------
    // Create the sparse matrix graph and element-to-graph map
    // from the element->to->node identifier array.
    // The graph only has rows for the owned nodes.

    typename NodeNodeGraphType::Times graph_times;

    const NodeNodeGraphType
      mesh_to_graph( fixture.elem_node() , fixture.node_count_owned(), graph_times );

    perf.map_ratio          = maximum(comm, graph_times.ratio);
    perf.fill_node_set      = maximum(comm, graph_times.fill_node_set);
    perf.scan_node_count    = maximum(comm, graph_times.scan_node_count);
    perf.fill_graph_entries = maximum(comm, graph_times.fill_graph_entries);
    perf.sort_graph_entries = maximum(comm, graph_times.sort_graph_entries);
    perf.fill_element_graph = maximum(comm, graph_times.fill_element_graph);

    wall_clock.reset();
    // Create the sparse matrix from the graph:

    SparseMatrixType jacobian( mesh_to_graph.graph );

    Space::fence();

    perf.create_sparse_matrix = maximum( comm , wall_clock.seconds() );

    //----------------------------------

    for ( int k = 0 ; k < comm_size && print_flag ; ++k ) {
      if ( k == comm_rank ) {
        const unsigned nrow = jacobian.graph.numRows();
        std::cout << "MPI[" << comm_rank << "]" << std::endl ;
        std::cout << "JacobianGraph {" << std::endl ;
        for ( unsigned irow = 0 ; irow < nrow ; ++irow ) {
          std::cout << "  row[" << irow << "]{" ;
          const unsigned entry_end = jacobian.graph.row_map(irow+1);
          for ( unsigned entry = jacobian.graph.row_map(irow) ; entry < entry_end ; ++entry ) {
            std::cout << " " << jacobian.graph.entries(entry);
          }
          std::cout << " }" << std::endl ;
        }
        std::cout << "}" << std::endl ;

        std::cout << "ElemGraph {" << std::endl ;
        for ( unsigned ielem = 0 ; ielem < mesh_to_graph.elem_graph.dimension_0() ; ++ielem ) {
          std::cout << "  elem[" << ielem << "]{" ;
          for ( unsigned irow = 0 ; irow < mesh_to_graph.elem_graph.dimension_1() ; ++irow ) {
            std::cout << " {" ;
            for ( unsigned icol = 0 ; icol < mesh_to_graph.elem_graph.dimension_2() ; ++icol ) {
              std::cout << " " << mesh_to_graph.elem_graph(ielem,irow,icol);
            }
            std::cout << " }" ;
          }
          std::cout << " }" << std::endl ;
        }
        std::cout << "}" << std::endl ;
      }
      std::cout.flush();
      MPI_Barrier( comm );
    }

    //----------------------------------

    // Allocate solution vector for each node in the mesh and residual vector for each owned node
    const VectorType nodal_solution( "nodal_solution" , fixture.node_count() );
    const VectorType nodal_residual( "nodal_residual" , fixture.node_count_owned() );
    const VectorType nodal_delta(    "nodal_delta" ,    fixture.node_count_owned() );

    // Create element computation functor
    const ElementComputationType elemcomp(
      use_atomic ? ElementComputationType( fixture , manufactured_solution.K , nodal_solution ,
                                           mesh_to_graph.elem_graph , jacobian , nodal_residual )
                 : ElementComputationType( fixture , manufactured_solution.K , nodal_solution ) );

    const NodeElemGatherFillType gatherfill(
      use_atomic ? NodeElemGatherFillType()
                 : NodeElemGatherFillType( fixture.elem_node() ,
                                           mesh_to_graph.elem_graph ,
                                           nodal_residual ,
                                           jacobian ,
                                           elemcomp.elem_residuals ,
                                           elemcomp.elem_jacobians ) );

    // Create boundary condition functor
    const DirichletComputationType dirichlet(
      fixture , nodal_solution , jacobian , nodal_residual ,
      2 /* apply at 'z' ends */ ,
      manufactured_solution.T_zmin ,
      manufactured_solution.T_zmax );

    //----------------------------------
    // Nonlinear Newton iteration:

    double residual_norm_init = 0 ;

    for ( perf.newton_iter_count = 0 ;
          perf.newton_iter_count < newton_iteration_limit ;
          ++perf.newton_iter_count ) {

      //--------------------------------

      comm_nodal_import( nodal_solution );

      //--------------------------------
      // Element contributions to residual and jacobian

      wall_clock.reset();

      Kokkos::deep_copy( nodal_residual , double(0) );
      Kokkos::deep_copy( jacobian.coeff , double(0) );

      elemcomp.apply();

      if ( ! use_atomic ) {
        gatherfill.apply();
      }

      Space::fence();
      perf.fill_time = maximum( comm , wall_clock.seconds() );

      //--------------------------------
      // Apply boundary conditions

      wall_clock.reset();

      dirichlet.apply();

      Space::fence();
      perf.bc_time = maximum( comm , wall_clock.seconds() );

      //--------------------------------
      // Evaluate convergence

      const double residual_norm =
        std::sqrt(
          Kokkos::Example::all_reduce(
            Kokkos::Example::dot( fixture.node_count_owned() , nodal_residual, nodal_residual ) , comm ) );

      perf.newton_residual = residual_norm ;

      if ( 0 == perf.newton_iter_count ) { residual_norm_init = residual_norm ; }

      if ( residual_norm < residual_norm_init * newton_iteration_tolerance ) { break ; }

      //--------------------------------
      // Solve for nonlinear update

      CGSolveResult cg_result ;

      Kokkos::Example::cgsolve( comm_nodal_import
                              , jacobian
                              , nodal_residual
                              , nodal_delta
                              , cg_iteration_limit
                              , cg_iteration_tolerance
                              , & cg_result
                              );

      // Update solution vector

      Kokkos::Example::waxpby( fixture.node_count_owned() , nodal_solution , -1.0 , nodal_delta , 1.0 , nodal_solution );

      perf.cg_iter_count += cg_result.iteration ;
      perf.matvec_time   += cg_result.matvec_time ;
      perf.cg_time       += cg_result.iter_time ;

      //--------------------------------

      if ( print_flag ) {
        const double delta_norm =
          std::sqrt(
            Kokkos::Example::all_reduce(
              Kokkos::Example::dot( fixture.node_count_owned() , nodal_delta, nodal_delta ) , comm ) );

        if ( 0 == comm_rank ) {
          std::cout << "Newton iteration[" << perf.newton_iter_count << "]"
                    << " residual[" << perf.newton_residual << "]"
                    << " update[" << delta_norm << "]"
                    << " cg_iteration[" << cg_result.iteration << "]"
                    << " cg_residual[" << cg_result.norm_res << "]"
                    << std::endl ;
        }

        for ( int k = 0 ; k < comm_size ; ++k ) {
          if ( k == comm_rank ) {
            const unsigned nrow = jacobian.graph.numRows();

            std::cout << "MPI[" << comm_rank << "]" << std::endl ;
            std::cout << "Residual {" ;
            for ( unsigned irow = 0 ; irow < nrow ; ++irow ) {
              std::cout << " " << nodal_residual(irow);
            }
            std::cout << " }" << std::endl ;

            std::cout << "Delta {" ;
            for ( unsigned irow = 0 ; irow < nrow ; ++irow ) {
              std::cout << " " << nodal_delta(irow);
            }
            std::cout << " }" << std::endl ;

            std::cout << "Solution {" ;
            for ( unsigned irow = 0 ; irow < nrow ; ++irow ) {
              std::cout << " " << nodal_solution(irow);
            }
            std::cout << " }" << std::endl ;

            std::cout << "Jacobian[ "
                      << jacobian.graph.numRows() << " x " << Kokkos::maximum_entry( jacobian.graph )
                      << " ] {" << std::endl ;
            for ( unsigned irow = 0 ; irow < nrow ; ++irow ) {
              std::cout << "  {" ;
              const unsigned entry_end = jacobian.graph.row_map(irow+1);
              for ( unsigned entry = jacobian.graph.row_map(irow) ; entry < entry_end ; ++entry ) {
                std::cout << " (" << jacobian.graph.entries(entry)
                          << "," << jacobian.coeff(entry)
                          << ")" ;
              }
              std::cout << " }" << std::endl ;
            }
            std::cout << "}" << std::endl ;
          }
          std::cout.flush();
          MPI_Barrier( comm );
        }
      }
      //--------------------------------
    }

    // Evaluate solution error

    if ( 0 == itrial ) {
      const typename FixtureType::node_coord_type::HostMirror
        h_node_coord = Kokkos::create_mirror_view( fixture.node_coord() );

      const typename VectorType::HostMirror
        h_nodal_solution = Kokkos::create_mirror_view( nodal_solution );

      Kokkos::deep_copy( h_node_coord , fixture.node_coord() );
      Kokkos::deep_copy( h_nodal_solution , nodal_solution );

      double error_max = 0 ;
      for ( unsigned inode = 0 ; inode < fixture.node_count_owned() ; ++inode ) {
        const double answer = manufactured_solution( h_node_coord( inode , 2 ) );
        const double error = ( h_nodal_solution(inode) - answer ) / answer ;
        if ( error_max < fabs( error ) ) { error_max = fabs( error ); }
      }

      perf.error_max = std::sqrt( Kokkos::Example::all_reduce_max( error_max , comm ) );

      perf_stats = perf ;
    }
    else {
      perf_stats.fill_node_set = std::min( perf_stats.fill_node_set , perf.fill_node_set );
      perf_stats.scan_node_count = std::min( perf_stats.scan_node_count , perf.scan_node_count );
      perf_stats.fill_graph_entries = std::min( perf_stats.fill_graph_entries , perf.fill_graph_entries );
      perf_stats.sort_graph_entries = std::min( perf_stats.sort_graph_entries , perf.sort_graph_entries );
      perf_stats.fill_element_graph = std::min( perf_stats.fill_element_graph , perf.fill_element_graph );
      perf_stats.create_sparse_matrix = std::min( perf_stats.create_sparse_matrix , perf.create_sparse_matrix );
      perf_stats.fill_time = std::min( perf_stats.fill_time , perf.fill_time );
      perf_stats.bc_time = std::min( perf_stats.bc_time , perf.bc_time );
      perf_stats.cg_time = std::min( perf_stats.cg_time , perf.cg_time );
    }
  }

  return perf_stats ;
}
Exemple #8
0
void FF10Node::process( qint64 pTimeStamp )
{
	fugio::Performance		Perf( mNode, __FUNCTION__, pTimeStamp );

	FF_Main_FuncPtr		MainFunc = mLibrary->func();

	if( !MainFunc )
	{
		return;
	}

	fugio::Image	DstImg = mValOutput->variant().value<fugio::Image>();

	if( DstImg.format() == fugio::ImageFormat::UNKNOWN )
	{
/*		if( mLibrary->flags().testFlag( FreeframeLibrary::CAP_32BIT ) )
		{
			DstImg.setFormat( fugio::ImageFormat::RGBA8 );

//			mBitDepth = FF_CAP_32BITVIDEO;
		}
		else */if( mLibrary->flags().testFlag( FreeframeLibrary::CAP_24BIT ) )
		{
#if defined( Q_OS_WIN )
			DstImg.setFormat( fugio::ImageFormat::BGR8 );
#else
			DstImg.setFormat( fugio::ImageFormat::RGB8 );
#endif

			mBitDepth = FF_CAP_24BITVIDEO;
		}
		else if( mLibrary->flags().testFlag( FreeframeLibrary::CAP_16BIT ) )
		{
			DstImg.setFormat( fugio::ImageFormat::RGB_565 );

			mBitDepth = FF_CAP_16BITVIDEO;
		}
	}

	if( DstImg.format() == fugio::ImageFormat::UNKNOWN )
	{
		return;
	}

	//-------------------------------------------------------------------------
	// Calculate the input size

	QSize		SrcSze;

	for( int i = 0 ; i < mInputs.size() ; i++ )
	{
		fugio::Image	SrcImg = variant<fugio::Image>( mInputs.at( i ) );

		if( !SrcImg.isValid() )
		{
			continue;
		}

		if( SrcImg.width() > SrcSze.width() )
		{
			SrcSze.setWidth( SrcImg.width() );
		}

		if( SrcImg.height() > SrcSze.height() )
		{
			SrcSze.setHeight( SrcImg.height() );
		}

		if( SrcImg.format() != DstImg.format() )
		{
			continue;
		}
	}

	if( !SrcSze.isValid() )
	{
		return;
	}

	//-------------------------------------------------------------------------
	// Initialise the instance

	FFMixed			PMU;

	if( DstImg.size() != SrcSze )
	{
		if( mInstanceId )
		{
			PMU.UIntValue = 0;

			PMU = MainFunc( FF_DEINSTANTIATE, PMU, mInstanceId );

			mInstanceId = 0;
		}

		DstImg.setSize( SrcSze );

		if( mBitDepth == FF_CAP_16BITVIDEO )
		{
			DstImg.setLineSize( 0, 2 * SrcSze.width() );
		}
		else if( mBitDepth == FF_CAP_24BITVIDEO )
		{
			DstImg.setLineSize( 0, 3 * SrcSze.width() );
		}
		else if( mBitDepth == FF_CAP_32BITVIDEO )
		{
			DstImg.setLineSize( 0, 4 * SrcSze.width() );
		}

		mDstBuf.resize( 1024 + DstImg.bufferSize( 0 ) + 1024 );

		DstImg.setBuffer( 0, &mDstBuf[ 1024 ] );

		VideoInfoStruct	VIS;

		VIS.BitDepth    = mBitDepth;
		VIS.FrameWidth  = SrcSze.width();
		VIS.FrameHeight = SrcSze.height();
		VIS.Orientation = FF_ORIENTATION_TL;

		PMU.PointerValue = &VIS;

		PMU = MainFunc( FF_INSTANTIATE, PMU, 0 );

		if( PMU.UIntValue == FF_FAIL )
		{
			return;
		}

		mInstanceId = PMU.PointerValue;
	}

	if( !mInstanceId )
	{
		return;
	}

	//-------------------------------------------------------------------------
	// Prepare the source frames

	QVector<void *>		SrcPtr;

	for( int i = 0 ; i < mInputs.size() ; i++ )
	{
		fugio::Image	SrcImg = variant<fugio::Image>( mInputs.at( i ) );

		if( !SrcImg.isValid() )
		{
			continue;
		}

		if( SrcImg.size() != SrcSze || SrcImg.lineSize( 0 ) != DstImg.lineSize( 0 ) )
		{
			continue;
		}

		SrcPtr << SrcImg.buffer( 0 );
	}

	//-------------------------------------------------------------------------
	// Update the parameters

	SetParameterStructTag	PrmSet;

	for( int i = 0 ; i < mParams.size() ; i++ )
	{
		QSharedPointer<fugio::PinInterface>		PrmPin = mParams.at( i );
		FreeframeLibrary::ParamEntry			PrmEnt = mLibrary->params().at( i );

		QVariant		PrmVal = variant( PrmPin );

		PrmSet.ParameterNumber = i;

		if( PrmEnt.mType == FF_TYPE_STANDARD )
		{
			PrmSet.NewParameterValue.FloatValue = qBound( 0.0f, PrmVal.value<float>(), 1.0f );

			PMU.PointerValue = &PrmSet;

			MainFunc( FF_SETPARAMETER, PMU, mInstanceId );
		}
		else if( PrmEnt.mType == FF_TYPE_BOOLEAN )
		{
			PrmSet.NewParameterValue.UIntValue = PrmVal.value<bool>() ? FF_TRUE : FF_FALSE;

			PMU.PointerValue = &PrmSet;

			MainFunc( FF_SETPARAMETER, PMU, mInstanceId );
		}

		PMU.UIntValue = i;

		PMU = MainFunc( FF_GETPARAMETERDISPLAY, PMU, mInstanceId );

		if( PMU.UIntValue != FF_FAIL )
		{
			PrmPin->setDisplayLabel( QString::fromLatin1( QByteArray( (const char *)PMU.PointerValue, 16 ) ) );
		}
	}

	//-------------------------------------------------------------------------
	// Call the plugin

	if( SrcPtr.size() >= mLibrary->minInputFrames() )
	{
		if( mLibrary->hasProcessFrameCopy() )
		{
			ProcessFrameCopyStruct	PFC;

			PFC.numInputFrames = SrcPtr.size();
			PFC.pOutputFrame   = DstImg.buffer( 0 );
			PFC.ppInputFrames  = SrcPtr.data();

			PMU.PointerValue = &PFC;

			PMU = MainFunc( FF_PROCESSFRAMECOPY, PMU, mInstanceId );
		}
		else
		{
			if( !SrcPtr.isEmpty() )
			{
				memcpy( DstImg.buffer( 0 ), SrcPtr.first(), DstImg.bufferSize( 0 ) );
			}

			PMU.PointerValue = DstImg.buffer( 0 );

			PMU = MainFunc( FF_PROCESSFRAME, PMU, mInstanceId );
		}
	}

	//-------------------------------------------------------------------------
	// Update the pin if we succeed

	if( PMU.UIntValue == FF_SUCCESS )
	{
		pinUpdated( mPinOutput );
	}
}