Files
rocm-systems/examples/lulesh/lulesh-viz.cc
T
Jonathan R. Madsen 39f17ae8b8 rocm-smi and KokkosTools support (#23)
* renamed omnitrace_thread_data to thread_data

* initial implementation

* Numerous fixes and updates

- Updated timemory submodule
- Updated perfetto submodule (pulls in fixes for TRACE_EVENT)
- pthread_gotcha only after omnitrace_init_tooling
- omnitrace banner
- config settings for rocm-smi freq and devices
- critical_trace::get_entries
- OMNITRACE_BASIC_PRINT
- rocm_smi perfetto category
- redirect roctracer warnings for ROCm 4.5.0
- property specializations for rocm-smi components
- units fixes data_tracker types
- roctracer entries for pthread_create and start_thread
- omnitrace-avail defaults to settings, not components
- settings have conforming names
- settings warn about duplicates
- ptl named threads
- decreased max freq for sampler SIGALRM
- rocm-smi names thread
- rocm-smi avoids call to hipGetDeviceCount
- name roctracer activity callback threads
- fixed binary rewrite test output names

* Update lulesh example

- supports non-UVM GPU

* Lulesh tweaks + formatting

* KokkosP + Mode + Roctracer sampling deadlock fix

- kokkosp support
- omnitrace_init_library
- config::print_settings()
- config::get_mode()
- omnitrace::Mode
- omnitrace-avail improvements (removes settings)
- handle get_verbose() < 0
- disable dyninst InstrStackFrames by default
- handle perf_event_paranoid > 1 by disabling PAPI
- SIGALRM max freq to 5.0
- Name threads
- rocm-smi handles get_use_perfetto() and get_use_timemory()
- HSA_ENABLE_INTERRUPT=0 when roctracer + sampling (fixes deadlock)

* Tests, API renaming, roctracer

- disable renaming of thread 0
- verbprintf_bare
- enable dyninst merge tramp
- tweaked some omnitrace exe verbose levels
- reworked roctracer::setup and roctracer::shutdown
- rocm_smi::data::poll checks get_state()
- omnitrace_trace_finalize -> omnitrace_finalize
- omnitrace_trace_init -> omnitrace_init
- omnitrace_trace_set_env -> omnitrace_set_env
- omnitrace_trace_set_mpi -> omnitrace_set_mpi
- sampling mode does not disable timemory
- disable roctracer before shutting down rocm-smi
- lulesh tests w/ and w/o kokkosp
- lulesh tests for perfetto only
    - with --dynamic-callsites --traps --allow-overlapping
- lulesh tests for timemory only
    - with --stdlib --dynamic-callsites --traps --allow-overlapping

* Update timemory submodule

- fix for TIMEMORY_PROPERTY_SPECIALIZATION

* get_verbose() handling + timemory submodule update

- Findroctracer.cmake uses find_package(hsakmt)

* Stability fixes + rework roctracer + perfetto

- reworked roctracer start up
- critical_trace perfetto basic values
- perfetto sampling category
- sampler checks signals
- peak_rss in sampling
- pthread_gotcha::shutdown()
- rocm_smi::device_count()
- HSA_TOOLS_LIB is set
- HSA_ENABLE_INTERRUPT in omnitrace exe
- omnitrace exe verbosity level changes
- Avoid instrumenting Impl ns in Kokkos
- gpu::device_count prefers rocm_smi instead of hip
- ptl blocks signals
- fixed pthread_gotcha roctracer_data values
- removed runtime-instrument-sampling tests
- timemory submodule update

* cmake formatting

* timemory + roctracer updates

- fix timemory issue with papi_common
- fix timemory issue with units
- define roctracer::is_setup()

* Miscellaneous tweaks

- Disable sampling during runtime instrument
- Fixed warnings about dynamic callsites
- Fixed backtrace output when timemory disabled
- Test tweaks

* cmake-format

* omnitrace_target_compile_definitions

* timemory submodule update

* config, omnitrace, State, mpi_gotcha updates

- use OMNITRACE_THROW instead of direct throw
- is_attached()
- is_binary_rewrite()
- get_is_continuous_integration()
- get_debug_init()
- get_debug_finalize()
- max_thread_bookmarks default to 1
- State::Init
- app_thread oneTimeCode
- runtime instrumentation uses waitpid
- fixed init_names
- include main in MPI runs
- fixed sampling setup when disabled
- reworked mpi_gotcha
- disabled critical trace in transpose test

* cmake-format

* handle rocm_smi::device_count() exception

* CI timeouts

* Re-enable runtime-instrument + sampling
2022-02-08 17:42:17 -06:00

422 lines
12 KiB
C++

#include "lulesh.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef VIZ_MESH
# ifdef __cplusplus
extern "C"
{
# endif
# include "silo.h"
# if USE_MPI
# include "pmpio.h"
# endif
# ifdef __cplusplus
}
# endif
// Function prototypes
static void
DumpDomainToVisit(DBfile* db, Domain& domain, int myRank);
static
# if USE_MPI
// For some reason, earlier versions of g++ (e.g. 4.2) won't let me
// put the 'static' qualifier on this prototype, even if it's done
// consistently in the prototype and definition
void
DumpMultiblockObjects(DBfile* db, PMPIO_baton_t* bat, char basename[], int numRanks);
// Callback prototypes for PMPIO interface (only useful if we're
// running parallel)
static void*
LULESH_PMPIO_Create(const char* fname, const char* dname, void* udata);
static void*
LULESH_PMPIO_Open(const char* fname, const char* dname, PMPIO_iomode_t ioMode,
void* udata);
static void
LULESH_PMPIO_Close(void* file, void* udata);
# else
void
DumpMultiblockObjects(DBfile* db, char basename[], int numRanks);
# endif
/**********************************************************************/
void
DumpToVisit(Domain& domain, int numFiles, int myRank, int numRanks)
{
char subdirName[32];
char basename[32];
DBfile* db;
sprintf(basename, "lulesh_plot_c%d", domain.cycle());
sprintf(subdirName, "data_%d", myRank);
# if USE_MPI
PMPIO_baton_t* bat =
PMPIO_Init(numFiles, PMPIO_WRITE, MPI_COMM_WORLD, 10101, LULESH_PMPIO_Create,
LULESH_PMPIO_Open, LULESH_PMPIO_Close, NULL);
int myiorank = PMPIO_GroupRank(bat, myRank);
char fileName[64];
if(myiorank == 0)
strcpy(fileName, basename);
else
sprintf(fileName, "%s.%03d", basename, myiorank);
db = (DBfile*) PMPIO_WaitForBaton(bat, fileName, subdirName);
DumpDomainToVisit(db, domain, myRank);
// Processor 0 writes out bit of extra data to its file that
// describes how to stitch all the pieces together
if(myRank == 0)
{
DumpMultiblockObjects(db, bat, basename, numRanks);
}
PMPIO_HandOffBaton(bat, db);
PMPIO_Finish(bat);
# else
db = (DBfile*) DBCreate(basename, DB_CLOBBER, DB_LOCAL, NULL, DB_HDF5X);
if(db)
{
DBMkDir(db, subdirName);
DBSetDir(db, subdirName);
DumpDomainToVisit(db, domain, myRank);
DumpMultiblockObjects(db, basename, numRanks);
}
else
{
printf("Error writing out viz file - rank %d\n", myRank);
}
# endif
}
/**********************************************************************/
static void
DumpDomainToVisit(DBfile* db, Domain& domain, int myRank)
{
int ok = 0;
/* Create an option list that will give some hints to VisIt for
* printing out the cycle and time in the annotations */
DBoptlist* optlist;
/* Write out the mesh connectivity in fully unstructured format */
int shapetype[1] = { DB_ZONETYPE_HEX };
int shapesize[1] = { 8 };
int shapecnt[1] = { domain.numElem() };
int* conn = Allocate<int>(domain.numElem() * 8);
int ci = 0;
for(int ei = 0; ei < domain.numElem(); ++ei)
{
Index_t* elemToNode = domain.nodelist(ei);
for(int ni = 0; ni < 8; ++ni)
{
conn[ci++] = elemToNode[ni];
}
}
ok += DBPutZonelist2(db, "connectivity", domain.numElem(), 3, conn,
domain.numElem() * 8, 0, 0, 0, /* Not carrying ghost zones */
shapetype, shapesize, shapecnt, 1, NULL);
Release<int>(&conn);
/* Write out the mesh coordinates associated with the mesh */
const char* coordnames[3] = { "X", "Y", "Z" };
float* coords[3];
coords[0] = Allocate<float>(domain.numNode());
coords[1] = Allocate<float>(domain.numNode());
coords[2] = Allocate<float>(domain.numNode());
for(int ni = 0; ni < domain.numNode(); ++ni)
{
coords[0][ni] = float(domain.x(ni));
coords[1][ni] = float(domain.y(ni));
coords[2][ni] = float(domain.z(ni));
}
optlist = DBMakeOptlist(2);
ok += DBAddOption(optlist, DBOPT_DTIME, &domain.time());
ok += DBAddOption(optlist, DBOPT_CYCLE, &domain.cycle());
ok += DBPutUcdmesh(db, "mesh", 3, (char**) &coordnames[0], (float**) coords,
domain.numNode(), domain.numElem(), "connectivity", 0, DB_FLOAT,
optlist);
ok += DBFreeOptlist(optlist);
Release<float>(&coords[2]);
Release<float>(&coords[1]);
Release<float>(&coords[0]);
/* Write out the materials */
int* matnums = Allocate<int>(domain.numReg());
int dims[1] = { domain.numElem() }; // No mixed elements
for(int i = 0; i < domain.numReg(); ++i)
matnums[i] = i + 1;
ok += DBPutMaterial(db, "regions", "mesh", domain.numReg(), matnums,
domain.regNumList(), dims, 1, NULL, NULL, NULL, NULL, 0, DB_FLOAT,
NULL);
Release<int>(&matnums);
/* Write out pressure, energy, relvol, q */
float* e = Allocate<float>(domain.numElem());
for(int ei = 0; ei < domain.numElem(); ++ei)
{
e[ei] = float(domain.e(ei));
}
ok += DBPutUcdvar1(db, "e", "mesh", e, domain.numElem(), NULL, 0, DB_FLOAT,
DB_ZONECENT, NULL);
Release<float>(&e);
float* p = Allocate<float>(domain.numElem());
for(int ei = 0; ei < domain.numElem(); ++ei)
{
p[ei] = float(domain.p(ei));
}
ok += DBPutUcdvar1(db, "p", "mesh", p, domain.numElem(), NULL, 0, DB_FLOAT,
DB_ZONECENT, NULL);
Release<float>(&p);
float* v = Allocate<float>(domain.numElem());
for(int ei = 0; ei < domain.numElem(); ++ei)
{
v[ei] = float(domain.v(ei));
}
ok += DBPutUcdvar1(db, "v", "mesh", v, domain.numElem(), NULL, 0, DB_FLOAT,
DB_ZONECENT, NULL);
Release<float>(&v);
float* q = Allocate<float>(domain.numElem());
for(int ei = 0; ei < domain.numElem(); ++ei)
{
q[ei] = float(domain.q(ei));
}
ok += DBPutUcdvar1(db, "q", "mesh", q, domain.numElem(), NULL, 0, DB_FLOAT,
DB_ZONECENT, NULL);
Release<float>(&q);
/* Write out nodal speed, velocities */
float* zd = Allocate<float>(domain.numNode());
float* yd = Allocate<float>(domain.numNode());
float* xd = Allocate<float>(domain.numNode());
float* speed = Allocate<float>(domain.numNode());
for(int ni = 0; ni < domain.numNode(); ++ni)
{
xd[ni] = float(domain.xd(ni));
yd[ni] = float(domain.yd(ni));
zd[ni] = float(domain.zd(ni));
speed[ni] =
float(sqrt((xd[ni] * xd[ni]) + (yd[ni] * yd[ni]) + (zd[ni] * zd[ni])));
}
ok += DBPutUcdvar1(db, "speed", "mesh", speed, domain.numNode(), NULL, 0, DB_FLOAT,
DB_NODECENT, NULL);
Release<float>(&speed);
ok += DBPutUcdvar1(db, "xd", "mesh", xd, domain.numNode(), NULL, 0, DB_FLOAT,
DB_NODECENT, NULL);
Release<float>(&xd);
ok += DBPutUcdvar1(db, "yd", "mesh", yd, domain.numNode(), NULL, 0, DB_FLOAT,
DB_NODECENT, NULL);
Release<float>(&yd);
ok += DBPutUcdvar1(db, "zd", "mesh", zd, domain.numNode(), NULL, 0, DB_FLOAT,
DB_NODECENT, NULL);
Release<float>(&zd);
if(ok != 0)
{
printf("Error writing out viz file - rank %d\n", myRank);
}
}
/**********************************************************************/
# if USE_MPI
void
DumpMultiblockObjects(DBfile* db, PMPIO_baton_t* bat, char basename[], int numRanks)
# else
void
DumpMultiblockObjects(DBfile* db, char basename[], int numRanks)
# endif
{
/* MULTIBLOCK objects to tie together multiple files */
char** multimeshObjs;
char** multimatObjs;
char*** multivarObjs;
int* blockTypes;
int* varTypes;
int ok = 0;
// Make sure this list matches what's written out above
char vars[][10] = { "p", "e", "v", "q", "speed", "xd", "yd", "zd" };
int numvars = sizeof(vars) / sizeof(vars[0]);
// Reset to the root directory of the silo file
DBSetDir(db, "/");
// Allocate a bunch of space for building up the string names
multimeshObjs = Allocate<char*>(numRanks);
multimatObjs = Allocate<char*>(numRanks);
multivarObjs = Allocate<char**>(numvars);
blockTypes = Allocate<int>(numRanks);
varTypes = Allocate<int>(numRanks);
for(int v = 0; v < numvars; ++v)
{
multivarObjs[v] = Allocate<char*>(numRanks);
}
for(int i = 0; i < numRanks; ++i)
{
multimeshObjs[i] = Allocate<char>(64);
multimatObjs[i] = Allocate<char>(64);
for(int v = 0; v < numvars; ++v)
{
multivarObjs[v][i] = Allocate<char>(64);
}
blockTypes[i] = DB_UCDMESH;
varTypes[i] = DB_UCDVAR;
}
// Build up the multiobject names
for(int i = 0; i < numRanks; ++i)
{
# if USE_MPI
int iorank = PMPIO_GroupRank(bat, i);
# else
int iorank = 0;
# endif
// delete multivarObjs[i];
if(iorank == 0)
{
snprintf(multimeshObjs[i], 64, "/data_%d/mesh", i);
snprintf(multimatObjs[i], 64, "/data_%d/regions", i);
for(int v = 0; v < numvars; ++v)
{
snprintf(multivarObjs[v][i], 64, "/data_%d/%s", i, vars[v]);
}
}
else
{
snprintf(multimeshObjs[i], 64, "%s.%03d:/data_%d/mesh", basename, iorank, i);
snprintf(multimatObjs[i], 64, "%s.%03d:/data_%d/regions", basename, iorank,
i);
for(int v = 0; v < numvars; ++v)
{
snprintf(multivarObjs[v][i], 64, "%s.%03d:/data_%d/%s", basename, iorank,
i, vars[v]);
}
}
}
// Now write out the objects
ok += DBPutMultimesh(db, "mesh", numRanks, (char**) multimeshObjs, blockTypes, NULL);
ok += DBPutMultimat(db, "regions", numRanks, (char**) multimatObjs, NULL);
for(int v = 0; v < numvars; ++v)
{
ok += DBPutMultivar(db, vars[v], numRanks, (char**) multivarObjs[v], varTypes,
NULL);
}
for(int v = 0; v < numvars; ++v)
{
for(int i = 0; i < numRanks; i++)
{
Release<char>(&multivarObjs[v][i]);
}
Release<char*>(&multivarObjs[v]);
}
// Clean up
for(int i = 0; i < numRanks; i++)
{
Release<char>(&multimeshObjs[i]);
Release<char>(&multimatObjs[i]);
}
Release<char*>(&multimeshObjs);
Release<char*>(&multimatObjs);
Release<char**>(&multivarObjs);
Release<int>(&blockTypes);
Release<int>(&varTypes);
if(ok != 0)
{
printf("Error writing out multiXXX objs to viz file - rank 0\n");
}
}
# if USE_MPI
/**********************************************************************/
static void*
LULESH_PMPIO_Create(const char* fname, const char* dname, void* udata)
{
/* Create the file */
DBfile* db = DBCreate(fname, DB_CLOBBER, DB_LOCAL, NULL, DB_HDF5X);
/* Put the data in a subdirectory, so VisIt only sees the multimesh
* objects we write out in the base file */
if(db)
{
DBMkDir(db, dname);
DBSetDir(db, dname);
}
return (void*) db;
}
/**********************************************************************/
static void*
LULESH_PMPIO_Open(const char* fname, const char* dname, PMPIO_iomode_t ioMode,
void* udata)
{
/* Open the file */
DBfile* db = DBOpen(fname, DB_UNKNOWN, DB_APPEND);
/* Put the data in a subdirectory, so VisIt only sees the multimesh
* objects we write out in the base file */
if(db)
{
DBMkDir(db, dname);
DBSetDir(db, dname);
}
return (void*) db;
}
/**********************************************************************/
static void
LULESH_PMPIO_Close(void* file, void* udata)
{
DBfile* db = (DBfile*) file;
if(db) DBClose(db);
}
# endif
#else
void
DumpToVisit(Domain& domain, int numFiles, int myRank, int numRanks)
{
if(myRank == 0)
{
printf("Must enable -DVIZ_MESH at compile time to call DumpDomain\n");
}
}
#endif