Files
paddlepaddle--paddle/tools/CrossStackProfiler/NetFileReader.py
T
2026-07-13 12:40:42 +08:00

145 lines
4.5 KiB
Python
Executable File

# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import multiprocessing
from multiprocessing import Process
from CspFileReader import (
FILEORGANIZEFORM_BYTRAINER,
PIPELINEINFO_TRACE_NUM,
FileReader,
getLogger,
)
class netFileReader(FileReader):
def _parseSingleFile(self, fileNameList, tx_pid, rx_pid, q=None):
traceInfo = {}
traceEventList = []
metaInfo = {}
metaInfo['name'] = 'process_name'
metaInfo['ph'] = 'M'
metaInfo['pid'] = tx_pid
metaInfo['args'] = {'name': f"{tx_pid:02}_tx"}
traceEventList.append(metaInfo)
metaInfo = {}
metaInfo['name'] = 'process_name'
metaInfo['ph'] = 'M'
metaInfo['pid'] = rx_pid
metaInfo['args'] = {'name': f"{rx_pid:02}_rx"}
traceEventList.append(metaInfo)
trainerIdList = []
for fileName in fileNameList:
trainerId = self.getTrainerId(fileName)
trainerIdList.append(trainerId)
with open(fileName, "r") as rf:
for line in rf:
try:
event_str = json.loads(line.strip())
event_str["pid"] = (
tx_pid if event_str["name"] == "tx" else rx_pid
)
# the unit of net is ms, we need ns
event_str["ts"] = self._align_ts(event_str["ts"] * 1e6)
event_str["id"] = trainerId
traceEventList.append(event_str)
except Exception:
self._logger.warning(
f"invalid record [{line[:-1]}] in [{fileName}]. skip it!"
)
traceInfo["traceEvents"] = traceEventList
if q is not None:
q.put(traceInfo)
else:
return traceInfo
def parseFileByGroup(self, groupId, processNum=8):
fileFist = self.getFileListByGroup(groupId)
fileFist = fileFist[: min(self._displaySize, len(fileFist))]
manager = multiprocessing.Manager()
q = manager.Queue()
processPool = []
pidList = []
tx_pid = PIPELINEINFO_TRACE_NUM
rx_pid = PIPELINEINFO_TRACE_NUM + 1
taskList = self._splitTaskListForMultiProcess(fileFist, processNum)
for task in taskList:
subproc = Process(
target=self._parseSingleFile,
args=(
task,
tx_pid,
rx_pid,
q,
),
)
processPool.append(subproc)
subproc.start()
pidList.append(subproc.pid)
self._logger.info(
f"[Net info]: process [{subproc.pid}] has been started, total task num is {len(processPool)} ..."
)
for t in processPool:
t.join()
pidList.remove(t.pid)
self._logger.info(
f"[Net info]: process [{t.pid}] has exited! remained {len(pidList)} process!"
)
traceInfo = {}
isFirstProcess = True
for t in processPool:
if isFirstProcess:
isFirstProcess = False
traceInfo["traceEvents"] = q.get()["traceEvents"]
else:
traceInfo["traceEvents"].extend(q.get()["traceEvents"])
return traceInfo
def test_netFileReader():
args = {
"dataPath": "data/newdata/net",
"groupSize": 4,
"displaySize": 2,
"gpuPerTrainer": 8,
"minTimeStamp": 0,
"organizeForm": FILEORGANIZEFORM_BYTRAINER,
}
testReader = netFileReader(getLogger(), args)
testReader.printArgs()
data = testReader.parseFileByGroup(0, 8)
jsObj = json.dumps(data, indent=4, separators=(',', ': '))
fileObject = open('jsonFile.json', 'w')
fileObject.write(jsObj)
fileObject.close()
if __name__ == "__main__":
test_netFileReader()