Esempio n. 1
0
static PyObject* Update_Skin(PyObject *self, PyObject *args)
{
	int num;
	int ret;
	if(!PyArg_ParseTuple(args, "i", &num))return NULL;
	
	ret=update_skin(&g_model[num]);
	return Py_BuildValue("i", ret);
}
STKUNIT_UNIT_TEST( PerformanceTestSkinning, large_cube)
{
  stk::ParallelMachine pm = MPI_COMM_WORLD;

  const size_t p_size = stk::parallel_machine_size(pm);
  const size_t p_rank = stk::parallel_machine_rank(pm);

  // Every processor will be involved in detachment and skin-update up to 500 processors.
  // This puts 5000 elements on each process unless we are running with STL
  // in debug mode in which case we shrink the problem down in order
  // to keep things running in a reasonable amount of time.
#ifdef _GLIBCXX_DEBUG
  const size_t NX = p_size*10, NY = 4, NZ = 5;
#else
  const size_t NX = p_size*10, NY = 20, NZ = 25;
#endif

  /* timings[0] = create mesh
   * timings[1] = intial skin mesh
   * timings[2] = detach mesh
   * timings[3] = delete skin
   * timings[4] = reskin mesh
   * timings[5] = sum(timings[0:4])
   */
  double timings[6] = {0};
  double start_time = 0;

  //recreate skin
  for ( int test_run = 0; test_run < 4; ++test_run) {
    //create the mesh

    start_time = stk::wall_time();
    stk::mesh::fixtures::HexFixture fixture(pm,NX,NY,NZ);
    const EntityRank element_rank = fixture.m_fem_meta.element_rank();
    const EntityRank side_rank = fixture.m_fem_meta.side_rank();

    stk::mesh::fem::FEMMetaData & fem_meta = fixture.m_fem_meta;
    stk::mesh::BulkData & mesh = fixture.m_bulk_data;

    stk::mesh::Part & skin_part = fem_meta.declare_part("skin_part");
    fem_meta.commit();

    fixture.generate_mesh();
    timings[0] = stk::wall_dtime(start_time);

    //intial skin of the mesh
    start_time = stk::wall_time();
    stk::mesh::skin_mesh(mesh, element_rank, &skin_part);
    timings[1] = stk::wall_dtime(start_time);

    stk::mesh::EntityVector entities_to_separate;

    if ( test_run < 2) {
      //detach 1/3 of the mesh
      size_t num_detached_this_proc = 0;
      for (size_t ix=NX/3; ix < 2*NX/3; ++ix) {
      for (size_t iy=0; iy < NY; ++iy) {
      for (size_t iz=0; iz < NZ; ++iz) {
        stk::mesh::Entity * element = fixture.elem(ix,iy,iz);
        if (element != NULL && element->owner_rank() == mesh.parallel_rank()) {
          entities_to_separate.push_back(element);
          num_detached_this_proc++;
        }
      }
      }
      }
      STKUNIT_EXPECT_TRUE( num_detached_this_proc > 0u );
    } else {
      //detach middle of the mesh
      for (size_t ix=NX/2; ix < NX/2+1; ++ix) {
      for (size_t iy=NY/2; iy < NY/2+1; ++iy) {
      for (size_t iz=NZ/2; iz < NZ/2+1; ++iz) {
        stk::mesh::Entity * element = fixture.elem(ix,iy,iz);
        if (element != NULL && element->owner_rank() == mesh.parallel_rank()) {
          entities_to_separate.push_back(element);
        }
      }
      }
      }
    }

    start_time = stk::wall_time();
    separate_and_skin_mesh(
        fem_meta,
        mesh,
        skin_part,
        entities_to_separate
        );
    timings[2] = stk::wall_dtime(start_time);

    if (test_run%2 == 0) { // delete the skin
      start_time = stk::wall_time();
      delete_skin( mesh, skin_part, side_rank );
      timings[3] = stk::wall_dtime(start_time);

      //reskin the entire mesh
      start_time = stk::wall_time();
      stk::mesh::skin_mesh( mesh, element_rank, &skin_part);
      timings[4] = stk::wall_dtime(start_time);
    }
    else { //update the skin
      timings[3] = 0;

      //update the skin of the mesh
      start_time = stk::wall_time();
      update_skin( mesh, &skin_part, element_rank);
      timings[4] = stk::wall_dtime(start_time);
    }

    //total the timings
    timings[5] = 0;
    for (int i=0; i <5; ++i) {
      timings[5] += timings[i];
    }

    stk::all_reduce(pm, stk::ReduceMax<5>(timings));

    if (p_rank == 0) {
      std::cout << "\n\n";
      switch (test_run) {
        case 0:
          std::cout << "Recreate entire skin after detaching 1/3 of the mesh:\n";
          break;
        case 1:
          std::cout << "Update skin after detaching 1/3 of the mesh:\n";
          break;
        case 2:
          std::cout << "Recreate entire skin after detaching middle of the mesh:\n";
          break;
        case 3:
          std::cout << "Update skin after detaching middle of the mesh:\n";
          break;
      }

      std::cout << "Num procs: " << p_size << "\n";
      std::cout << "Mesh size: " << NX << 'x' << NY << 'x' << NZ << " = " << NX*NY*NZ << " elements\n";
      std::cout << "Total time: "     << timings[5] << "\n";
      std::cout << "\tCreate mesh: "  << timings[0] << "\n";
      std::cout << "\tInitial skin: " << timings[1] << "\n";
      std::cout << "\tDetach mesh: "  << timings[2] << "\n";
      std::cout << "\tDelete skin: "  << timings[3] << "\n";
      std::cout << "\tReskin:      "  << timings[4] << "\n";
      std::cout << "\n\n";
    }

    size_t num_skin_entities = count_skin_entities(mesh, skin_part, side_rank );

    stk::all_reduce(pm, stk::ReduceSum<1>(&num_skin_entities));

    size_t expected_num_skin;

    if ( test_run < 2) {
      expected_num_skin = 2*(NX*NY + NX*NZ + 3*NY*NZ);
    } else {
      expected_num_skin = 2*(NX*NY + NX*NZ + NY*NZ) + 12;
    }

    STKUNIT_EXPECT_EQUAL( num_skin_entities, expected_num_skin );
  }
}
Esempio n. 3
0
TEST( skinning_large_cube, skinning_large_cube)
{
  stk::ParallelMachine pm = MPI_COMM_WORLD;

  const size_t p_size = stk::parallel_machine_size(pm);
  const size_t p_rank = stk::parallel_machine_rank(pm);

  // Every processor will be involved in detachment and skin-update up to 500 processors.
  // This puts 5000 elements on each process unless we are running with STL
  // in debug mode in which case we shrink the problem down in order
  // to keep things running in a reasonable amount of time.
#ifdef _GLIBCXX_DEBUG
  const size_t NX = p_size*10, NY = 4, NZ = 5;
#else
  const size_t NX = p_size*100, NY = 100, NZ = 100;
#endif

  static const int TIMER_COUNT = 6;
  /* timings[0] = create mesh
   * timings[1] = intial skin mesh
   * timings[2] = detach mesh
   * timings[3] = delete skin
   * timings[4] = reskin mesh
   * timings[5] = sum(timings[0:4])
   */
  double timings[TIMER_COUNT] = {0};
  double timing_sums[TIMER_COUNT] = {0};
  const char* timer_names[TIMER_COUNT] = {"Create mesh", "Initial skin", "Detach mesh", "Delete skin", "Reskin", "Total time"};
  double start_time = 0;
  size_t memory_max[2] = {0};
  const char* memory_names[2] = {"Current memory", "Memory high water"};

  //recreate skin
  for ( int test_run = 0; test_run < 4; ++test_run) {
    //create the mesh

    start_time = stk::wall_time();
    stk::mesh::fixtures::HexFixture fixture(pm,NX,NY,NZ);
    const EntityRank element_rank = stk::topology::ELEMENT_RANK;
    const EntityRank side_rank = fixture.m_meta.side_rank();

    stk::mesh::MetaData & fem_meta = fixture.m_meta;
    stk::mesh::BulkData & mesh = fixture.m_bulk_data;

    stk::mesh::Part & skin_part = fem_meta.declare_part("skin_part");
    fem_meta.commit();

    fixture.generate_mesh();
    timings[0] = stk::wall_dtime(start_time);

    //intial skin of the mesh
    start_time = stk::wall_time();
    {
      stk::mesh::PartVector add_parts(1,&skin_part);
      stk::mesh::skin_mesh(mesh, add_parts);
    }
    timings[1] = stk::wall_dtime(start_time);

    stk::mesh::EntityVector entities_to_separate;

    if ( test_run < 2) {
      //detach 1/3 of the mesh
      size_t num_detached_this_proc = 0;
      for (size_t ix=NX/3; ix < 2*NX/3; ++ix) {
      for (size_t iy=0; iy < NY; ++iy) {
      for (size_t iz=0; iz < NZ; ++iz) {
        stk::mesh::Entity element = fixture.elem(ix,iy,iz);
        if (mesh.is_valid(element) && mesh.parallel_owner_rank(element) == mesh.parallel_rank()) {
          entities_to_separate.push_back(element);
          num_detached_this_proc++;
        }
      }
      }
      }
      EXPECT_TRUE( num_detached_this_proc > 0u );
    } else {
      //detach middle of the mesh
      for (size_t ix=NX/2; ix < NX/2+1; ++ix) {
      for (size_t iy=NY/2; iy < NY/2+1; ++iy) {
      for (size_t iz=NZ/2; iz < NZ/2+1; ++iz) {
        stk::mesh::Entity element = fixture.elem(ix,iy,iz);
        if (mesh.is_valid(element) && mesh.parallel_owner_rank(element) == mesh.parallel_rank()) {
          entities_to_separate.push_back(element);
        }
      }
      }
      }
    }

    start_time = stk::wall_time();
    separate_and_skin_mesh(
        fem_meta,
        mesh,
        skin_part,
        entities_to_separate
        );
    timings[2] = stk::wall_dtime(start_time);

    if (test_run%2 == 0) { // delete the skin
      start_time = stk::wall_time();
      delete_skin( mesh, skin_part, side_rank );
      timings[3] = stk::wall_dtime(start_time);

      //reskin the entire mesh
      start_time = stk::wall_time();
      {
        stk::mesh::PartVector add_parts(1,&skin_part);
        stk::mesh::skin_mesh( mesh, add_parts);
      }
      timings[4] = stk::wall_dtime(start_time);
    }
    else { //update the skin
      timings[3] = 0;

      //update the skin of the mesh
      start_time = stk::wall_time();
      update_skin( mesh, &skin_part, element_rank);
      timings[4] = stk::wall_dtime(start_time);
    }

    //total the timings
    timings[5] = 0;
    for (int i=0; i <5; ++i) {
      timings[5] += timings[i];
    }

    size_t mem_now = 0, mem_hwm = 0;
    stk::get_memory_usage(mem_now, mem_hwm);

    stk::all_reduce(pm, stk::ReduceMax<5>(timings));
    stk::all_reduce(pm, stk::ReduceMax<1>(&mem_now));
    stk::all_reduce(pm, stk::ReduceMax<1>(&mem_hwm));

    if (mem_now > memory_max[0]) {
      memory_max[0] = mem_now;
    }
    if (mem_hwm > memory_max[1]) {
      memory_max[1] = mem_hwm;
    }

    //compute sums
    for (int i=0; i<TIMER_COUNT; ++i) {
      timing_sums[i] += timings[i];
    }

    if (p_rank == 0) {
      std::cout << "\n\n";
      switch (test_run) {
        case 0:
          std::cout << "Recreate entire skin after detaching 1/3 of the mesh:\n";
          break;
        case 1:
          std::cout << "Update skin after detaching 1/3 of the mesh:\n";
          break;
        case 2:
          std::cout << "Recreate entire skin after detaching middle of the mesh:\n";
          break;
        case 3:
          std::cout << "Update skin after detaching middle of the mesh:\n";
          break;
      }

      std::cout << "Num procs: " << p_size << "\n";
      std::cout << "Mesh size: " << NX << 'x' << NY << 'x' << NZ << " = " << NX*NY*NZ << " elements\n";
      std::cout << "Total time: "     << timings[5] << "\n";
      std::cout << "\tCreate mesh: "  << timings[0] << "\n";
      std::cout << "\tInitial skin: " << timings[1] << "\n";
      std::cout << "\tDetach mesh: "  << timings[2] << "\n";
      std::cout << "\tDelete skin: "  << timings[3] << "\n";
      std::cout << "\tReskin:      "  << timings[4] << "\n";
      std::cout << "\n\n";
    }

    size_t num_skin_entities = count_skin_entities(mesh, skin_part, side_rank );

    stk::all_reduce(pm, stk::ReduceSum<1>(&num_skin_entities));

    size_t expected_num_skin = 0;

    if ( test_run < 2) {
      expected_num_skin = 2*(NX*NY + NX*NZ + 3*NY*NZ);
    } else {
      expected_num_skin = 2*(NX*NY + NX*NZ + NY*NZ) + 12;
    }

    EXPECT_EQ( num_skin_entities, expected_num_skin );
  }

  if (p_rank == 0) {
    stk::print_timers_and_memory(&timer_names[0], &timing_sums[0], TIMER_COUNT, &memory_names[0], &memory_max[0], 2);
  }

  stk::parallel_print_time_without_output_and_hwm(pm, timings[5]);
}