Skip to content
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Documentation for TransferBench is available at
- Added new bmasweep preset that compares DMA to batched DMA execution for parallel transfers to other GPUs
- Added new wallclock preset that compares wallclock counters across XCCs within a GPU
- Added new smoketest preset that runs a variety of DMA/GFX tests for simple correctness tests
- Added new help preset to show config file examples
- Added new presets preset to show available presets and their descriptions
- Added new envvars preset to show environment variables that can change TransferBench behavior
- Adding information on how to run multi-rank with TransferBench, when run with no args

### Modified
- DMA-BUF support enablement in CMake changed to ENABLE_DMA_BUF to be more similar to other compile-time options
Expand All @@ -30,6 +34,7 @@ Documentation for TransferBench is available at
- Dynamically size CQs for NIC transfers in high QPs case
- Switch to using hipMemcpyDeviceToDeviceNoCU instead of hipMemcpyDefault for DMA Executor if available (requires HIP >= 6.0)
- Allow for multiple destination memory locations for DMA/Batched-DMA Transfers
- Removed env vars printing and preset print when running TransferBench with no args

## v1.66.02
### Added
Expand Down
25 changes: 18 additions & 7 deletions src/client/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ int main(int argc, char **argv)
if (!ev.outputToCsv) {
DisplayVersion();
DisplayUsage(argv[0]);
DisplayPresets();
}
DisplayTopology(ev.outputToCsv, ev.showBorders);
}
Expand Down Expand Up @@ -258,14 +257,26 @@ void DisplayUsage(char const* cmdName)

Print("Usage: %s config <N>\n", cmdName);
Print(" config: Either:\n");
Print(" - Filename of configFile containing Transfers to execute (see example.cfg for format)\n");
Print(" - Name of preset config:\n");
Print(" - Filename of config file containing Transfers to execute\n");
Print(" - Name of preset config\n");
Print(" - 'cmdline' followed by one transfer expression\n");
Print(" - 'dryrun' followed by one transfer expression (prints parsed transfers only)\n");
Print(" N : (Optional) Number of bytes to copy per Transfer.\n");
Print(" If not specified, defaults to %lu bytes. Must be a multiple of 4 bytes\n",
DEFAULT_BYTES_PER_TRANSFER);
Print(" If not specified, defaults to %lu. Must be a multiple of 4 bytes\n", DEFAULT_BYTES_PER_TRANSFER);
Print(" If 0 is specified, a range of Ns will be benchmarked\n");
Print(" May append a suffix ('K', 'M', 'G') for kilobytes / megabytes / gigabytes\n");
Print("\n");

EnvVars::DisplayUsage();
Print("- Use \"%s help\" for more information about how to create config files / describe Transfers\n", cmdName);
Print("- Use \"%s envvars\" for more information about environment variables that customize behavior\n", cmdName);
Print("- Use \"%s presets\" to display list of available presets\n", cmdName);
Print("\n");
Print("For multi-rank usage, TransferBench must either be compiled with MPI support or rely on sockets\n");
Print("It is recommended to only run one process per node\n");
Print(" - MPI approach:\n");
Print(" Node 0> mpirun -np 4 -host node0,node1,node2,node3 ./TransferBench a2a\n");
Print(" - Socket approach:\n");
Print(" Node 0> TB_RANK=0 TB_NUM_RANKS=4 TB_MASTER_ADDR=X.X.X.X ./TransferBench a2a\n");
Print(" Node 1> TB_RANK=1 TB_NUM_RANKS=4 TB_MASTER_ADDR=X.X.X.X ./TransferBench a2a\n");
Print(" Node 2> TB_RANK=2 TB_NUM_RANKS=4 TB_MASTER_ADDR=X.X.X.X ./TransferBench a2a\n");
Print(" Node 3> TB_RANK=3 TB_NUM_RANKS=4 TB_MASTER_ADDR=X.X.X.X ./TransferBench a2a\n");
};
94 changes: 54 additions & 40 deletions src/client/EnvVars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,56 +314,70 @@ class EnvVars
}

// Display info on the env vars that can be used
static void DisplayUsage()
static void DisplayEnvVarsList()
{
printf("Environment variables:\n");
printf("Environment variables (client):\n");
printf("======================\n");
printf(" ALWAYS_VALIDATE - Validate after each iteration instead of once after all iterations\n");
printf(" BLOCK_BYTES - Controls granularity of how work is divided across subExecutors\n");
printf(" BYTE_OFFSET - Initial byte-offset for memory allocations. Must be multiple of 4\n");
printf(" CU_MASK - CU mask for streams. Can specify ranges e.g '5,10-12,14'\n");
printf(" FILL_COMPRESS - Percentages of 64B lines to be filled by random/1B0/2B0/4B0/32B0\n");
printf(" FILL_PATTERN - Big-endian pattern for source data, specified in hex digits. Must be even # of digits\n");
printf(" GFX_BLOCK_ORDER - How blocks for transfers are ordered. 0=sequential, 1=interleaved\n");
printf(" GFX_BLOCK_SIZE - # of threads per threadblock (Must be multiple of 64)\n");
printf(" GFX_SE_TYPE - SubExecutor granularity type (0=threadblock, 1=warp)\n");
printf(" GFX_TEMPORAL - Use of non-temporal loads or stores (0=none 1=loads 2=stores 3=both)\n");
printf(" GFX_UNROLL - Unroll factor for GFX kernel (0=auto), must be less than %d\n", TransferBench::GetIntAttribute(ATR_GFX_MAX_UNROLL));
printf(" GFX_SINGLE_TEAM - Have subexecutors work together on full array instead of working on disjoint subarrays\n");
printf(" GFX_WAVE_ORDER - Stride pattern for GFX kernel (0=UWC,1=UCW,2=WUC,3=WCU,4=CUW,5=CWU)\n");
printf(" GFX_WORD_SIZE - GFX kernel packed data size (4=DWORDx4, 2=DWORDx2, 1=DWORDx1)\n");
printf(" HIDE_ENV - Hide environment variable value listing\n");
printf(" ALWAYS_VALIDATE - Validate after each iteration instead of once after all iterations\n");
printf(" BLOCK_BYTES - Controls granularity of how work is divided across subExecutors\n");
printf(" BYTE_OFFSET - Initial byte-offset for memory allocations. Must be multiple of 4\n");
printf(" CU_MASK - CU mask for streams. Can specify ranges e.g '5,10-12,14'\n");
printf(" FILL_COMPRESS - Percentages of 64B lines to be filled by random/1B0/2B0/4B0/32B0\n");
printf(" FILL_PATTERN - Big-endian pattern for source data, specified in hex digits. Must be even # of digits\n");
printf(" GFX_BLOCK_ORDER - How blocks for transfers are ordered. 0=sequential, 1=interleaved\n");
printf(" GFX_BLOCK_SIZE - # of threads per threadblock (Must be multiple of 64)\n");
printf(" GFX_SE_TYPE - SubExecutor granularity type (0=threadblock, 1=warp)\n");
printf(" GFX_TEMPORAL - Use of non-temporal loads or stores (0=none 1=loads 2=stores 3=both)\n");
printf(" GFX_UNROLL - Unroll factor for GFX kernel (0=auto), must be less than %d\n", TransferBench::GetIntAttribute(ATR_GFX_MAX_UNROLL));
printf(" GFX_SINGLE_TEAM - Have subexecutors work together on full array instead of working on disjoint subarrays\n");
printf(" GFX_WAVE_ORDER - Stride pattern for GFX kernel (0=UWC,1=UCW,2=WUC,3=WCU,4=CUW,5=CWU)\n");
printf(" GFX_WORD_SIZE - GFX kernel packed data size (4=DWORDx4, 2=DWORDx2, 1=DWORDx1)\n");
printf(" HIDE_ENV - Hide environment variable value listing\n");
#if NIC_EXEC_ENABLED
printf(" IB_GID_INDEX - Required for RoCE NICs (default=-1/auto)\n");
printf(" IB_PORT_NUMBER - RDMA port count for RDMA NIC (default=1)\n");
printf(" IP_ADDRESS_FAMILY - IP address family (4=v4, 6=v6, default=v4)\n");
printf(" IB_GID_INDEX - Required for RoCE NICs (default=-1/auto)\n");
printf(" IB_PORT_NUMBER - RDMA port count for RDMA NIC (default=1)\n");
printf(" IP_ADDRESS_FAMILY - IP address family (4=v4, 6=v6, default=v4)\n");
#endif
printf(" MIN_VAR_SUBEXEC - Minumum # of subexecutors to use for variable subExec Transfers\n");
printf(" MAX_VAR_SUBEXEC - Maximum # of subexecutors to use for variable subExec Transfers (0 for device limits)\n");
printf(" MIN_VAR_SUBEXEC - Minimum # of subexecutors to use for variable subExec Transfers\n");
printf(" MAX_VAR_SUBEXEC - Maximum # of subexecutors to use for variable subExec Transfers (0 for device limits)\n");
#if NIC_EXEC_ENABLED
printf(" NIC_CHUNK_BYTES - Number of bytes to send at a time using NIC (default = 1GB)\n");
printf(" NIC_CQ_POLL_BATCH - Number of CQ entries to poll per ibv_poll_cq call (default = 4)\n");
printf(" NIC_RELAX_ORDER - Set to non-zero to use relaxed ordering");
printf(" NIC_CHUNK_BYTES - Number of bytes to send at a time using NIC (default = 1GB)\n");
printf(" NIC_CQ_POLL_BATCH - Number of CQ entries to poll per ibv_poll_cq call (default = 4)\n");
printf(" NIC_RELAX_ORDER - Set to non-zero to use relaxed ordering\n");
#endif
printf(" NUM_ITERATIONS - # of timed iterations per test. If negative, run for this many seconds instead\n");
printf(" NUM_SUBITERATIONS - # of sub-iterations to run per iteration. Must be non-negative\n");
printf(" NUM_WARMUPS - # of untimed warmup iterations per test\n");
printf(" OUTPUT_TO_CSV - Outputs to CSV format if set\n");
printf(" NUM_ITERATIONS - # of timed iterations per test. If negative, run for this many seconds instead\n");
printf(" NUM_SUBITERATIONS - # of sub-iterations to run per iteration. Must be non-negative\n");
printf(" NUM_WARMUPS - # of untimed warmup iterations per test\n");
printf(" OUTPUT_TO_CSV - Outputs to CSV format if set\n");
#if NIC_EXEC_ENABLED
printf(" ROCE_VERSION - RoCE version (default=2)\n");
printf(" ROCE_VERSION - RoCE version (default=2)\n");
#endif
printf(" SAMPLING_FACTOR - Add this many samples (when possible) between powers of 2 when auto-generating data sizes\n");
printf(" SHOW_BORDERS - Show ASCII box-drawing characaters in tables\n");
printf(" SHOW_ITERATIONS - Show per-iteration timing info\n");
printf(" USE_HIP_EVENTS - Use HIP events for GFX executor timing\n");
printf(" USE_HSA_DMA - Use hsa_amd_async_copy instead of hipMemcpy for non-targeted DMA execution\n");
printf(" USE_INTERACTIVE - Pause for user-input before starting transfer loop\n");
printf(" USE_SINGLE_STREAM - Use a single stream per GPU GFX executor instead of stream per Transfer\n");
printf(" VALIDATE_DIRECT - Validate GPU destination memory directly instead of staging GPU memory on host\n");
printf(" VALIDATE_SOURCE - Validate GPU src memory immediately after preparation\n");
printf(" SAMPLING_FACTOR - Add this many samples (when possible) between powers of 2 when auto-generating data sizes\n");
printf(" SHOW_BORDERS - Show ASCII box-drawing characters in tables\n");
printf(" SHOW_ITERATIONS - Show per-iteration timing info\n");
printf(" USE_HIP_EVENTS - Use HIP events for GFX executor timing\n");
printf(" USE_HSA_DMA - Use hsa_amd_async_copy instead of hipMemcpy for non-targeted DMA execution\n");
printf(" USE_INTERACTIVE - Pause for user-input before starting transfer loop\n");
printf(" USE_SINGLE_STREAM - Use a single stream per GPU GFX executor instead of stream per Transfer\n");
printf(" VALIDATE_DIRECT - Validate GPU destination memory directly instead of staging GPU memory on host\n");
printf(" VALIDATE_SOURCE - Validate GPU src memory immediately after preparation\n");
printf("\n");
printf("Environment variables (back-end):\n");
printf("====================================\n");
printf(" TB_RANK - Used to specify the rank of this process (0-based, socket communicator)\n");
printf(" TB_NUM_RANKS - Used to specify the total number of ranks (socket communicator)\n");
printf(" TB_MASTER_ADDR - Used to set Rank 0 IP/hostname for socket communicator\n");
printf(" TB_MASTER_PORT - Used to set Rank 0 port for socket communicator (default: 29500)\n");
printf(" TB_SINGLE_LOG - In socket mode, only rank 0 logs when set\n");
printf(" TB_VERBOSE - Enables additional internal logging\n");
printf(" TB_DUMP_CFG_FILE - Writes executed transfers to a config file\n");
printf(" TB_DUMP_LINES - Dumps randomized input-line statistics for FILL_COMPRESS setup\n");
printf(" TB_NIC_FILTER - Regex filter to limit NIC visibility for NIC executors\n");
printf(" TB_FORCE_SINGLE_POD - Forces all ranks into one pod (skips pod query)\n");
printf(" TB_WALLCLOCK_RATE - Overrides queried GPU wallclock rate if needed\n");
printf(" TB_PAUSE - Pauses startup for debugger attachment\n");
}


void Print(std::string const& name, int32_t const value, const char* format, ...) const
{
printf("%-20s%s%12d%s", name.c_str(), outputToCsv ? "," : " = ", value, outputToCsv ? "," : " : ");
Expand Down
31 changes: 31 additions & 0 deletions src/client/Presets/EnvVarsList.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright (c) Advanced Micro Devices, Inc. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

int EnvVarsPreset([[maybe_unused]] EnvVars& ev,
[[maybe_unused]] size_t const numBytesPerTransfer,
[[maybe_unused]] std::string const presetName,
[[maybe_unused]] bool const bytesSpecified)
{
if (!Utils::RankDoesOutput()) return 0;
EnvVars::DisplayEnvVarsList();
return 0;
}
Loading