Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/sst/elements/balar/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ _cuobjdump_list_ptx_*
_app_cuda_version_*
.gdbinit
*.trace
!tests/traces/*.trace
*.data
gpgpu_inst_stats.txt
*.dot
Expand Down
7 changes: 7 additions & 0 deletions src/sst/elements/balar/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ EXTRA_DIST = \
tests/testsuite_default_balar_wire.py \
tests/testBalar-testcpu.py \
tests/testBalar-vanadis.py \
tests/testBalar-doorbell.py \
tests/testBalar-malloc-free.py \
tests/testBalar-wide-packet.py \
tests/balar_test_topology.py \
tests/traces/doorbell_malloc.trace \
tests/traces/malloc_free.trace \
tests/traces/wide_memcpy_d2h.trace \
tests/testsuite_default_balar.py \
tests/utils.py \
tests/vanadisBlock.py \
Expand Down
11 changes: 10 additions & 1 deletion src/sst/elements/balar/testcpu/balarTestCPU.cc
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,16 @@ Interfaces::StandardMem::Request* BalarTestCPU::CudaAPITraceParser::getNextCall(
Interfaces::StandardMem::Request* launch_req = cpu->createGPUReqFromPacket(launch_pack);
initReqs->push(launch_req);
} else if (cudaCallType.find("free") != std::string::npos) {
// Future: Remove device pointer from hashmap as cleanup task?
pack.cuda_call_id = CUDA_FREE;

std::string dptr_name = trim(params_map.find(std::string("dptr"))->second);
auto pair = dptr_map->find(dptr_name);
if (pair == dptr_map->end()) {
out->fatal(CALL_INFO, -1,"Error: device pointer: '%s' not exist in hashmap\n", dptr_name.c_str());
}
pack.cuda_free.devPtr = (void*) *(pair->second);
out->verbose(CALL_INFO, 2, 0, "Free Device pointer (%s) val: 0x%llx\n", dptr_name.c_str(), (unsigned long long)*(pair->second));
req = cpu->createGPUReqFromPacket(pack);
}
}
return req;
Expand Down
102 changes: 102 additions & 0 deletions src/sst/elements/balar/tests/balar_test_topology.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""
Shared SST topology builder for Balar contract tests.
"""

import sst

DEBUG_PARAMS = {"debug": 0, "debug_level": 10}
NETWORK_BW = "25GB/s"
CLOCK = "2GHz"

CORE_GROUP = 0
MMIO_GROUP = 1
MEMORY_GROUP = 2

CORE_DST = [MEMORY_GROUP, MMIO_GROUP]
MMIO_SRC = [CORE_GROUP]
MMIO_DST = [MEMORY_GROUP]
MEMORY_SRC = [CORE_GROUP, MMIO_GROUP]


def build_testcpu_router(balar_builder, cfg_file, balar_verbosity=0, dma_verbosity=0):
"""Return (cpu, balar_mmio_addr) for merlin router + BalarTestCPU."""
balar_mmio_iface, balar_mmio_addr, dma_mem_if, dma_mmio_if = balar_builder.buildTestCPU(
cfg_file, balar_verbosity, dma_verbosity
)

mmio_nic = balar_mmio_iface.setSubComponent("lowlink", "memHierarchy.MemNIC")
mmio_nic.addParams({
"group": MMIO_GROUP,
"sources": MMIO_SRC,
"destinations": MMIO_DST,
"network_bw": NETWORK_BW,
})

dma_mem_nic = dma_mem_if.setSubComponent("lowlink", "memHierarchy.MemNIC")
dma_mem_nic.addParams({
"group": CORE_GROUP,
"destinations": CORE_DST,
"network_bw": NETWORK_BW,
})

dma_mmio_nic = dma_mmio_if.setSubComponent("lowlink", "memHierarchy.MemNIC")
dma_mmio_nic.addParams({
"group": MEMORY_GROUP,
"sources": MEMORY_SRC,
"network_bw": NETWORK_BW,
})

cpu = sst.Component("cpu", "balar.BalarTestCPU")
cpu.addParams({
"clock": CLOCK,
"verbose": balar_verbosity,
"scratch_mem_addr": 0,
"gpu_addr": balar_mmio_addr,
"enable_memcpy_dump": False,
})
iface = cpu.setSubComponent("memory", "memHierarchy.standardInterface")
iface.addParams(DEBUG_PARAMS)
cpu_nic = iface.setSubComponent("lowlink", "memHierarchy.MemNIC")
cpu_nic.addParams({
"group": CORE_GROUP,
"destinations": CORE_DST,
"network_bw": NETWORK_BW,
})

chiprtr = sst.Component("chiprtr", "merlin.hr_router")
chiprtr.addParams({
"xbar_bw": "1GB/s",
"id": "0",
"input_buf_size": "1KB",
"num_ports": "5",
"flit_size": "72B",
"output_buf_size": "1KB",
"link_bw": "1GB/s",
"topology": "merlin.singlerouter",
})
chiprtr.setSubComponent("topology", "merlin.singlerouter")

memctrl = sst.Component("memory", "memHierarchy.MemController")
memctrl.addParams({
"clock": "1GHz",
"addr_range_end": balar_mmio_addr - 1,
})
mem_nic = memctrl.setSubComponent("highlink", "memHierarchy.MemNIC")
mem_nic.addParams({
"group": MEMORY_GROUP,
"sources": MEMORY_SRC,
"network_bw": NETWORK_BW,
})
memory = memctrl.setSubComponent("backend", "memHierarchy.simpleMem")
memory.addParams({
"access_time": "100 ns",
"mem_size": "512MiB",
})

sst.Link("link_cpu").connect((cpu_nic, "port", "1000ps"), (chiprtr, "port0", "1000ps"))
sst.Link("link_mmio").connect((mmio_nic, "port", "500ps"), (chiprtr, "port1", "500ps"))
sst.Link("link_dma_mem").connect((dma_mem_nic, "port", "500ps"), (chiprtr, "port2", "500ps"))
sst.Link("link_dma_mmio").connect((dma_mmio_nic, "port", "500ps"), (chiprtr, "port3", "500ps"))
sst.Link("link_mem").connect((mem_nic, "port", "1000ps"), (chiprtr, "port4", "1000ps"))

return cpu, balar_mmio_addr
22 changes: 22 additions & 0 deletions src/sst/elements/balar/tests/testBalar-doorbell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Contract test: minimal CUDA API (malloc) exercises scratch write + MMIO doorbell + DMA read.
# Run: sst testBalar-doorbell.py --model-options='-c gpu-v100-mem.cfg -s stats.out -x ./balar_trace/vectorAdd -t traces/doorbell_malloc.trace'

import sst
import argparse
from utils import *
import balarBlock
import balar_test_topology

args = vars(balarTestParser.parse_args())
balarBuilder = balarBlock.Builder(args)
cpu, _ = balar_test_topology.build_testcpu_router(
balarBuilder, args["config"], args["balar_verbosity"], args["dma_verbosity"]
)
cpu.addParams({
"trace_file": args["trace"],
"cuda_executable": args["cuda_binary"],
})

sst.setStatisticLoadLevel(args["statlevel"])
sst.enableAllStatisticsForAllComponents({"type": "sst.AccumulatorStatistic"})
sst.setStatisticOutput("sst.statOutputTXT", {"filepath": args["statfile"]})
21 changes: 21 additions & 0 deletions src/sst/elements/balar/tests/testBalar-malloc-free.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Contract test: cudaMalloc + cudaFree round-trip via scratch + doorbell + DMA.
# Run: sst testBalar-malloc-free.py --model-options='-c gpu-v100-mem.cfg -s stats.out -x ./balar_trace/vectorAdd -t traces/malloc_free.trace'

import sst
from utils import *
import balarBlock
import balar_test_topology

args = vars(balarTestParser.parse_args())
balarBuilder = balarBlock.Builder(args)
cpu, _ = balar_test_topology.build_testcpu_router(
balarBuilder, args["config"], args["balar_verbosity"], args["dma_verbosity"]
)
cpu.addParams({
"trace_file": args["trace"],
"cuda_executable": args["cuda_binary"],
})

sst.setStatisticLoadLevel(args["statlevel"])
sst.enableAllStatisticsForAllComponents({"type": "sst.AccumulatorStatistic"})
sst.setStatisticOutput("sst.statOutputTXT", {"filepath": args["statfile"]})
21 changes: 21 additions & 0 deletions src/sst/elements/balar/tests/testBalar-wide-packet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Contract test: 4 KiB cudaMemcpy H2D+D2H validates multi-cache-line scratch packet path.
# Run: sst testBalar-wide-packet.py --model-options='-c gpu-v100-mem.cfg -s stats.out -x ./balar_trace/vectorAdd -t traces/wide_memcpy_d2h.trace'

import sst
from utils import *
import balarBlock
import balar_test_topology

args = vars(balarTestParser.parse_args())
balarBuilder = balarBlock.Builder(args)
cpu, _ = balar_test_topology.build_testcpu_router(
balarBuilder, args["config"], args["balar_verbosity"], args["dma_verbosity"]
)
cpu.addParams({
"trace_file": args["trace"],
"cuda_executable": args["cuda_binary"],
})

sst.setStatisticLoadLevel(args["statlevel"])
sst.enableAllStatisticsForAllComponents({"type": "sst.AccumulatorStatistic"})
sst.setStatisticOutput("sst.statOutputTXT", {"filepath": args["statfile"]})
Loading
Loading