Skip to content

Commit

Permalink
Extend FieldAccessCount
Browse files Browse the repository at this point in the history
* Add total() and totalBytes() to FieldHitsArray
* Add field size and totals to console output
* Add prettySize() utility function
  • Loading branch information
bernhardmgruber committed Feb 13, 2023
1 parent 768d0a5 commit 1f1a375
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 26 deletions.
21 changes: 21 additions & 0 deletions include/llama/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,4 +762,25 @@ namespace llama
}
};
} // namespace internal

struct PrettySize
{
double size;
const char* unit;
};

/// Repeatedly divides the given size (in bytes) until it fits below 1000. Returns the new size and a string
/// literal with the corresponding unit.
inline auto prettySize(double size) -> PrettySize
{
static const char* unit[] = {"B ", "KB", "MB", "GB", "TB", "PB", "EB"};
unsigned unitIndex = 0;
while(size > 1000.0)
{
size /= 1000.0;
unitIndex++;
}
assert(unitIndex < std::size(unit));
return {size, unit[unitIndex]};
}
} // namespace llama
130 changes: 120 additions & 10 deletions include/llama/mapping/FieldAccessCount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,56 @@ namespace llama::mapping
using RecordDim = typename Mapping::RecordDim;
using CountType = TCountType;
inline static constexpr bool myCodeHandlesProxyReferences = MyCodeHandlesProxyReferences;
using FieldHitsArray = Array<AccessCounts<CountType>, flatFieldCount<RecordDim>>;

struct FieldHitsArray : Array<AccessCounts<CountType>, flatFieldCount<RecordDim>>
{
LLAMA_FN_HOST_ACC_INLINE auto total() const -> AccessCounts<CountType>
{
AccessCounts<CountType> total{};
for(const auto& ac : *this)
{
if constexpr(MyCodeHandlesProxyReferences)
{
total.reads += ac.reads;
total.writes += ac.writes;
}
else
total.memLocsComputed += ac.memLocsComputed;
}
return total;
}

struct TotalBytes
{
CountType totalRead;
CountType totalWritten;
};

/// When MyCodeHandlesProxyReferences is true, return a pair of the total read and written bytes. If false,
/// returns the total bytes of accessed data as a single value.
LLAMA_FN_HOST_ACC_INLINE auto totalBytes() const
{
CountType r = 0;
CountType w = 0; // NOLINT(misc-const-correctness)
forEachLeafCoord<RecordDim>(
[&](auto rc)
{
const size_type i = flatRecordCoord<RecordDim, decltype(rc)>;
const auto fieldSize = sizeof(GetType<RecordDim, decltype(rc)>);
if constexpr(MyCodeHandlesProxyReferences)
{
r += (*this)[i].reads * fieldSize;
w += (*this)[i].writes * fieldSize;
}
else
r += (*this)[i].memLocsComputed * fieldSize;
});
if constexpr(MyCodeHandlesProxyReferences)
return TotalBytes{r, w};
else
return r;
}
};

inline static constexpr auto blobCount = Mapping::blobCount + 1;

Expand Down Expand Up @@ -175,28 +224,49 @@ namespace llama::mapping

private:
static constexpr auto columnWidth = 10;
static constexpr auto sizeColumnWidth = 5;

void printFieldHitsHost(const FieldHitsArray& hits) const
{
if constexpr(MyCodeHandlesProxyReferences)
std::cout << std::left << std::setw(columnWidth) << "Field" << ' ' << std::right
<< std::setw(columnWidth) << "Reads" << ' ' << std::right << std::setw(columnWidth)
<< "Writes" << '\n';
<< std::setw(sizeColumnWidth) << "Size" << std::right << std::setw(columnWidth) << "Reads"
<< ' ' << std::right << std::setw(columnWidth) << "Writes" << '\n';
else
std::cout << std::left << std::setw(columnWidth) << "Field" << ' ' << std::right
<< std::setw(columnWidth) << "Mlocs comp" << '\n';
<< std::setw(sizeColumnWidth) << "Size" << std::right << std::setw(columnWidth)
<< "Mlocs cmp" << '\n';
forEachLeafCoord<RecordDim>(
[&](auto rc)
{
const size_type i = flatRecordCoord<RecordDim, decltype(rc)>;
const auto fieldSize = sizeof(GetType<RecordDim, decltype(rc)>);
if constexpr(MyCodeHandlesProxyReferences)
std::cout << std::left << std::setw(columnWidth) << prettyRecordCoord<RecordDim>(rc) << ' '
<< std::right << std::setw(columnWidth) << hits[i].reads << ' ' << std::right
<< std::right << std::setw(sizeColumnWidth) << fieldSize << std::right
<< std::setw(columnWidth) << hits[i].reads << ' ' << std::right
<< std::setw(columnWidth) << hits[i].writes << '\n';
else
std::cout << std::left << std::setw(columnWidth) << prettyRecordCoord<RecordDim>(rc) << ' '
<< std::right << std::setw(columnWidth) << hits[i].memLocsComputed << '\n';
<< std::right << std::setw(sizeColumnWidth) << fieldSize << std::right
<< std::setw(columnWidth) << hits[i].memLocsComputed << '\n';
});
const auto total = hits.totalBytes();
if constexpr(MyCodeHandlesProxyReferences)
{
const auto [rsize, runit] = prettySize(total.totalRead);
const auto [wsize, wunit] = prettySize(total.totalWritten);
std::cout << std::left << std::setw(columnWidth) << "Total" << ' ' << std::right
<< std::setw(sizeColumnWidth) << ' ' << std::right << std::setw(columnWidth) << rsize
<< runit << ' ' << std::right << std::setw(columnWidth - 2) << wsize << wunit << '\n';
}
else
{
const auto [size, unit] = prettySize(total);
std::cout << std::left << std::setw(columnWidth) << "Total" << ' ' << std::right
<< std::setw(sizeColumnWidth) << ' ' << std::right << std::setw(columnWidth) << size << unit
<< '\n';
}
std::cout << std::internal;
}

Expand All @@ -205,27 +275,39 @@ namespace llama::mapping
if constexpr(MyCodeHandlesProxyReferences)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf("%*s %*s %*s\n", columnWidth, "Field", columnWidth, "Reads", columnWidth, "Writes");
printf(
"%*s %*s %*s %*s\n",
columnWidth,
"Field",
sizeColumnWidth,
"Size",
columnWidth,
"Reads",
columnWidth,
"Writes");
}
else
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf("%*s %*s\n", columnWidth, "Field", columnWidth, "Mlocs comp");
printf("%*s %*s %*s\n", columnWidth, "Field", sizeColumnWidth, "Size", columnWidth, "Mlocs cmp");
}
forEachLeafCoord<RecordDim>(
[&](auto rc)
{
const size_type i = flatRecordCoord<RecordDim, decltype(rc)>;
const auto fieldSize = sizeof(GetType<RecordDim, decltype(rc)>);
constexpr auto fieldName = prettyRecordCoord<RecordDim>(rc);
char fieldNameZT[fieldName.size() + 1]{}; // nvcc does not handle the %*.*s parameter correctly
llama::internal::constexprCopy(fieldName.begin(), fieldName.end(), fieldNameZT);
if constexpr(MyCodeHandlesProxyReferences)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf(
"%*.s %*lu %*lu\n",
"%*.s %*lu %*lu %*lu\n",
columnWidth,
fieldNameZT,
sizeColumnWidth,
fieldSize,
columnWidth,
static_cast<unsigned long>(hits[i].reads),
columnWidth,
Expand All @@ -235,13 +317,41 @@ namespace llama::mapping
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf(
"%*.s %*lu\n",
"%*.s %*lu %*lu\n",
columnWidth,
fieldNameZT,
sizeColumnWidth,
fieldSize,
columnWidth,
static_cast<unsigned long>(hits[i].memLocsComputed));
}
});

const auto total = hits.totalBytes();
if constexpr(MyCodeHandlesProxyReferences)
{
const auto [rsize, runit] = prettySize(total.totalRead);
const auto [wsize, wunit] = prettySize(total.totalWritten);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf(
"%*s %*s %*f%s %*f%s\n",
columnWidth,
"Total",
sizeColumnWidth,
"",
columnWidth,
rsize,
runit,
columnWidth - 2,
wsize,
wunit);
}
else
{
const auto [size, unit] = prettySize(total);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
printf("%*s %*s %*f%s\n", columnWidth, "Total", sizeColumnWidth, "", columnWidth, size, unit);
}
}

LLAMA_FN_HOST_ACC_INLINE auto inner() const -> const Mapping&
Expand Down
43 changes: 27 additions & 16 deletions tests/mapping.HeatmapTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,19 @@ TEMPLATE_LIST_TEST_CASE("FieldAccessCount.nbody.mem_locs_computed", "", SizeType
std::streambuf* old = std::cout.rdbuf(buffer.rdbuf());
particles.mapping().printFieldHits(particles.storageBlobs);
std::cout.rdbuf(old);
CHECK(buffer.str() == R"(Field Mlocs comp
Pos.X 10400
Pos.Y 10400
Pos.Z 10400
Vel.X 400
Vel.Y 400
Vel.Z 400
Mass 10300
CHECK(buffer.str() == R"(Field Size Mlocs cmp
Pos.X 8 10400
Pos.Y 8 10400
Pos.Z 8 10400
Vel.X 8 400
Vel.Y 8 400
Vel.Z 8 400
Mass 4 10300
Total 300.4KB
)");

CHECK(hits.total().memLocsComputed == 42700);
CHECK(hits.totalBytes() == 300400);
};
run(llama::mapping::AlignedAoS<llama::ArrayExtents<std::size_t, n>, ParticleHeatmap>{});
run(llama::mapping::PackedSingleBlobSoA<llama::ArrayExtents<std::size_t, n>, ParticleHeatmap>{});
Expand Down Expand Up @@ -224,15 +228,22 @@ TEMPLATE_LIST_TEST_CASE("FieldAccessCount.nbody.reads_writes", "", SizeTypes)
std::streambuf* old = std::cout.rdbuf(buffer.rdbuf());
particles.mapping().printFieldHits(particles.storageBlobs);
std::cout.rdbuf(old);
CHECK(buffer.str() == R"(Field Reads Writes
Pos.X 10200 300
Pos.Y 10200 300
Pos.Z 10200 300
Vel.X 200 200
Vel.Y 200 200
Vel.Z 200 200
Mass 10100 200
CHECK(buffer.str() == R"(Field Size Reads Writes
Pos.X 8 10200 300
Pos.Y 8 10200 300
Pos.Z 8 10200 300
Vel.X 8 200 200
Vel.Y 8 200 200
Vel.Z 8 200 200
Mass 4 10100 200
Total 290KB 12.8KB
)");

CHECK(hits.total().reads == 41300);
CHECK(hits.total().writes == 1700);
const auto [totalRead, totalWritten] = hits.totalBytes();
CHECK(totalRead == 290000);
CHECK(totalWritten == 12800);
};
run(llama::mapping::AlignedAoS<llama::ArrayExtents<std::size_t, n>, ParticleHeatmap>{});
run(llama::mapping::PackedSingleBlobSoA<llama::ArrayExtents<std::size_t, n>, ParticleHeatmap>{});
Expand Down

0 comments on commit 1f1a375

Please sign in to comment.