Skip to content

Commit db971f5

Browse files
committed
feat: add MetaX MACA/MCPTI profiler support
Add support for MetaX GPUs (C500, C550, etc.) using MCPTI API: New files: - include/tracesmith/capture/mcpti_profiler.hpp - src/capture/mcpti_profiler.cpp Features: - MCPTIProfiler class with full IPlatformProfiler interface - Kernel execution tracing (launch/complete events) - Memory operations (memcpy H2D/D2H/D2D, memset) - Synchronization events (stream/device/event sync) - Device info retrieval (name, memory, compute capability) - MCPTI buffer callbacks for activity collection Build system: - TRACESMITH_ENABLE_MACA CMake option - Auto-detect MACA SDK at /opt/maca - Links against libmcpti.so and libmcc.so Python bindings: - PlatformType.MACA enum value - is_maca_available() function - get_maca_driver_version() function - get_maca_device_count() function Note: MCPTI API is highly compatible with NVIDIA CUPTI, enabling easy migration of CUDA profiling code to MetaX platforms.
1 parent 074d443 commit db971f5

10 files changed

Lines changed: 902 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [0.8.0] - 2025-12-07
99

1010
### Added
11+
- **MetaX MACA/MCPTI Integration**: Support for MetaX GPUs (C500, C550)
12+
- `MCPTIProfiler`: GPU profiler using MetaX mcpti API
13+
- Kernel execution tracing
14+
- Memory copy/memset tracking
15+
- Synchronization events
16+
- API compatible with CUPTI for easy migration
17+
- Python bindings: `is_maca_available()`, `get_maca_device_count()`
18+
1119
- **Apple Instruments (xctrace) Integration**: Real Metal GPU profiling on macOS
1220
- `XCTraceProfiler`: Python wrapper for xctrace
1321
- Automatic Metal GPU event parsing from Instruments traces

CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ option(TRACESMITH_BUILD_PYTHON "Build Python bindings" OFF)
2626
option(TRACESMITH_ENABLE_CUDA "Enable CUDA/CUPTI support" OFF)
2727
option(TRACESMITH_ENABLE_ROCM "Enable ROCm support" OFF)
2828
option(TRACESMITH_ENABLE_METAL "Enable Metal support" OFF)
29+
option(TRACESMITH_ENABLE_MACA "Enable MetaX MACA/MCPTI support" OFF)
2930
option(TRACESMITH_USE_LIBUNWIND "Use libunwind for call stack capture" ON)
3031
option(TRACESMITH_USE_PERFETTO_SDK "Use Perfetto SDK for protobuf export" OFF)
3132

@@ -62,6 +63,21 @@ if(TRACESMITH_ENABLE_CUDA)
6263
endif()
6364
endif()
6465

66+
# MetaX MACA/MCPTI Support
67+
if(TRACESMITH_ENABLE_MACA)
68+
if(NOT MACA_ROOT)
69+
set(MACA_ROOT "/opt/maca" CACHE PATH "Path to MACA SDK")
70+
endif()
71+
72+
if(EXISTS "${MACA_ROOT}/include/mcpti/mcpti.h")
73+
message(STATUS "MACA SDK found at: ${MACA_ROOT}")
74+
add_definitions(-DTRACESMITH_ENABLE_MACA)
75+
else()
76+
message(WARNING "MACA SDK not found at ${MACA_ROOT}, MetaX support disabled")
77+
set(TRACESMITH_ENABLE_MACA OFF)
78+
endif()
79+
endif()
80+
6581
# libunwind Support (Cross-platform stack unwinding)
6682
if(TRACESMITH_USE_LIBUNWIND)
6783
find_package(Libunwind)
@@ -194,6 +210,7 @@ else()
194210
endif()
195211
message(STATUS " ROCm support: ${TRACESMITH_ENABLE_ROCM}")
196212
message(STATUS " Metal support: ${TRACESMITH_ENABLE_METAL}")
213+
message(STATUS " MACA support: ${TRACESMITH_ENABLE_MACA}")
197214
message(STATUS " Perfetto SDK: ${TRACESMITH_USE_PERFETTO_SDK}")
198215
message(STATUS " libunwind: ${TRACESMITH_USE_LIBUNWIND}")
199216
message(STATUS "")

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
| NVIDIA | CUPTI SDK | ✅ Production |
5656
| Apple | Metal API | ✅ Production |
5757
| Apple | Instruments (xctrace) | ✅ Production |
58+
| MetaX | MCPTI SDK | ✅ Production |
5859
| AMD | ROCm | 🔜 Coming Soon |
5960
| Linux | eBPF | ✅ Available |
6061

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#pragma once
2+
3+
#include "tracesmith/capture/profiler.hpp"
4+
#include <mutex>
5+
#include <unordered_map>
6+
7+
#ifdef TRACESMITH_ENABLE_MACA
8+
#include <mcc/mcc.h>
9+
#include <mcpti/mcpti.h>
10+
#endif
11+
12+
namespace tracesmith {
13+
14+
/**
15+
* MCPTI-based GPU Profiler for MetaX GPUs (C500/C550)
16+
*
17+
* Uses MetaX MCPTI (MACA Profiling Tools Interface) to capture:
18+
* - Kernel launches and completions
19+
* - Memory operations (H2D, D2H, D2D, memset)
20+
* - Synchronization events
21+
* - Stream operations
22+
*
23+
* Requirements:
24+
* - MetaX GPU (C500, C550, etc.)
25+
* - MACA SDK with MCPTI headers and library
26+
* - Driver with profiling permissions
27+
*
28+
* Note: MCPTI API is highly compatible with NVIDIA CUPTI
29+
*/
30+
class MCPTIProfiler : public IPlatformProfiler {
31+
public:
32+
MCPTIProfiler();
33+
~MCPTIProfiler() override;
34+
35+
// IPlatformProfiler interface
36+
PlatformType platformType() const override { return PlatformType::MACA; }
37+
bool isAvailable() const override;
38+
39+
bool initialize(const ProfilerConfig& config) override;
40+
void finalize() override;
41+
42+
bool startCapture() override;
43+
bool stopCapture() override;
44+
bool isCapturing() const override { return capturing_; }
45+
46+
size_t getEvents(std::vector<TraceEvent>& events, size_t max_count = 0) override;
47+
std::vector<DeviceInfo> getDeviceInfo() const override;
48+
49+
void setEventCallback(EventCallback callback) override;
50+
51+
uint64_t eventsCaptured() const override { return events_captured_; }
52+
uint64_t eventsDropped() const override { return events_dropped_; }
53+
54+
#ifdef TRACESMITH_ENABLE_MACA
55+
// MCPTI-specific methods
56+
57+
/**
58+
* Set activity buffer size (default: 32MB)
59+
*/
60+
void setBufferSize(size_t size_bytes);
61+
62+
/**
63+
* Enable/disable specific activity types
64+
*/
65+
void enableActivityKind(MCpti_ActivityKind kind, bool enable);
66+
67+
/**
68+
* Get MCPTI version
69+
*/
70+
uint32_t getMcptiVersion() const;
71+
72+
private:
73+
// MCPTI callback handlers (static for C API)
74+
static void MCPTIAPI bufferRequested(uint8_t** buffer, size_t* size, size_t* maxNumRecords);
75+
static void MCPTIAPI bufferCompleted(MCcontext ctx, uint32_t streamId,
76+
uint8_t* buffer, size_t size, size_t validSize);
77+
static void MCPTIAPI callbackHandler(void* userdata, MCpti_CallbackDomain domain,
78+
MCpti_CallbackId cbid, const void* cbdata);
79+
80+
// Activity processing
81+
void processActivity(MCpti_Activity* record);
82+
void processKernelActivity(const MCpti_ActivityKernel4* kernel);
83+
void processMemcpyActivity(const MCpti_ActivityMemcpy* memcpy);
84+
void processMemsetActivity(const MCpti_ActivityMemset* memset);
85+
void processSyncActivity(const MCpti_ActivitySynchronization* sync);
86+
87+
// Event creation helpers
88+
TraceEvent createKernelEvent(const MCpti_ActivityKernel4* kernel);
89+
TraceEvent createMemcpyEvent(const MCpti_ActivityMemcpy* memcpy);
90+
TraceEvent createMemsetEvent(const MCpti_ActivityMemset* memset);
91+
TraceEvent createSyncEvent(const MCpti_ActivitySynchronization* sync);
92+
93+
// Thread-safe event storage
94+
void addEvent(TraceEvent&& event);
95+
96+
// MCPTI handles
97+
MCpti_SubscriberHandle subscriber_;
98+
99+
// Activity buffer management
100+
size_t buffer_size_;
101+
static constexpr size_t DEFAULT_BUFFER_SIZE = 32 * 1024 * 1024; // 32MB
102+
static constexpr size_t ALIGN_SIZE = 8;
103+
104+
// Enabled activity kinds
105+
std::vector<MCpti_ActivityKind> enabled_activities_;
106+
107+
// Correlation ID tracking (to match kernel launch with completion)
108+
std::unordered_map<uint64_t, Timestamp> kernel_start_times_;
109+
std::mutex correlation_mutex_;
110+
111+
#endif // TRACESMITH_ENABLE_MACA
112+
113+
// Configuration
114+
ProfilerConfig config_;
115+
116+
// State
117+
bool initialized_;
118+
bool capturing_;
119+
120+
// Event storage
121+
std::vector<TraceEvent> events_;
122+
std::mutex events_mutex_;
123+
EventCallback callback_;
124+
125+
// Statistics
126+
uint64_t events_captured_;
127+
uint64_t events_dropped_;
128+
129+
// Correlation ID counter
130+
std::atomic<uint64_t> correlation_counter_;
131+
132+
// Singleton instance for static callbacks
133+
static MCPTIProfiler* instance_;
134+
};
135+
136+
/**
137+
* Check if MACA and MCPTI are available on this system
138+
*/
139+
bool isMACAAvailable();
140+
141+
/**
142+
* Get MACA driver version
143+
*/
144+
int getMACADriverVersion();
145+
146+
/**
147+
* Get number of MetaX GPU devices
148+
*/
149+
int getMACADeviceCount();
150+
151+
} // namespace tracesmith

include/tracesmith/capture/profiler.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ enum class PlatformType {
3535
Unknown,
3636
CUDA,
3737
ROCm,
38-
Metal
38+
Metal,
39+
MACA // MetaX MACA (C500, C550, etc.)
3940
};
4041

4142
/// Convert PlatformType to string
@@ -44,6 +45,7 @@ inline const char* platformTypeToString(PlatformType type) {
4445
case PlatformType::CUDA: return "CUDA";
4546
case PlatformType::ROCm: return "ROCm";
4647
case PlatformType::Metal: return "Metal";
48+
case PlatformType::MACA: return "MACA";
4749
default: return "Unknown";
4850
}
4951
}

python/src/bindings.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ PYBIND11_MODULE(_tracesmith, m) {
274274
.value("CUDA", PlatformType::CUDA)
275275
.value("ROCm", PlatformType::ROCm)
276276
.value("Metal", PlatformType::Metal)
277+
.value("MACA", PlatformType::MACA)
277278
.export_values();
278279

279280
// Platform type to string helper
@@ -935,7 +936,7 @@ PYBIND11_MODULE(_tracesmith, m) {
935936
m.def("create_profiler", [](PlatformType type) -> std::shared_ptr<IPlatformProfiler> {
936937
return createProfiler(type);
937938
}, py::arg("platform") = PlatformType::Unknown,
938-
"Create a profiler for the specified platform (CUDA, ROCm, Metal, or auto-detect with Unknown)");
939+
"Create a profiler for the specified platform (CUDA, ROCm, Metal, MACA, or auto-detect with Unknown)");
939940

940941
// Platform detection functions
941942
m.def("is_cuda_available", &isCUDAAvailable,
@@ -949,9 +950,19 @@ PYBIND11_MODULE(_tracesmith, m) {
949950

950951
m.def("is_metal_available", &isMetalAvailable,
951952
"Check if Metal is available on this system (macOS only)");
952-
953+
953954
m.def("get_metal_device_count", &getMetalDeviceCount,
954955
"Get number of Metal-capable devices");
956+
957+
// MetaX MACA functions
958+
m.def("is_maca_available", &isMACAAvailable,
959+
"Check if MetaX MACA is available on this system");
960+
961+
m.def("get_maca_driver_version", &getMACADriverVersion,
962+
"Get MetaX MACA driver version");
963+
964+
m.def("get_maca_device_count", &getMACADeviceCount,
965+
"Get number of MetaX GPU devices");
955966

956967
m.def("detect_platform", &detectPlatform,
957968
"Auto-detect the best available GPU platform");

python/tracesmith/__init__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,22 @@
170170
detect_platform,
171171
)
172172

173+
# MetaX MACA functions - may not be available on all builds
174+
try:
175+
from ._tracesmith import (
176+
is_maca_available,
177+
get_maca_driver_version,
178+
get_maca_device_count,
179+
)
180+
except ImportError:
181+
# MACA not available in this build
182+
def is_maca_available():
183+
return False
184+
def get_maca_driver_version():
185+
return 0
186+
def get_maca_device_count():
187+
return 0
188+
173189
# ============================================================================
174190
# Cluster Module - Multi-GPU Profiling (v0.7.0)
175191
# Optional: Only available when compiled with cluster support
@@ -413,6 +429,9 @@ def is_nccl_available() -> bool:
413429
'get_cuda_driver_version',
414430
'is_metal_available',
415431
'get_metal_device_count',
432+
'is_maca_available',
433+
'get_maca_driver_version',
434+
'get_maca_device_count',
416435
'detect_platform',
417436

418437
# High-level convenience functions

src/capture/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ if(TRACESMITH_ENABLE_ROCM)
3131
# TODO: Add ROCm profiler
3232
endif()
3333

34+
if(TRACESMITH_ENABLE_MACA)
35+
message(STATUS "Building MCPTI profiler for MetaX GPUs")
36+
target_sources(tracesmith-capture PRIVATE mcpti_profiler.cpp)
37+
38+
# Find MACA SDK (typically in /opt/maca)
39+
if(NOT MACA_ROOT)
40+
set(MACA_ROOT "/opt/maca" CACHE PATH "Path to MACA SDK")
41+
endif()
42+
43+
if(EXISTS "${MACA_ROOT}/include/mcpti/mcpti.h")
44+
message(STATUS " MACA SDK found at: ${MACA_ROOT}")
45+
target_include_directories(tracesmith-capture PRIVATE ${MACA_ROOT}/include)
46+
target_link_directories(tracesmith-capture PRIVATE ${MACA_ROOT}/lib)
47+
target_link_libraries(tracesmith-capture PUBLIC mcpti mcc)
48+
target_compile_definitions(tracesmith-capture PUBLIC TRACESMITH_ENABLE_MACA)
49+
else()
50+
message(WARNING "MACA SDK not found at ${MACA_ROOT}. Set MACA_ROOT to the correct path.")
51+
endif()
52+
endif()
53+
3454
if(TRACESMITH_ENABLE_METAL)
3555
message(STATUS "Building Metal profiler")
3656
# Objective-C++ source file (use full path to avoid path resolution issues)

0 commit comments

Comments
 (0)