diff --git a/include/recorder-log-format.h b/include/recorder-log-format.h index 09c9618..0be23f5 100644 --- a/include/recorder-log-format.h +++ b/include/recorder-log-format.h @@ -125,7 +125,7 @@ static const char* func_list[] = { "fdopen", "fileno", "access", "faccessat","tmpfile", "remove", "truncate", "ftruncate", "vfprintf", "msync", - // MPI I/O - 76 functions + // MPI I/O - 78 functions "PMPI_File_close", "PMPI_File_set_size", "PMPI_File_iread_at", "PMPI_File_iread", "PMPI_File_iread_shared", "PMPI_File_iwrite_at", "PMPI_File_iwrite", "PMPI_File_iwrite_shared", "PMPI_File_open", @@ -156,6 +156,7 @@ static const char* func_list[] = { "PMPI_Info_create", "PMPI_Info_set", "PMPI_Info_get", // Added 2020/08/06 "PMPI_Waitall", "PMPI_Waitsome", "PMPI_Waitany", + "PMPI_Ssend", // HDF5 I/O - 74 functions @@ -213,7 +214,7 @@ static char filename_arg_pos[] = { 0b00000001, 0b00000001, 0b00000001, 0b00000011, 0b00000000, // tmpfile 0b00000001, 0b00000001, 0b00000001, 0b00000001, 0b00000000, // remove - // MPI I/O - 76 functions + // MPI I/O - 78 functions // Only MPI_File_open has the filename argument 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, @@ -245,7 +246,7 @@ static char filename_arg_pos[] = { 0b00000000, 0b00000000, 0b00000000, // Added 2020/08/06 0b00000000, 0b00000000, 0b00000000, - + 0b00000000, // HDF5 I/O - 74 functions // Only H5Fcreate and H5Fopen have filename arguments diff --git a/include/recorder.h b/include/recorder.h index abda66f..e12a10d 100644 --- a/include/recorder.h +++ b/include/recorder.h @@ -352,10 +352,11 @@ RECORDER_FORWARD_DECL(PMPI_Irecv, int, (void *buf, int count, MPI_Datatype datat RECORDER_FORWARD_DECL(PMPI_Info_create, int, (MPI_Info *info)); RECORDER_FORWARD_DECL(PMPI_Info_set, int, (MPI_Info info, CONST char *key, CONST char *value)); RECORDER_FORWARD_DECL(PMPI_Info_get, int, (MPI_Info info, CONST char *key, int valuelen, char *value, int *flag)); -// Add MPI_Waitall, MPI_Waitsome and MPI_Waitany on 2020/08/06 +// Add MPI_Waitall, MPI_Waitsome, MPI_Waitany, MPI_Ssend on 2020/08/06 RECORDER_FORWARD_DECL(PMPI_Waitall, int, (int count, MPI_Request array_of_requests[], MPI_Status array_of_statuses[])); RECORDER_FORWARD_DECL(PMPI_Waitsome, int, (int incount, MPI_Request array_of_requests[], int *outcount, int array_of_indices[], MPI_Status array_of_statuses[])); RECORDER_FORWARD_DECL(PMPI_Waitany, int, (int count, MPI_Request array_of_requests[], int *indx, MPI_Status * status)); +RECORDER_FORWARD_DECL(PMPI_Ssend, int, (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)); diff --git a/lib/recorder-mpi.c b/lib/recorder-mpi.c index 977ad43..6913b78 100644 --- a/lib/recorder-mpi.c +++ b/lib/recorder-mpi.c @@ -458,7 +458,38 @@ int RECORDER_MPI_DECL(MPI_Wait) (MPI_Request *request, MPI_Status *status) { RECORDER_INTERCEPTOR(2, args); } -// Add MPI_Waitall, MPI_Waitsome and MPI_Waitany on 2020/08/06 +int RECORDER_MPI_DECL(MPI_Send) (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Send, (buf, count, datatype, dest, tag, comm)); + char **args = assemble_args_list(6, ptoa(buf), itoa(count), type2name(datatype), itoa(dest), itoa(tag), comm2name(comm)); + RECORDER_INTERCEPTOR(6, args); +} +int RECORDER_MPI_DECL(MPI_Recv) (void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Recv, (buf, count, datatype, source, tag, comm, status)); + char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(source), itoa(tag), comm2name(comm), ptoa(status)); + RECORDER_INTERCEPTOR(7, args); +} +int RECORDER_MPI_DECL(MPI_Sendrecv) (CONST void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, + int source, int recvtag, MPI_Comm comm, MPI_Status *status) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Sendrecv, (sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm, status)); + char **args = assemble_args_list(12, ptoa(sendbuf), itoa(sendcount), type2name(sendtype), itoa(dest), itoa(sendtag), ptoa(recvbuf), itoa(recvcount), type2name(recvtype), + itoa(source), itoa(recvtag), comm2name(comm), ptoa(status)); + RECORDER_INTERCEPTOR(12, args); +} +int RECORDER_MPI_DECL(MPI_Isend) (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Isend, (buf, count, datatype, dest, tag, comm, request)); + size_t r = *request; + char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(dest), itoa(tag), comm2name(comm), itoa(r)); + RECORDER_INTERCEPTOR(7, args); +} +int RECORDER_MPI_DECL(MPI_Irecv) (void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Irecv, (buf, count, datatype, source, tag, comm, request)); + size_t r = *request; + char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(source), itoa(tag), comm2name(comm), itoa(r)); + RECORDER_INTERCEPTOR(7, args); +} + + +// Add MPI_Waitall, MPI_Waitsome, MPI_Waitany and MPI_Ssend on 2020/08/06 int RECORDER_MPI_DECL(MPI_Waitall) (int count, MPI_Request requests[], MPI_Status statuses[]) { int i; size_t arr[count]; @@ -496,35 +527,9 @@ int RECORDER_MPI_DECL(MPI_Waitany) (int count, MPI_Request requests[], int *indx char **args = assemble_args_list(4, itoa(count), requests_str, itoa(*indx), ptoa(status)); RECORDER_INTERCEPTOR(4, args); } - - -int RECORDER_MPI_DECL(MPI_Send) (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { - RECORDER_INTERCEPTOR_NOIO(int, PMPI_Send, (buf, count, datatype, dest, tag, comm)); +int RECORDER_MPI_DECL(MPI_Ssend) (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { + RECORDER_INTERCEPTOR_NOIO(int, PMPI_Ssend, (buf, count, datatype, dest, tag, comm)); char **args = assemble_args_list(6, ptoa(buf), itoa(count), type2name(datatype), itoa(dest), itoa(tag), comm2name(comm)); RECORDER_INTERCEPTOR(6, args); } -int RECORDER_MPI_DECL(MPI_Recv) (void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) { - RECORDER_INTERCEPTOR_NOIO(int, PMPI_Recv, (buf, count, datatype, source, tag, comm, status)); - char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(source), itoa(tag), comm2name(comm), ptoa(status)); - RECORDER_INTERCEPTOR(7, args); -} -int RECORDER_MPI_DECL(MPI_Sendrecv) (CONST void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, - int source, int recvtag, MPI_Comm comm, MPI_Status *status) { - RECORDER_INTERCEPTOR_NOIO(int, PMPI_Sendrecv, (sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm, status)); - char **args = assemble_args_list(12, ptoa(sendbuf), itoa(sendcount), type2name(sendtype), itoa(dest), itoa(sendtag), ptoa(recvbuf), itoa(recvcount), type2name(recvtype), - itoa(source), itoa(recvtag), comm2name(comm), ptoa(status)); - RECORDER_INTERCEPTOR(12, args); -} -int RECORDER_MPI_DECL(MPI_Isend) (CONST void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) { - RECORDER_INTERCEPTOR_NOIO(int, PMPI_Isend, (buf, count, datatype, dest, tag, comm, request)); - size_t r = *request; - char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(dest), itoa(tag), comm2name(comm), itoa(r)); - RECORDER_INTERCEPTOR(7, args); -} -int RECORDER_MPI_DECL(MPI_Irecv) (void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request) { - RECORDER_INTERCEPTOR_NOIO(int, PMPI_Irecv, (buf, count, datatype, source, tag, comm, request)); - size_t r = *request; - char **args = assemble_args_list(7, ptoa(buf), itoa(count), type2name(datatype), itoa(source), itoa(tag), comm2name(comm), itoa(r)); - RECORDER_INTERCEPTOR(7, args); -} diff --git a/tools/reporter/reader.py b/tools/reporter/reader.py deleted file mode 100644 index 5d5a038..0000000 --- a/tools/reporter/reader.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -import sys, struct -import numpy as np -import time - -''' -Global Metadata Structure - same as in include/recorder-log-format.h - Time Resolution: double, 8 bytes - Number of MPI Ranks: Int, 4 bytes - Compression Mode: Int, 4 bytes - Recorder Window Size: Int ,4 bytes - - Then followed by one function name per line - They are the one intercepted by the current version of Recorder -''' -class GlobalMetadata: - def __init__(self, path): - self.timeResolution = 0 - self.numRanks = 0 - self.compMode = 0 - self.windowSize = 0 - self.funcs = [] - - self.read(path) - self.output() - - def read(self, path): - with open(path, 'rb') as f: - buf = f.read(8+4+4+4) - self.timeResolution, self.numRanks, \ - self.compMode, self.windowSize = struct.unpack("diii", buf) - - f.seek(24, 0) - self.funcs = f.read().splitlines() - self.funcs = [func.decode('utf-8').replace("PMPI", "MPI") for func in self.funcs] - - - def output(self): - print("Time Resolution:", self.timeResolution) - print("Ranks:", self.numRanks) - print("Compression Mode:", self.compMode) - print("Window Sizes:", self.windowSize) - -''' -Local Metadata Structure - same as in include/recorder-log-format.h - - Start timestamp: double, 8 bytes - ed timestamp: double, 8 bytes - Number of files accessed: int, 4 bytes - Total number of records: int, 4 bytes - Filemap: char**, 8 bytes pointer, ignore it - File sizes array: int*, 8 bytes pointer, size of each file accessed, ignore it - Function counter: int*256,4 * 256 bytes - - Then one line per file accessed, has the following form: - file id(4), file size(8), filename length(4), filename(variable length) -''' -class LocalMetadata: - def __init__(self, path): - self.tstart = 0 - self.tend = 0 - self.numFiles = 0 - self.totalRecords = 0 - self.functionCounter = [] - self.fileMap = [] - - self.read(path) - - def read(self, path): - with open(path, 'rb') as f: - self.tstart, self.tend = struct.unpack("dd", f.read(8+8)) - self.numFiles, self.totalRecords = struct.unpack("ii", f.read(4+4)) - - # ignore the two pointers - f.read(8+8) - - self.functionCounter = struct.unpack("i"*256, f.read(256*4)) - - self.fileMap = [None] * self.numFiles - for i in range(self.numFiles): - fileId = struct.unpack("i", f.read(4))[0] - fileSize = struct.unpack("l", f.read(8))[0] - filenameLen = struct.unpack("i", f.read(4))[0] - filename = f.read(filenameLen).decode('utf-8', 'ignore') - self.fileMap[fileId] = [fileId, fileSize, filename] - - def output(self): - print("Basic Information:") - print("tstart:", self.tstart) - print("tend:", self.tend) - print("files:", self.numFiles) - print("records:", self.totalRecords) - - #print("\nFunction Counter:") - #for idx, count in enumerate(self.functionCounter): - # if count > 0: print(idx, count) - print("\nFile Map:") - for fileInfo in self.fileMap: - print(fileInfo) - -class Record: - def __init__(self, rank, status, tstart, tend, funcId, args, res=None): - self.rank = rank - self.status = status - self.tstart = tstart - self.tend = tend - self.funcId = funcId - self.args = args - self.res = res - - - - -class RecorderReader: - def __init__(self, path, readMetadataOnly=False): - self.globalMetadata = GlobalMetadata(path+"/recorder.mt") - self.localMetadata = [] - self.records = [] - - for rank in range(self.globalMetadata.numRanks): - self.localMetadata.append( LocalMetadata(path+"/"+str(rank)+".mt") ) - if(readMetadataOnly): continue - lines = self.read( path+"/"+str(rank)+".itf" ) - records = self.decode(lines, rank) - records = self.decompress(records) - # sort records by tstart - records = sorted(records, key=lambda x: x.tstart) # sort by tstart - self.records.append( records ) - - def decompress(self, records): - for idx, record in enumerate(records): - if record.status != 0: # compressed - status, ref_id = record.status, record.funcId - records[idx].funcId = records[idx-1-ref_id].funcId - binStr = bin(status & 0b11111111) # use mask to get the two's complement as in C code - binStr = binStr[3:][::-1] # ignore the leading "0b1" and reverse the string - - refArgs = list(records[idx-1-ref_id].args) # copy the list - ii = 0 - for i, c in enumerate(binStr): - if c == '1': - if ii >= len(record.args): - print("Error:", record, ii) - refArgs[i] = record.args[ii] - ii += 1 - records[idx].args = refArgs - return records - - ''' - @lines: The lines read in from one log file - status: singed char, 1 byte - delta_tstart: int, 4 bytes - delta_tend: int, 4 bytes - funcId/refId: signed char, 1 byte - args: string seperated by space - Output is a list of records for one rank, where each record has the format - [status, tstart, tend, funcId/refId, [args]] - ''' - def decode(self, lines, rank): - records = [] - for line in lines: - status = struct.unpack('b', line[0:1])[0] - tstart = struct.unpack('i', line[1:5])[0] - tend = struct.unpack('i', line[5:9])[0] - res = struct.unpack('i', line[9:13])[0] - funcId = struct.unpack('B', line[13:14])[0] - args = line[15:].decode('utf-8').split(' ') - records.append(Record(rank, status, tstart, tend, funcId, args, res)) - - return records - - - ''' - Read one rank's trace file and return one line for each record - ''' - def read(self, path): - print(path) - lines = [] - with open(path, 'rb') as f: - content = f.read() - start_pos = 0 - end_pos = 0 - while True: - end_pos = content.find(b"\n", start_pos+10) - if end_pos == -1: - break - line = content[start_pos: end_pos] - lines.append(line) - start_pos = end_pos+1 - return lines