diff --git a/src/describe.cpp b/src/describe.cpp index edd536158..b04a0da0c 100644 --- a/src/describe.cpp +++ b/src/describe.cpp @@ -1,15 +1,73 @@ #include #include +#include +#include +#include +#include +template +void printTagInfo(Omega_h::Mesh mesh, std::ostringstream& oss, int dim, int tag, std::string type) { + auto tagbase = mesh.get_tag(dim, tag); + auto array = Omega_h::as(tagbase)->array(); + + Omega_h::Real min = get_min(array); + Omega_h::Real max = get_max(array); + + oss << std::setw(18) << std::left << tagbase->name().c_str() + << std::setw(5) << std::left << dim + << std::setw(7) << std::left << type + << std::setw(5) << std::left << tagbase->ncomps() + << std::setw(10) << std::left << min + << std::setw(10) << std::left << max + << "\n"; +} + +template +int getNumEq(Omega_h::Mesh mesh, std::string tagname, int dim, int value) { + auto array = mesh.get_array(dim, tagname); + auto each_eq_to = Omega_h::each_eq_to(array, value); + return Omega_h::get_sum(each_eq_to); +} + +void printMPIChar(std::string output, int comm_size, int comm_rank) { +#ifdef OMEGA_H_USE_MPI + if (comm_rank) { + MPI_Send(output.c_str(), output.size(), MPI_CHAR, 0, 0, MPI_COMM_WORLD); + } else for (int sender=1; sender < comm_size; sender++) { + std::cout << output; + MPI_Status status; + MPI_Probe(sender, 0, MPI_COMM_WORLD, &status); + int count; + MPI_Get_count(&status, MPI_CHAR, &count); + char buf [count]; + MPI_Recv(&buf, count, MPI_CHAR, sender, 0, MPI_COMM_WORLD, &status); + std::cout << buf; + } +#else + std::cout << output; +#endif +} int main(int argc, char** argv) { auto lib = Omega_h::Library(&argc, &argv); auto comm = lib.world(); - Omega_h::Mesh mesh = Omega_h::read_mesh_file(argv[1], lib.world()); - auto verbose = false; - if (argc == 3) verbose = (std::string(argv[2]) == "on"); + Omega_h::CmdLine cmdline; + cmdline.add_arg("mesh.osh"); + cmdline.add_flag("-v", "verbose"); + auto& tagInfoFlag = cmdline.add_flag("--tag-info", "space seperated \"name dim value\""); + tagInfoFlag.add_arg("name"); + tagInfoFlag.add_arg("dim"); + tagInfoFlag.add_arg("value"); + if (!cmdline.parse(comm, &argc, argv) || + !Omega_h::CmdLine::check_empty(comm, argc, argv)) { + cmdline.show_help(comm, argv); + return -1; + } + + std::string meshPath = cmdline.get("mesh.osh"); + Omega_h::Mesh mesh = Omega_h::read_mesh_file(meshPath, lib.world()); const int rank = comm->rank(); @@ -34,33 +92,28 @@ int main(int argc, char** argv) for(int dim=0; dim < mesh.dim(); dim++) oss << "(" << dim << ", " << counts[dim] << ", " << imb[dim] << ")\n"; - oss << "\nTags by Dimension: (Dim, Tag, Size per Entity)\n"; + oss << "\nTag Properties by Dimension: (Name, Dim, Type, Number of Components, Min. Value, Max. Value)\n"; for (int dim=0; dim < mesh.dim(); dim++) for (int tag=0; tag < mesh.ntags(dim); tag++) { auto tagbase = mesh.get_tag(dim, tag); - int size; if (tagbase->type() == OMEGA_H_I8) - size = mesh.get_tag(dim, tagbase->name())->array().size(); + printTagInfo(mesh, oss, dim, tag, "I8"); if (tagbase->type() == OMEGA_H_I32) - size = mesh.get_tag(dim, tagbase->name())->array().size(); + printTagInfo(mesh, oss, dim, tag, "I32"); if (tagbase->type() == OMEGA_H_I64) - size = mesh.get_tag(dim, tagbase->name())->array().size(); + printTagInfo(mesh, oss, dim, tag, "I64"); if (tagbase->type() == OMEGA_H_F64) - size = mesh.get_tag(dim, tagbase->name())->array().size(); - - size /= mesh.nents(dim); - oss << "(" << dim << ", " << tagbase->name().c_str() << ", " << size << ")\n"; + printTagInfo(mesh, oss, dim, tag, "F64"); } std::cout << oss.str(); } - if(verbose) { + if(cmdline.parsed("-v")) { comm->barrier(); // write the per-part data at the end if(!rank) { std::cout << "\nPer Rank Mesh Entity Count: (Rank: Entity Count by Dim <0,1,2,3>)\n"; } - comm->barrier(); // write the per-part data at the end oss.str(""); // clear the stream std::array counts = {0,0,0,0}; @@ -70,7 +123,39 @@ int main(int argc, char** argv) << counts[1] << ", " << counts[2] << ", " << counts[3] << ")\n"; - std::cout << oss.str(); + printMPIChar(oss.str(), comm->size(), rank); + + comm->barrier(); + if (!rank) std::cout << "\nPer Rank Mesh Entity Owned: (Rank: Entity Owned by Dim <0,1,2,3>)\n"; + oss.str(""); // clear the stream + for (int dim=0; dim < mesh.dim(); dim++) + counts[dim] = mesh.nents_owned(dim); + oss << "(" << rank << ": " << counts[0] << ", " + << counts[1] << ", " + << counts[2] << ", " + << counts[3] << ")\n"; + printMPIChar(oss.str(), comm->size(), rank); + } + + if (cmdline.parsed("--tag-info")) { + std::string name = cmdline.get("--tag-info", "name"); + int dim = cmdline.get("--tag-info", "dim"); + int value = cmdline.get("--tag-info", "value"); + auto tagbase = mesh.get_tagbase(dim, name); + int numEq = 0; + if (tagbase->type() == OMEGA_H_I8) + numEq = getNumEq(mesh, name, dim, value); + if (tagbase->type() == OMEGA_H_I32) + numEq = getNumEq(mesh, name, dim, value); + if (tagbase->type() == OMEGA_H_I64) + numEq = getNumEq(mesh, name, dim, value); + if (tagbase->type() == OMEGA_H_F64) + numEq = getNumEq(mesh, name, dim, value); + + if (!rank) std::cout << "\nInput: (" << name << " " << dim << " " << value <<"), Output: (Rank, Num Entities Equal to Value)\n"; + comm->barrier(); + std::cout << "(" << rank << ", " << numEq << ")\n"; + return 0; } return 0; }