TEST_FIXTURE(INDMathTests,LookAtMatrixEyeLookUpLH) {
	//Result
	IND_Matrix result;
	IND_Vector3 eye(1.0f, 2.0f, 3.0f);
	IND_Vector3 look(1.0f, 2.0f, 2.0f);  //Just on z coord lower
	IND_Vector3 up(0.0f, -1.0f, 0.0f);

    math->matrix4DLookAtMatrixEyeLookUpLH(eye,look,up,result);

	IND_Vector3 x(1.0f, 0.0f, 0.0f);
    IND_Vector3 y(0.0f, -1.0f, 0.0f);
	IND_Vector3 z(0.0f, 0.0f, -1.0f);

	CHECK_CLOSE(x._x, result._11, 0.01f);
	CHECK_CLOSE(x._y, result._12, 0.01f);
	CHECK_CLOSE(x._z, result._13, 0.01f);
	CHECK_CLOSE(0.0f, result._41, 0.01f);

	CHECK_CLOSE(y._x, result._21, 0.01f);
	CHECK_CLOSE(y._y, result._22, 0.01f);
	CHECK_CLOSE(y._z, result._23, 0.01f);
	CHECK_CLOSE(0.0f, result._42, 0.01f);

	CHECK_CLOSE(z._x, result._31, 0.01f);
	CHECK_CLOSE(z._y, result._32, 0.01f);
	CHECK_CLOSE(z._z, result._33, 0.01f);
	CHECK_CLOSE(0.0f, result._43, 0.01f);

	CHECK_CLOSE(-x.dotProduct(eye), result._14, 0.01f);
	CHECK_CLOSE(-y.dotProduct(eye), result._24, 0.01f);
	CHECK_CLOSE(-z.dotProduct(eye), result._34, 0.01f);
	CHECK_CLOSE(1.0f, result._44, 0.01f);
}
TEST_FIXTURE(INDMathTests,idendityMatrix) {
    IND_Matrix matrix = IND_Matrix::identity();
    
    CHECK_CLOSE(1.f, matrix._11, 0.01f);
    CHECK_CLOSE(0.f, matrix._12, 0.01f);
    CHECK_CLOSE(0.f, matrix._13, 0.01f);
    CHECK_CLOSE(0.f, matrix._14, 0.01f);
    CHECK_CLOSE(0.f, matrix._21, 0.01f);
    CHECK_CLOSE(1.f, matrix._22, 0.01f);
    CHECK_CLOSE(0.f, matrix._23, 0.01f);
    CHECK_CLOSE(0.f, matrix._24, 0.01f);
    CHECK_CLOSE(0.f, matrix._31, 0.01f);
    CHECK_CLOSE(0.f, matrix._32, 0.01f);
    CHECK_CLOSE(1.f, matrix._33, 0.01f);
    CHECK_CLOSE(0.f, matrix._34, 0.01f);
    CHECK_CLOSE(0.f, matrix._41, 0.01f);
    CHECK_CLOSE(0.f, matrix._42, 0.01f);
    CHECK_CLOSE(0.f, matrix._43, 0.01f);
    CHECK_CLOSE(1.f, matrix._44, 0.01f);
}
TEST_FIXTURE(INDMathTests,LookAtMatrixLH) {
	//Result
	IND_Matrix result;
	IND_Vector3 up(0.0f, 1.0f, 0.0f);
	IND_Vector3 right(1.0f, 0.0f, 0.0f);
	IND_Vector3 look(0.0f, 0.0f, -1.0f);
	IND_Vector3 pos(1.0f, 2.0f, 3.0f);

	math->matrix4DLookAtMatrixLH(right, up, look, pos, result);

	CHECK_CLOSE(right._x, result._11, 0.01f);
	CHECK_CLOSE(right._y, result._12, 0.01f);
	CHECK_CLOSE(right._z, result._13, 0.01f);
	CHECK_CLOSE(0.0f, result._41, 0.01f);

	CHECK_CLOSE(up._x, result._21, 0.01f);
	CHECK_CLOSE(up._y, result._22, 0.01f);
	CHECK_CLOSE(up._z, result._23, 0.01f);
	CHECK_CLOSE(0.0f, result._42, 0.01f);

	CHECK_CLOSE(look._x, result._31, 0.01f);
	CHECK_CLOSE(look._y, result._32, 0.01f);
	CHECK_CLOSE(look._z, result._33, 0.01f);
	CHECK_CLOSE(0.0f, result._43, 0.01f);

	CHECK_CLOSE(-pos.dotProduct(right), result._14, 0.01f);
	CHECK_CLOSE(-pos.dotProduct(up), result._24, 0.01f);
	CHECK_CLOSE(-pos.dotProduct(look), result._34, 0.01f);
	CHECK_CLOSE(1.0f, result._44, 0.01f);
}
TEST_FIXTURE(INDMathTests,MatrixMultiplyIdentity) {
	IND_Matrix m1;
	IND_Matrix m2;
	IND_Matrix result;

	//Construct first matrix
	math->matrix4DSetIdentity(m1);
	//Construct second matrix
	m2._11 = 11.0f;
	m2._12 = 12.0f;
	m2._13 = 12.0f;
	m2._14 = 14.0f;
	m2._21 = 21.0f;
	m2._22 = 22.0f;
	m2._23 = 22.0f;
	m2._24 = 24.0f;
	m2._31 = 31.0f;
	m2._32 = 32.0f;
	m2._33 = 32.0f;
	m2._34 = 34.0f;
	m2._41 = 41.0f;
	m2._42 = 42.0f;
	m2._43 = 42.0f;
	m2._44 = 44.0f;

	//Perform matrix multiplication
	math->matrix4DMultiply(m1, m2, result);

	//Checkings
	CHECK_CLOSE(m2._11, result._11, 0.01f);
	CHECK_CLOSE(m2._12, result._12, 0.01f);
	CHECK_CLOSE(m2._13, result._13, 0.01f);
	CHECK_CLOSE(m2._14, result._14, 0.01f);

	CHECK_CLOSE(m2._21, result._21, 0.01f);
	CHECK_CLOSE(m2._22, result._22, 0.01f);
	CHECK_CLOSE(m2._23, result._23, 0.01f);
	CHECK_CLOSE(m2._24, result._24, 0.01f);

	CHECK_CLOSE(m2._31, result._31, 0.01f);
	CHECK_CLOSE(m2._32, result._32, 0.01f);
	CHECK_CLOSE(m2._33, result._33, 0.01f);
	CHECK_CLOSE(m2._34, result._34, 0.01f);

	CHECK_CLOSE(m2._41, result._41, 0.01f);
	CHECK_CLOSE(m2._42, result._42, 0.01f);
	CHECK_CLOSE(m2._43, result._43, 0.01f);
	CHECK_CLOSE(m2._44, result._44, 0.01f);
}
TEST_FIXTURE(INDMathTests,MatrixMultiplyInPlace) {
	IND_Matrix m1;
	IND_Matrix m2;
    
	//Construct first matrix
	m1._11 = 1.0f;
	m1._12 = 2.0f;
	m1._13 = 3.0f;
	m1._14 = 4.0f;
	m1._21 = 5.0f;
	m1._22 = 6.0f;
	m1._23 = 7.0f;
	m1._24 = 8.0f;
	m1._31 = 9.0f;
	m1._32 = 10.0f;
	m1._33 = 11.0f;
	m1._34 = 12.0f;
	m1._41 = 13.0f;
	m1._42 = 14.0f;
	m1._43 = 15.0f;
	m1._44 = 16.0f;
	//Construct second matrix
	m2._11 = 1.0f;
	m2._12 = 2.0f;
	m2._13 = 3.0f;
	m2._14 = 4.0f;
	m2._21 = 5.0f;
	m2._22 = 6.0f;
	m2._23 = 7.0f;
	m2._24 = 8.0f;
	m2._31 = 9.0f;
	m2._32 = 10.0f;
	m2._33 = 11.0f;
	m2._34 = 12.0f;
	m2._41 = 13.0f;
	m2._42 = 14.0f;
	m2._43 = 15.0f;
	m2._44 = 16.0f;
    
	//Perform matrix multiplication
	math->matrix4DMultiplyInPlace(m1, m2);
    
	//Checkings
	CHECK_CLOSE(90.0f, m1._11, 0.01f);
	CHECK_CLOSE(100.0f, m1._12, 0.01f);
	CHECK_CLOSE(110.0f, m1._13, 0.01f);
	CHECK_CLOSE(120.0f, m1._14, 0.01f);
    
	CHECK_CLOSE(202.0f, m1._21, 0.01f);
	CHECK_CLOSE(228.0f, m1._22, 0.01f);
	CHECK_CLOSE(254.0f, m1._23, 0.01f);
	CHECK_CLOSE(280.0f, m1._24, 0.01f);
    
	CHECK_CLOSE(314.0f, m1._31, 0.01f);
	CHECK_CLOSE(356.0f, m1._32, 0.01f);
	CHECK_CLOSE(398.0f, m1._33, 0.01f);
	CHECK_CLOSE(440.0f, m1._34, 0.01f);
    
	CHECK_CLOSE(426.0f, m1._41, 0.01f);
	CHECK_CLOSE(484.0f, m1._42, 0.01f);
	CHECK_CLOSE(542.0f, m1._43, 0.01f);
	CHECK_CLOSE(600.0f, m1._44, 0.01f);
}
TEST_FIXTURE(INDMathTests,RotateVector) {
	//Rotation matrix
	IND_Matrix mrot;
	//Vector to rotate
	IND_Vector3 vec;

    //------------Rotation around Z axis-------------------------------
	//90 degress around z axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
    math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 0.0f, 1.0f));
	
    //Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(1.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around z axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 0.0f, 1.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.7f, vec._x, 0.01f);
	CHECK_CLOSE(0.7f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

	//90 degress around z axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 0.0f, 1.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(-1.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around z axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 0.0f, 1.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(-0.7f, vec._x, 0.01f);
	CHECK_CLOSE(0.7f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

	//90 degress around z axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 0.0f, 1.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(1.0f, vec._z, 0.01f);

    //45 degress around z axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 0.0f, 1.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(1.0f, vec._z, 0.01f);

    //------------Rotation around Y axis-------------------------------
	//90 degress around y axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(-1.0f, vec._z, 0.01f);

    //45 degress around y axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.7f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(-0.7f, vec._z, 0.01f);

	//90 degress around y axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(1.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around y axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(1.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);


    //90 degress around y axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(1.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around y axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(0.0f, 1.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.7f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.7f, vec._z, 0.01f);

    //------------Rotation around X axis-------------------------------
    //90 degress around x axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(1.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around x axis (x axis vector)
	vec = IND_Vector3(1.0f, 0.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(1.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

	//90 degress around x axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.0f, vec._y, 0.01f);
	CHECK_CLOSE(1.0f, vec._z, 0.01f);

    //45 degress around x axis (y axis vector)
	vec = IND_Vector3(0.0f, 1.0f, 0.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(0.7f, vec._y, 0.01f);
	CHECK_CLOSE(0.7f, vec._z, 0.01f);
	
    //90 degress around x axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 90.f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(-1.0f, vec._y, 0.01f);
	CHECK_CLOSE(0.0f, vec._z, 0.01f);

    //45 degress around x axis (z axis vector)
	vec = IND_Vector3(0.0f, 0.0f, 1.0f);
	math->matrix4DSetRotationAroundAxis(mrot, 45.0f, IND_Vector3(1.0f, 0.0f, 0.0f));

	//Rotation
	math->transformVector3DbyMatrix4D(vec, mrot);

	CHECK_CLOSE(0.0f, vec._x, 0.01f);
	CHECK_CLOSE(-0.7f, vec._y, 0.01f);
	CHECK_CLOSE(0.7f, vec._z, 0.01f);
}
示例#7
0
TEST_F (MyFixture, TestCase1)
{
    CHECK_CLOSE (someValue, 2.0f, 0.00001);
    someValue = 13;
}
示例#8
0
TEST_F (MyFixture, TestCase2)
{
    CHECK_CLOSE (someValue, 2.0f, 0.00001);
    CHECK_EQUAL (str, "Hello");
}
void test_boundary_mesh()
{
  typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
  typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3;
  typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits;
  typedef Traits::Barycentric_coordinate Barycentric_coordinate;
  typedef Traits::FT FT;
  typedef Traits::Point_3 Point_3;
  typedef Traits::Triangle_3 Triangle_3;
  typedef boost::graph_traits<Polyhedron_3> Graph_traits;
  typedef Graph_traits::vertex_descriptor vertex_descriptor;
  typedef Graph_traits::vertex_iterator vertex_iterator;
  typedef Graph_traits::face_descriptor face_descriptor;
  typedef Graph_traits::face_iterator face_iterator;
  typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
  typedef boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type VPM;

  Traits traits;

  Traits::Construct_triangle_3_to_triangle_2_projection project_triangle_3_to_triangle_2(traits.construct_triangle_3_to_triangle_2_projection_object());
  CGAL_USE(project_triangle_3_to_triangle_2);
  Traits::Compute_squared_distance_3 compute_squared_distance_3(traits.compute_squared_distance_3_object());
  Traits::Construct_barycenter_3 construct_barycenter_3(traits.construct_barycenter_3_object());
  Traits::Construct_triangle_3_along_segment_2_flattening flatten_triangle_3_along_segment_2(traits.construct_triangle_3_along_segment_2_flattening_object());
  CGAL_USE(flatten_triangle_3_along_segment_2);
  Traits::Construct_barycentric_coordinate construct_barycentric_coordinate(traits.construct_barycentric_coordinate_object());

  struct Construct_barycenter_in_triangle_3
  {
    Traits::Construct_barycenter_3 m_cb3;

    Construct_barycenter_in_triangle_3(Traits::Construct_barycenter_3 cb3)
      : m_cb3(cb3)
    {
    }

    Point_3 operator() (const Triangle_3& t, const Barycentric_coordinate& b)
    {
      return m_cb3(t[0], b[0], t[1], b[1], t[2], b[2]);
    }
  } construct_barycenter_in_triangle_3(construct_barycenter_3);

  std::ifstream inFile("data/boundary_mesh.off");

  Polyhedron_3 P;

  inFile >> P;

  inFile.close();

  CGAL::set_halfedgeds_items_id(P);

  face_iterator startFace;
  face_iterator endFace;

  boost::tie(startFace, endFace) = CGAL::faces(P);

  vertex_iterator currentVertex;
  vertex_iterator endVertex;

  VPM vpm = CGAL::get(CGAL::vertex_point, P);

  vertex_descriptor vertexHandles[10];
  face_descriptor faceHandles[8];
  Point_3 vertexLocations[10];
  size_t currentVertexIndex = 0;

  for (boost::tie(currentVertex, endVertex) = CGAL::vertices(P); currentVertex != endVertex; ++currentVertex)
  {
    vertexHandles[currentVertexIndex] = *currentVertex;
    vertexLocations[currentVertexIndex] = vpm[*currentVertex];
    ++currentVertexIndex;
  }

  size_t currentFaceIndex = 0;

  for (face_iterator currentFace = startFace; currentFace != endFace; ++currentFace)
  {
    faceHandles[currentFaceIndex] = *currentFace;
    ++currentFaceIndex;
  }

  Barycentric_coordinate startLocation = construct_barycentric_coordinate(FT(0.1), FT(0.8), FT(0.1));

  typedef boost::property_map<Polyhedron_3, CGAL::face_external_index_t>::type FaceIndexMap;

  FaceIndexMap faceIndexMap(CGAL::get(CGAL::face_external_index, P));

  Surface_mesh_shortest_path shortestPaths(P, traits);
  //shortestPaths.m_debugOutput = true;
  shortestPaths.add_source_point(*startFace, startLocation);
  shortestPaths.build_sequence_tree();

  Triangle_3 firstTriangle(vertexLocations[1], vertexLocations[0], vertexLocations[2]);

  Point_3 locationInTriangle(construct_barycenter_in_triangle_3(firstTriangle, startLocation));

  FT dist0 = shortestPaths.shortest_distance_to_source_points(vertexHandles[0]).first;
  CHECK_CLOSE(dist0, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[0])), FT(0.000001));

  FT dist1 = shortestPaths.shortest_distance_to_source_points(vertexHandles[1]).first;
  CHECK_CLOSE(dist1, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[1])), FT(0.000001));

  FT dist2 = shortestPaths.shortest_distance_to_source_points(vertexHandles[2]).first;
  CHECK_CLOSE(dist2, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[2])), FT(0.000001));

  FT dist3 = shortestPaths.shortest_distance_to_source_points(vertexHandles[3]).first;
  CHECK_CLOSE(dist3, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[3])), FT(0.000001));

  FT dist4 = shortestPaths.shortest_distance_to_source_points(vertexHandles[4]).first;
  CHECK_CLOSE(dist4, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[1])) + CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], vertexLocations[4])), FT(0.000001));

  FT dist5 = shortestPaths.shortest_distance_to_source_points(vertexHandles[5]).first;
  CHECK_CLOSE(dist5, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, vertexLocations[3])) + CGAL::sqrt(compute_squared_distance_3(vertexLocations[3], vertexLocations[5])), FT(0.000001));

  Barycentric_coordinate somewhereElseInFirstTriangle = construct_barycentric_coordinate(0.8, 0.05, 0.15);

  FT distT0 = shortestPaths.shortest_distance_to_source_points(faceHandles[0], somewhereElseInFirstTriangle).first;
  CHECK_CLOSE(distT0, CGAL::sqrt(compute_squared_distance_3(locationInTriangle, construct_barycenter_in_triangle_3(firstTriangle, somewhereElseInFirstTriangle))), FT(0.000001));

  Triangle_3 oneStepTriangle(vertexLocations[4], vertexLocations[1], vertexLocations[3]);
  Barycentric_coordinate locationInOneStepTriangle = construct_barycentric_coordinate(0.1, 0.8, 0.1);

  CGAL::test::Edge_sequence_collector<Traits> collector(P);
  shortestPaths.shortest_path_sequence_to_source_points(faceHandles[2], locationInOneStepTriangle, collector);

  FT distT2 = shortestPaths.shortest_distance_to_source_points(faceHandles[2], locationInOneStepTriangle).first;
  CHECK_CLOSE(distT2, dist1 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], construct_barycenter_in_triangle_3(oneStepTriangle, locationInOneStepTriangle))), FT(0.00001));

  Triangle_3 twoStepTriangle(vertexLocations[6], vertexLocations[5], vertexLocations[7]);
  Barycentric_coordinate locationInTwoStepTriangle = construct_barycentric_coordinate(0.8, 0.1, 0.1);

  FT distT5 = shortestPaths.shortest_distance_to_source_points(faceHandles[5], locationInTwoStepTriangle).first;
  CHECK_CLOSE(distT5, dist3 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[3], construct_barycenter_in_triangle_3(twoStepTriangle, locationInTwoStepTriangle))), FT(0.00001));

  Triangle_3 threeStepTriangle(vertexLocations[7], vertexLocations[5], vertexLocations[8]);
  Barycentric_coordinate locationInThreeStepTriangle = construct_barycentric_coordinate(0.2, 0.6, 0.2);

  FT distT6 = shortestPaths.shortest_distance_to_source_points(faceHandles[6], locationInThreeStepTriangle).first;
  CHECK_CLOSE(distT6, dist5 + CGAL::sqrt(compute_squared_distance_3(vertexLocations[5], construct_barycenter_in_triangle_3(threeStepTriangle, locationInThreeStepTriangle))), FT(0.00001));
}
void test_simple_saddle_vertex_mesh()
{
  typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
  typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3;
  typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits;
  typedef Traits::Barycentric_coordinate Barycentric_coordinate;
  typedef Traits::FT FT;
  typedef Traits::Point_3 Point_3;
  typedef Traits::Point_2 Point_2;
  typedef Traits::Triangle_3 Triangle_3;
  typedef Traits::Triangle_2 Triangle_2;
  typedef Traits::Segment_2 Segment_2;
  typedef boost::graph_traits<Polyhedron_3> Graph_traits;
  typedef Graph_traits::vertex_descriptor vertex_descriptor;
  typedef Graph_traits::vertex_iterator vertex_iterator;
  typedef Graph_traits::halfedge_descriptor halfedge_descriptor;
  typedef Graph_traits::face_descriptor face_descriptor;
  typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
  typedef boost::property_map<Polyhedron_3, CGAL::vertex_point_t>::type VPM;

  Traits traits;

  Traits::Compute_squared_distance_3 compute_squared_distance_3(traits.compute_squared_distance_3_object());
  Traits::Compute_squared_distance_2 compute_squared_distance_2(traits.compute_squared_distance_2_object());
  Traits::Construct_triangle_3_along_segment_2_flattening flatten_triangle_3_along_segment_2(traits.construct_triangle_3_along_segment_2_flattening_object());
  Traits::Construct_barycentric_coordinate construct_barycentric_coordinate(traits.construct_barycentric_coordinate_object());

  std::ifstream inFile("data/saddle_vertex_mesh.off");

  Polyhedron_3 P;

  inFile >> P;

  inFile.close();

  CGAL::set_halfedgeds_items_id(P);

  vertex_iterator startVertex;
  vertex_iterator endVertex;
  boost::tie(startVertex, endVertex) = CGAL::vertices(P);

  vertex_iterator currentVertex = startVertex;

  ++currentVertex;
  vertex_descriptor rootSearchVertex = *currentVertex;

  face_descriptor currentFace = CGAL::face(CGAL::halfedge(rootSearchVertex, P), P);
  size_t vertexIndex = CGAL::test::face_vertex_index(currentFace, rootSearchVertex, P);
  Barycentric_coordinate baryCoord = construct_barycentric_coordinate(vertexIndex == 0 ? FT(1.0) : FT(0.0), vertexIndex == 1 ? FT(1.0) : FT(0.0), vertexIndex == 2 ? FT(1.0) : FT(0.0));

  Surface_mesh_shortest_path shortestPaths(P, traits);
  //shortestPaths.m_debugOutput = true;
  Surface_mesh_shortest_path::Source_point_iterator firstSourcePoint = shortestPaths.add_source_point(currentFace, baryCoord);
  shortestPaths.build_sequence_tree();

  VPM vpm = CGAL::get(CGAL::vertex_point, P);

  Point_3 vertexLocations[8];
  vertex_descriptor vertexHandles[8];

  currentVertex = startVertex;

  for (size_t i = 0; i < 8; ++i)
  {
    vertexHandles[i] = *currentVertex;
    vertexLocations[i] = vpm[*currentVertex];
    ++currentVertex;
  }

  FT distanceToBottom = CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], vertexLocations[0]));
  FT largerSideLength = CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], vertexLocations[2]));
  FT distanceToSaddle = CGAL::sqrt(compute_squared_distance_3(vertexLocations[1], vertexLocations[4]));
  FT shorterSideLength = CGAL::sqrt(compute_squared_distance_3(vertexLocations[4], vertexLocations[6]));

  Triangle_3 lower(vertexLocations[6], vertexLocations[4], vertexLocations[1]);
  Triangle_3 upper(vertexLocations[4], vertexLocations[6], vertexLocations[7]);

  Segment_2 base(Point_2(CGAL::ORIGIN), Point_2(shorterSideLength, FT(0.0)));

  Triangle_2 flatLower(flatten_triangle_3_along_segment_2(lower, 0, base));
  Triangle_2 flatUpper(flatten_triangle_3_along_segment_2(upper, 0, Segment_2(base[1], base[0])));

  FT distanceToApex = CGAL::sqrt(compute_squared_distance_2(flatLower[2], flatUpper[2]));

  FT expectedDistances[8] =
  {
    distanceToBottom, // a vertex of the larger tetrahedron
    FT(0.0), // the initial vertex
    largerSideLength, // a vertex of the larger tetrahedron
    largerSideLength, // a vertex of the larger tetrahedron
    distanceToSaddle,  // direct line of sight from root
    distanceToSaddle + shorterSideLength,  // around the corner from a pseudo-source (not in direct line of geodesic sight)
    distanceToSaddle, // direct line of sight from root
    distanceToApex,
  };

  currentVertex = startVertex;

  for (size_t i = 0; i < 8; ++i)
  {
    CHECK_CLOSE(shortestPaths.shortest_distance_to_source_points(*currentVertex).first, expectedDistances[i], Kernel::FT(0.0001));
    ++currentVertex;
  }

  // test the edge sequence reporting
  CGAL::test::Edge_sequence_collector<Traits> collector(P);

  shortestPaths.shortest_path_sequence_to_source_points(vertexHandles[5], collector);

  CHECK_EQUAL(collector.m_sequence.size(), 3u);
  CHECK_EQUAL(collector.m_sequence[1].type, CGAL::test::SEQUENCE_ITEM_VERTEX);
  assert(collector.m_sequence[1].index == 4 || collector.m_sequence[1].index == 6);
  CHECK_EQUAL(collector.m_sequence[2].type, CGAL::test::SEQUENCE_ITEM_VERTEX);
  CHECK_EQUAL(collector.m_sequence[2].index, 1u);

  collector.m_sequence.clear();

  typedef boost::property_map<Polyhedron_3, CGAL::halfedge_external_index_t>::type HalfedgeIndexMap;

  HalfedgeIndexMap halfedgeIndexMap(CGAL::get(CGAL::halfedge_external_index, P));

  shortestPaths.shortest_path_sequence_to_source_points(vertexHandles[7], collector);

  CHECK_EQUAL(collector.m_sequence.size(), 3u);
  CHECK_EQUAL(collector.m_sequence[1].type, CGAL::test::SEQUENCE_ITEM_EDGE);
  CHECK_EQUAL(collector.m_sequence[1].index, halfedgeIndexMap[CGAL::halfedge(vertexHandles[4], vertexHandles[6], P).first]);
  CHECK_CLOSE(collector.m_sequence[1].edgeAlpha, FT(0.5), FT(0.0001));
  CHECK_EQUAL(collector.m_sequence[2].type, CGAL::test::SEQUENCE_ITEM_VERTEX);
  CHECK_EQUAL(collector.m_sequence[2].index, 1u);

  // Now test an internal face location sequence
  halfedge_descriptor firstCrossing = CGAL::halfedge(vertexHandles[4], vertexHandles[7], P).first;

  size_t edgeIndex = CGAL::internal::edge_index(firstCrossing, P);

  Barycentric_coordinate location = construct_barycentric_coordinate(0.25, 0.5, 0.25);

  collector.m_sequence.clear();
  shortestPaths.shortest_path_sequence_to_source_points(CGAL::face(firstCrossing, P), construct_barycentric_coordinate(location[edgeIndex], location[(edgeIndex + 1) % 3], location[(edgeIndex + 2) % 3]), collector);

  CHECK_EQUAL(collector.m_sequence.size(), 4u);
  CHECK_EQUAL(collector.m_sequence[1].type, CGAL::test::SEQUENCE_ITEM_EDGE);
  CHECK_EQUAL(collector.m_sequence[1].index, halfedgeIndexMap[firstCrossing]);
  CHECK_EQUAL(collector.m_sequence[2].type, CGAL::test::SEQUENCE_ITEM_EDGE);
  CHECK_EQUAL(collector.m_sequence[2].index, halfedgeIndexMap[CGAL::halfedge(vertexHandles[4], vertexHandles[6], P).first]);
  CHECK_EQUAL(collector.m_sequence[3].type, CGAL::test::SEQUENCE_ITEM_VERTEX);
  CHECK_EQUAL(collector.m_sequence[3].index, 1u);

  // Now test with 2 source vertices
  currentVertex = startVertex;

  for (size_t i = 0; i < 5; ++i)
  {
    ++currentVertex;
  }

  vertex_descriptor rootSearchVertex2 = *currentVertex;

  face_descriptor currentFace2 = CGAL::face(CGAL::halfedge(rootSearchVertex2, P), P);
  size_t vertexIndex2 = CGAL::test::face_vertex_index(currentFace2, rootSearchVertex2, P);
  Barycentric_coordinate baryCoord2 = construct_barycentric_coordinate(vertexIndex2 == 0 ? FT(1.0) : FT(0.0), vertexIndex2 == 1 ? FT(1.0) : FT(0.0), vertexIndex2 == 2 ? FT(1.0) : FT(0.0));

  Surface_mesh_shortest_path::Source_point_iterator secondSourcePoint = shortestPaths.add_source_point(currentFace2, baryCoord2);
  shortestPaths.build_sequence_tree();

  FT distanceToApexFrom2 = CGAL::sqrt(compute_squared_distance_3(vertexLocations[5], vertexLocations[7]));

  Triangle_3 lower2(vertexLocations[2], vertexLocations[3], vertexLocations[5]);
  Triangle_3 upper2(vertexLocations[3], vertexLocations[2], vertexLocations[0]);

  Segment_2 base2(Point_2(CGAL::ORIGIN), Point_2(largerSideLength, FT(0.0)));

  Triangle_2 flatLower2(flatten_triangle_3_along_segment_2(lower2, 0, base2));
  Triangle_2 flatUpper2(flatten_triangle_3_along_segment_2(upper2, 0, Segment_2(base2[1], base2[0])));

  FT distanceToBottom2 = CGAL::sqrt(compute_squared_distance_2(flatLower2[2], flatUpper2[2]));

  FT expectedDistances2[8] =
  {
    distanceToBottom2, // a vertex of the larger tetrahedron
    FT(0.0), // an initial vertex
    distanceToSaddle, // a vertex of the larger tetrahedron
    distanceToSaddle, // a vertex of the larger tetrahedron
    shorterSideLength,  // direct line of sight from root
    FT(0.0),  // around the corner from a pseudo-source (not in direct line of geodesic sight)
    shorterSideLength, // direct line of sight from root
    distanceToApexFrom2,
  };

  Surface_mesh_shortest_path::Source_point_iterator expectedSources2[8] =
  {
    secondSourcePoint,
    firstSourcePoint,
    secondSourcePoint,
    secondSourcePoint,
    secondSourcePoint,
    secondSourcePoint,
    secondSourcePoint,
    secondSourcePoint,
  };

  currentVertex = startVertex;

  for (size_t i = 0; i < 8; ++i)
  {
    Surface_mesh_shortest_path::Shortest_path_result result = shortestPaths.shortest_distance_to_source_points(*currentVertex);

    CHECK_CLOSE(result.first, expectedDistances2[i], Kernel::FT(0.0001));
    assert(result.second == expectedSources2[i]);
    ++currentVertex;
  }

  // Test removing a source vertex

  shortestPaths.remove_source_point(firstSourcePoint);
  shortestPaths.build_sequence_tree();

  // replace the only shortest path which was not reporting to the 2nd source point
  expectedDistances2[1] = distanceToSaddle + shorterSideLength;

  currentVertex = startVertex;

  for (size_t i = 0; i < 8; ++i)
  {
    Surface_mesh_shortest_path::Shortest_path_result result = shortestPaths.shortest_distance_to_source_points(*currentVertex);

    CHECK_CLOSE(result.first, expectedDistances2[i], Kernel::FT(0.0001));
    assert(result.second == secondSourcePoint);
    ++currentVertex;
  }

}
示例#11
0
/* Basic functionality test for distributed 3D FFT
   This tests the integrity of a forward transform,
   followed by an inverse transform
 */
void test_distributed_fft_nd(int nd)
{
    int p,s;
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &s);

    int *pdim;
    pdim = (int *) malloc(sizeof(int)*nd);

    /* choose a decomposition */
    int r = powf(p,1.0/(double)nd)+0.5;
    int root = 1;
    while (root < r) root*=2;
    int ptot = 1;
    if (!s) printf("Processor grid: ");
    int i;
    for (i = 0; i < nd-1; ++i)
    {
        pdim[i] = (((ptot*root) > p) ? 1 : root);
        ptot *= pdim[i];
        if (!s) printf("%d x ",pdim[i]);
    }
    pdim[nd-1] = p/ptot;
    if (!s) printf("%d\n", pdim[nd-1]);

    /* determine processor index */
    int *pidx;
    pidx = (int*)malloc(nd*sizeof(int));
    int idx = s;
    for (i = nd-1; i >= 0; --i)
    {
        pidx[i] = idx % pdim[i];
        idx /= pdim[i];
    }

    double tol = 0.001;
    double abs_tol = 0.2;
    int *dim_glob;
    dim_glob = (int *) malloc(sizeof(int)*nd);

    /* test with a 1x1 matrix, but only if we are executing on a single rank */
    if (p == 1)
    {
        cuda_cpx_t *in_1_d;
        cuda_cpx_t *in_1_h;
        in_1_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*1);
        cudaMalloc((void **)&in_1_d,sizeof(cuda_cpx_t)*1);

        for (i = 0; i < nd; ++i)
            dim_glob[i] = 1*pdim[i];

        CUDA_RE(in_1_h[0]) = (double) s;
        CUDA_IM(in_1_h[0]) = 0.0f;

        /* copy to device */
        cudaMemcpy(in_1_d, in_1_h, sizeof(cuda_cpx_t)*1,cudaMemcpyDefault);

        dfft_plan plan_1;

        int pidx[1];
        pidx[0] =s;
        dfft_cuda_create_plan(&plan_1, nd, dim_glob, NULL, NULL, pdim, pidx,
                              0, 0, 0, MPI_COMM_WORLD, proc_map);
        dfft_cuda_check_errors(&plan_1,1);

        /* forward transform */
        dfft_cuda_execute(in_1_d, in_1_d, 0, &plan_1);

        /* backward transform */
        dfft_cuda_execute(in_1_d, in_1_d, 1, &plan_1);

        /* copy back to host */
        cudaMemcpy(in_1_h, in_1_d, sizeof(cuda_cpx_t)*1,cudaMemcpyDefault);

        if (s == 0)
        {
            CHECK_SMALL(CUDA_RE(in_1_h[0]),abs_tol);
            CHECK_SMALL(CUDA_IM(in_1_h[0]),abs_tol);
        }
        else
        {
            CHECK_CLOSE(CUDA_RE(in_1_h[0]),(double)s/(double)p,tol);
            CHECK_SMALL(CUDA_IM(in_1_h[0]),abs_tol);
        }

        cudaFree(in_1_d);
        free(in_1_h);
        dfft_cuda_destroy_plan(plan_1);
    }

    /* now do a test with a 2^n local matrix */
    cuda_cpx_t *in_2_d;
    cuda_cpx_t *in_2_h;
    int size_2n = 1;
    for (i = 0; i < nd; ++i)
        size_2n *= 2;

    cudaMalloc((void **)&in_2_d,sizeof(cuda_cpx_t)*size_2n);
    in_2_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*size_2n);

    for (i = 0; i < size_2n; ++i)
    {
        CUDA_RE(in_2_h[i]) =(i+s*(double)size_2n);
        CUDA_IM(in_2_h[i]) =0.0f;
    }

    /* copy data to device */
    cudaMemcpy(in_2_d, in_2_h, sizeof(cuda_cpx_t)*size_2n,cudaMemcpyDefault);

    for (i = 0; i < nd; ++i)
        dim_glob[i] = 2*pdim[i];

    for (i = 0; i < nd-1; ++i)
        if (!s) printf("%d x ",dim_glob[i]);
    if (!s) printf("%d matrix\n", dim_glob[nd-1]);

    dfft_plan plan_2;
    dfft_cuda_create_plan(&plan_2, nd, dim_glob, NULL, NULL, pdim, pidx, 0, 0, 0, MPI_COMM_WORLD, proc_map);
    dfft_cuda_check_errors(&plan_2,1);

    /* forward transfom */
    dfft_cuda_execute(in_2_d, in_2_d, 0, &plan_2);

    /* inverse transform */
    dfft_cuda_execute(in_2_d, in_2_d, 1, &plan_2);

    /* copy back to host */
    cudaMemcpy(in_2_h, in_2_d, sizeof(cuda_cpx_t)*size_2n, cudaMemcpyDefault);

    for (i = 0; i < size_2n; ++i)
    {
        if (s == 0 && i == 0)
        {
            CHECK_SMALL(CUDA_RE(in_2_h[i]), abs_tol);
            CHECK_SMALL(CUDA_IM(in_2_h[i]), abs_tol);
        }
        else
        {
            CHECK_CLOSE(CUDA_RE(in_2_h[i]), size_2n*p*(i+(double)size_2n*(double)s),tol);
            CHECK_SMALL(CUDA_IM(in_2_h[i]), abs_tol);
        }
    }

    cudaFree(in_2_d);
    free(in_2_h);
    dfft_cuda_destroy_plan(plan_2);

    // test with a padded 4^n local matrix (two ghost cells per axis)
    cuda_cpx_t *in_3_d;
    cuda_cpx_t *out_3_d;
    cuda_cpx_t *in_3_h;

    int *inembed;
    inembed = (int *) malloc(sizeof(int)*nd);

    int size_4n_embed = 1;
    int size_4n = 1;
    for (i = 0; i < nd; ++i)
    {
        inembed[i] = 4;
        size_4n_embed *= 4;
        size_4n *= 2;
        dim_glob[i]= 2*pdim[i];
    }

    for (i = 0; i < nd-1; ++i)
        if (!s) printf("%d x ",dim_glob[i]);
    if (!s) printf("%d matrix with padding\n", dim_glob[nd-1]);

    cudaMalloc((void **)&in_3_d,sizeof(cuda_cpx_t)*size_4n_embed);
    cudaMalloc((void **)&out_3_d,sizeof(cuda_cpx_t)*size_4n);
    in_3_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*size_4n_embed);

    int *lidx;
    int *gidx;
    lidx = (int *) malloc(nd*sizeof(int));
    gidx = (int *) malloc(nd*sizeof(int));

    for (i = 0; i < size_4n_embed; ++i)
    {
        //processor grid in column major
        int idx = i;

        // find local coordinate tuple
        int j;
        for (j = nd-1; j >= 0; --j)
        {
            int length = inembed[j];
            lidx[j] = idx % length;
            idx /= length;
        }

        // global coordinates in block distribution
        for (j = 0; j<nd; ++j)
            gidx[j] = lidx[j] + inembed[j]*pidx[j];

        int val=0;
        for (j = 0; j<nd; ++j)
        {
            val *= inembed[j];
            val += gidx[j];
        }

        int ghost_cell = 0;
        for (j = 0; j < nd; ++j)
            if (lidx[j] == 0 || lidx[j] == 3) ghost_cell = 1;

        if (ghost_cell)
        {
            CUDA_RE(in_3_h[i]) = 99.0;
            CUDA_IM(in_3_h[i]) = 123.0;
        }
        else
        {
            CUDA_RE(in_3_h[i]) = (double) val;
            CUDA_IM(in_3_h[i]) = 0.0;
        }
    }

    /* copy data to device */
    cudaMemcpy(in_3_d, in_3_h, sizeof(cuda_cpx_t)*size_4n_embed,cudaMemcpyDefault);

    dfft_plan plan_3_fw,plan_3_bw;
    dfft_cuda_create_plan(&plan_3_fw, nd, dim_glob, inembed, NULL, pdim, pidx, 0, 0, 0, MPI_COMM_WORLD, proc_map);
    dfft_cuda_check_errors(&plan_3_fw,1);
    dfft_cuda_create_plan(&plan_3_bw, nd, dim_glob, NULL, inembed, pdim, pidx, 0, 0, 0, MPI_COMM_WORLD, proc_map);
    dfft_cuda_check_errors(&plan_3_bw,1);

    int offset = 0;
    int n_ghost = 2;
    for (i = 0; i < nd; i++)
    {
        offset *= 4;
        offset += n_ghost/2;
    }

    /* forward transform */
    dfft_cuda_execute(in_3_d+offset, out_3_d, 0, &plan_3_fw);

    /* inverse transform */
    dfft_cuda_execute(out_3_d,in_3_d+offset, 1, &plan_3_bw);

    /* copy data back to host */
    cudaMemcpy(in_3_h, in_3_d, sizeof(cuda_cpx_t)*size_4n_embed,cudaMemcpyDefault);

    /* check results */
    for (i = 0; i < size_4n_embed; ++i)
    {
        //processor grid in column major
        int idx = i;

        // find local coordinate tuple
        int j;
        for (j = nd-1; j >= 0; --j)
        {
            int length = inembed[j];
            lidx[j] = idx % length;
            idx /= length;
        }

        // global coordinates in block distribution
        for (j = 0; j<nd; ++j)
            gidx[j] = lidx[j] + inembed[j]*pidx[j];

        int val=0;
        for (j = 0; j<nd; ++j)
        {
            val *= inembed[j];
            val += gidx[j];
        }

        int ghost_cell = 0;
        for (j = 0; j < nd; ++j)
            if (lidx[j] == 0 || lidx[j] == 3) ghost_cell = 1;

        if (ghost_cell)
        {
            //CHECK_CLOSE(CUDA_RE(in_3[i]),99.0,tol);
            //CHECK_CLOSE(CUDA_IM(in_3[i]), 123.0,tol);
        }
        else
        {
            CHECK_CLOSE(CUDA_RE(in_3_h[i]), (double) val*(double)p*(double)size_4n,tol);
            CHECK_SMALL(CUDA_IM(in_3_h[i]), abs_tol);
        }
    }

    cudaFree(in_3_d);
    cudaFree(out_3_d);
    free(in_3_h);
    free(lidx);
    free(gidx);

    dfft_cuda_destroy_plan(plan_3_fw);
    dfft_cuda_destroy_plan(plan_3_bw);

    free(pidx);
    free(pdim);
    free(dim_glob);
}
示例#12
0
/* Compare a 3d FFT against a reference FFT */
void test_distributed_fft_3d_compare()
{
    int s,p;
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &s);

    int nd = 3;
    int *pdim;
    pdim = (int *) malloc(sizeof(int)*nd);
    /* choose a decomposition */
    int r = powf(p,1.0/(double)nd)+0.5;
    int root = 1;
    while (root < r) root*=2;
    int ptot = 1;
    if (!s) printf("Processor grid: ");
    int i;
    for (i = 0; i < nd-1; ++i)
    {
        pdim[i] = (((ptot*root) > p) ? 1 : root);
        ptot *= pdim[i];
        if (!s) printf("%d x ",pdim[i]);
    }
    pdim[nd-1] = p/ptot;
    if (!s) printf("%d\n", pdim[nd-1]);

    /* determine processor index */
    int *pidx;
    pidx = (int*)malloc(nd*sizeof(int));
    int idx = s;
    for (i = nd-1; i >= 0; --i)
    {
        pidx[i] = idx % pdim[i];
        idx /= pdim[i];
    }

    int *dim_glob;
    dim_glob = (int *) malloc(sizeof(int)*nd);

    // Do a pdim[0]*4 x pdim[1]* 8 x pdim[2] * 16 FFT (powers of two)
    int local_nx = 4;
    int local_ny = 8;
    int local_nz = 16;
    dim_glob[0] = pdim[0]*local_nx;
    dim_glob[1] = pdim[1]*local_ny;
    dim_glob[2] = pdim[2]*local_nz;

    for (i = 0; i < nd-1; ++i)
        if (!s) printf("%d x ",dim_glob[i]);
    if (!s) printf("%d matrix\n", dim_glob[nd-1]);

    float scale = dim_glob[0]*dim_glob[1]*dim_glob[2];
    /* assume 0.5 sig digit loss per addition/twiddling (empirical)*/
    float sig_digits = 7.0-0.5*logf(scale)/logf(2.0);
    double tol = powf(10.0,-sig_digits);
    double abs_tol = 1.0*tol;
    printf("Testing with %f sig digits, rel precision %f, abs precision %f\n", sig_digits,  tol, abs_tol);

    kiss_fft_cpx *in_kiss;
    in_kiss = (kiss_fft_cpx *)malloc(sizeof(kiss_fft_cpx)*dim_glob[0]*dim_glob[1]*dim_glob[2]);

    srand(12345);

    // fill table with complex random numbers in row major order
    int x,y,z;
    int nx = dim_glob[0];
    int ny = dim_glob[1];
    int nz = dim_glob[2];
    for (x = 0; x < dim_glob[0]; ++x)
        for (y = 0; y < dim_glob[1]; ++y)
            for (z = 0; z < dim_glob[2]; ++z)
            {
                // KISS has column-major storage
                in_kiss[z+nz*(y+ny*x)].r = (float)rand()/(float)RAND_MAX;
                in_kiss[z+nz*(y+ny*x)].i =(float)rand()/(float)RAND_MAX;
            }

    kiss_fft_cpx *out_kiss;
    out_kiss = (kiss_fft_cpx *)malloc(sizeof(kiss_fft_cpx)*dim_glob[0]*dim_glob[1]*dim_glob[2]);

    // construct forward transform
    kiss_fftnd_cfg cfg = kiss_fftnd_alloc(dim_glob,3,0,NULL,NULL);

    // carry out conventional FFT
    kiss_fftnd(cfg, in_kiss, out_kiss);

    // compare to distributed FFT
    cuda_cpx_t * in_d, *in_h;
    cudaMalloc((void **)&in_d,sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz);
    in_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz);

    int x_local, y_local, z_local;
    for (x = 0; x < nx; ++x)
        for (y = 0; y < ny; ++y)
            for (z = 0; z < nz; ++z)
            {
                if (x>=pidx[0]*local_nx && x < (pidx[0]+1)*local_nx &&
                        y>=pidx[1]*local_ny && y < (pidx[1]+1)*local_ny &&
                        z>=pidx[2]*local_nz && z < (pidx[2]+1)*local_nz)
                {
                    x_local = x - pidx[0]*local_nx;
                    y_local = y - pidx[1]*local_ny;
                    z_local = z - pidx[2]*local_nz;

                    CUDA_RE(in_h[z_local+local_nz*(y_local+local_ny*x_local)]) =
                        in_kiss[z+nz*(y+ny*x)].r;
                    CUDA_IM(in_h[z_local+local_nz*(y_local+local_ny*x_local)]) =
                        in_kiss[z+nz*(y+ny*x)].i;
                }
            }

    cuda_cpx_t *out_d, *out_h;
    cudaMalloc((void **)&out_d,sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz);
    out_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz);

    dfft_plan plan;
    dfft_cuda_create_plan(&plan,3, dim_glob, NULL, NULL, pdim, pidx,0, 0, 0, MPI_COMM_WORLD, proc_map);
    dfft_cuda_check_errors(&plan,1);

    /* copy data to device */
    cudaMemcpy(in_d, in_h, sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz, cudaMemcpyDefault);

    // forward transform
    dfft_cuda_execute(in_d, out_d, 0, &plan);

    /* copy data back to host */
    cudaMemcpy(out_h, out_d, sizeof(cuda_cpx_t)*local_nx*local_ny*local_nz, cudaMemcpyDefault);

    // do comparison
    int n_wave_local = local_nx * local_ny * local_nz;
    for (i = 0; i < n_wave_local; ++i)
    {

        x_local = i / local_ny / local_nz;
        y_local = (i - x_local*local_ny*local_nz)/local_nz;
        z_local = i % local_nz;

        x = pidx[0]*local_nx + x_local;
        y = pidx[1]*local_ny + y_local;
        z = pidx[2]*local_nz + z_local;

        double re = CUDA_RE(out_h[i]);
        double im = CUDA_IM(out_h[i]);
        double re_kiss = out_kiss[z+nz*(y+ny*x)].r;
        double im_kiss = out_kiss[z+nz*(y+ny*x)].i;

        if (fabs(re_kiss) < abs_tol)
        {
            CHECK_SMALL(re,2*abs_tol);
        }
        else
        {
            CHECK_CLOSE(re,re_kiss, tol);
        }

        if (fabs(im_kiss) < abs_tol)
        {
            CHECK_SMALL(im,2*abs_tol);
        }
        else
        {
            CHECK_CLOSE(im, im_kiss, tol);
        }
    }
    free(in_kiss);
    free(out_kiss);
    cudaFree(out_d);
    cudaFree(in_d);
    free(in_h);
    free(out_h);
    free(pidx);
    free(dim_glob);
    dfft_cuda_destroy_plan(plan);
}
示例#13
0
/* Compare a 1d FFT against a reference FFT */
void test_distributed_fft_1d_compare(int n)
{
    int s,p;
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &s);

    int pdim[1];
    pdim[0]=p;

    /* determine processor index */
    int pidx[1];
    pidx[0]=s;

    float scale = n;
    /* assume 0.5 sig digit loss per addition/twiddling (empirical)*/
    float sig_digits = 7.0-0.5*logf(scale)/logf(2.0);
    double tol = powf(10.0,-sig_digits);
    double abs_tol = 1.0*tol;
    printf("Testing with %f sig digits, rel precision %f, abs precision %f\n", sig_digits,  tol, abs_tol);

    int dim_glob[1];
    dim_glob[0] = n;

    // Do a size n FFT (n = power of two)
    kiss_fft_cpx *in_kiss;
    in_kiss = (kiss_fft_cpx *)malloc(sizeof(kiss_fft_cpx)*n);

    srand(45678);

    // fill vector with complex random numbers in row major order
    int i;
    for (i = 0; i < n; ++i)
    {
        in_kiss[i].r = (float)rand()/(float)RAND_MAX;
        in_kiss[i].i =(float)rand()/(float)RAND_MAX;
    }

    kiss_fft_cpx *out_kiss;
    out_kiss = (kiss_fft_cpx *)malloc(sizeof(kiss_fft_cpx)*n);

    // construct forward transform
    kiss_fft_cfg cfg = kiss_fft_alloc(n,0,NULL,NULL);

    // carry out conventional FFT
    kiss_fft(cfg, in_kiss, out_kiss);

    // compare to distributed FFT
    cuda_cpx_t * in_d, *in_h;
    cudaMalloc((void **)&in_d,sizeof(cuda_cpx_t)*n/p);
    in_h = (cuda_cpx_t *) malloc(sizeof(cuda_cpx_t)*n/p);

    for (i = 0; i < n/p; ++i)
    {
        CUDA_RE(in_h[i]) = in_kiss[s*n/p+i].r;
        CUDA_IM(in_h[i]) = in_kiss[s*n/p+i].i;
    }

    cuda_cpx_t *out_d,*out_h;
    cudaMalloc((void **)&out_d,sizeof(cuda_cpx_t)*n/p);
    out_h = (cuda_cpx_t *)malloc(sizeof(cuda_cpx_t)*n/p);

    dfft_plan plan;
    dfft_cuda_create_plan(&plan,1, dim_glob, NULL, NULL, pdim, pidx,0, 0, 0, MPI_COMM_WORLD, proc_map);
    dfft_cuda_check_errors(&plan,1);

    /* copy data to device */
    cudaMemcpy(in_d, in_h, sizeof(cuda_cpx_t)*n/p, cudaMemcpyDefault);

    /* forward transform */
    dfft_cuda_execute(in_d, out_d, 0, &plan);

    /* copy data back to host */
    cudaMemcpy(out_h, out_d, sizeof(cuda_cpx_t)*n/p, cudaMemcpyDefault);

    /* do comparison */
    for (i = 0; i < n/p; ++i)
    {

        int j = s*n/p + i;

        double re = CUDA_RE(out_h[i]);
        double im = CUDA_IM(out_h[i]);
        double re_kiss = out_kiss[j].r;
        double im_kiss = out_kiss[j].i;

        if (fabs(re_kiss) < abs_tol)
        {
            CHECK_SMALL(re,2*abs_tol);
        }
        else
        {
            CHECK_CLOSE(re,re_kiss, tol);
        }

        if (fabs(im_kiss) < abs_tol)
        {
            CHECK_SMALL(im,2*abs_tol);
        }
        else
        {
            CHECK_CLOSE(im, im_kiss, tol);
        }
    }
    free(in_kiss);
    free(out_kiss);
    cudaFree(out_d);
    cudaFree(in_d);
    free(in_h);
    free(out_h);
    dfft_cuda_destroy_plan(plan);
}
示例#14
0
/**
 * Retrieve a single configuration \c widget for the \c camera.
 *
 * @param camera a #Camera
 * @param name the name of a configuration widget
 * @param widget a #CameraWidget
 * @param context a #GPContext
 * @return gphoto2 error code
 *
 * This \c widget will then contain the current and the possible values and the type.
 *
 */
int
gp_camera_get_single_config (Camera *camera, const char *name, CameraWidget **widget, GPContext *context)
{
	CameraWidget		*rootwidget, *child;
	CameraWidgetType	type;
	const char		*label;
	int			ret, ro;

	C_PARAMS (camera);
	CHECK_INIT (camera, context);

	if (camera->functions->get_single_config) {
		CHECK_RESULT_OPEN_CLOSE (camera, camera->functions->get_single_config (
						camera, name, widget, context), context);

		CAMERA_UNUSED (camera, context);
		return GP_OK;
	}

	if (!camera->functions->get_config) {
		gp_context_error (context, _("This camera does not provide any configuration options."));
		CAMERA_UNUSED (camera, context);
		return GP_ERROR_NOT_SUPPORTED;
	}
	/* emulate it ... */
	CHECK_OPEN (camera, context);

	ret = camera->functions->get_config ( camera, &rootwidget, context);
	if (ret != GP_OK) {
		CHECK_CLOSE (camera, context);
		CAMERA_UNUSED (camera, context);
		return ret;
	}
	ret = gp_widget_get_child_by_name (rootwidget, name, &child);
	if (ret != GP_OK) {
		gp_widget_free (rootwidget);
		CHECK_CLOSE (camera, context);
		CAMERA_UNUSED (camera, context);
		return ret;
	}

	/* We need to duplicate the widget, as we will free the widgettree */
	gp_widget_get_type (child, &type);
	gp_widget_get_label (child, &label);
	gp_widget_get_readonly (child, &ro);

	ret = gp_widget_new (type, label, widget);
	if (ret != GP_OK)
		goto out;
	gp_widget_set_name (*widget, name);
	gp_widget_set_readonly (*widget, ro);

	switch (type) {
        case GP_WIDGET_MENU:
        case GP_WIDGET_RADIO: {
		char *value;
		int i, nrofchoices;

		nrofchoices = gp_widget_count_choices (child);
		for (i = 0; i < nrofchoices; i++) {
			const char *choice;

			gp_widget_get_choice (child, i, &choice);
			gp_widget_add_choice (*widget, choice);
		}
		gp_widget_get_value (child, &value);
		gp_widget_set_value (*widget, value);
		break;
	}
        case GP_WIDGET_TEXT: {
		char *value;

		gp_widget_get_value (child, &value);
		gp_widget_set_value (*widget, value);
		break;
	}
        case GP_WIDGET_RANGE: {
		float value, rmin, rmax, rstep;

		gp_widget_get_range (child, &rmin, &rmax, &rstep);
		gp_widget_set_range (*widget, rmin, rmax, rstep);
		gp_widget_get_value (child, &value);
		gp_widget_set_value (*widget, &value);
                break;
	}
        case GP_WIDGET_TOGGLE:
        case GP_WIDGET_DATE: {
		int value;

		gp_widget_get_value (child, &value);
		gp_widget_set_value (*widget, &value);
                break;
	}
        case GP_WIDGET_BUTTON:
        case GP_WIDGET_SECTION:
        case GP_WIDGET_WINDOW:
        default:
                ret = GP_ERROR_BAD_PARAMETERS;
		break;
	}
out:
	gp_widget_free (rootwidget);
	CHECK_CLOSE (camera, context);
	CAMERA_UNUSED (camera, context);
	return ret;
}
示例#15
0
/**
 * Set a single configuration \c widget for the \c camera.
 *
 * @param camera a #Camera
 * @param name the name of a configuration widget
 * @param widget a #CameraWidget
 * @param context a #GPContext
 * @return gphoto2 error code
 *
 * This \c widget contains the new value of the widget to set.
 *
 */
int
gp_camera_set_single_config (Camera *camera, const char *name, CameraWidget *widget, GPContext *context)
{
	CameraWidget		*rootwidget, *child;
	CameraWidgetType	type;
	int			ret;

	C_PARAMS (camera);
	CHECK_INIT (camera, context);

	if (camera->functions->set_single_config) {
		CHECK_RESULT_OPEN_CLOSE (camera, camera->functions->set_single_config (
						camera, name, widget, context), context);

		CAMERA_UNUSED (camera, context);
		return GP_OK;
	}

	if (!camera->functions->set_config) {
		gp_context_error (context, _("This camera does not provide any configuration options."));
		CAMERA_UNUSED (camera, context);
		return GP_ERROR_NOT_SUPPORTED;
	}
	/* emulate single config with the full tree */
	CHECK_OPEN (camera, context);

	ret = camera->functions->get_config ( camera, &rootwidget, context);
	if (ret != GP_OK) {
		CHECK_CLOSE (camera, context);
		CAMERA_UNUSED (camera, context);
		return ret;
	}
	ret = gp_widget_get_child_by_name (rootwidget, name, &child);
	if (ret != GP_OK) {
		gp_widget_free (rootwidget);
		CHECK_CLOSE (camera, context);
		CAMERA_UNUSED (camera, context);
		return ret;
	}

	gp_widget_get_type (child, &type);
	ret = GP_OK;
	switch (type) {
        case GP_WIDGET_MENU:
        case GP_WIDGET_RADIO:
        case GP_WIDGET_TEXT: {
		char *value;

		gp_widget_get_value (widget, &value);
		gp_widget_set_value (child, value);
		break;
	}
        case GP_WIDGET_RANGE: {
		float value;

		gp_widget_get_value (widget, &value);
		gp_widget_set_value (child, &value);
                break;
	}
        case GP_WIDGET_TOGGLE:
        case GP_WIDGET_DATE: {
		int value;

		gp_widget_get_value (widget, &value);
		gp_widget_set_value (child, &value);
                break;
	}
        case GP_WIDGET_BUTTON:
        case GP_WIDGET_SECTION:
        case GP_WIDGET_WINDOW:
        default:
                ret = GP_ERROR_BAD_PARAMETERS;
		break;
	}
	gp_widget_set_changed (child, 1);

	if (ret == GP_OK)
		ret = camera->functions->set_config (camera, rootwidget, context);
	gp_widget_free (rootwidget);
	CHECK_CLOSE (camera, context);
	CAMERA_UNUSED (camera, context);
	return ret;
}