/// <summary>Constructor</summary> /// /// <param name="symbol">IDiaSymbol to wrap. Symbol must be of type SymTagUDTType</summary> /// /// <exception cref="runtime_error">Thrown if an internal error occurs</exception> /// PdbTypeClass::PdbTypeClass(IDiaSymbol* symbol) { CHECKTAG(symbol, SymTagUDT, "PdbTypeClass"); // check it is a class DWORD kind; if (FAILED(symbol->get_udtKind(&kind))) { throwError(); } if (kind != UdtClass) { throw runtime_error("Attempt to make a PdbTypeClass out of something not a class"); } // remember the symbol this->symbol = symbol; }
/* run a queue depth detection test sending messages * of a message of size msgsz bytes and no acknowledgements - * messages are shoveled into a send queue of size up to queuesz, * as quickly as MPI will take them and injection rate is timed for each queue size */ void queuetest(int iters, int msgsz, int printoutput) { int iamsender = (rank % 2 == 0); int iamreceiver = !iamsender || peerid == rank; /* handle loopback */ MPI_Request *recvHandle = NULL; MPI_Request *sendHandle = NULL; char *sendbuffer = NULL; char *recvbuffer = NULL; MPI_Status *statustmp = malloc(sizeof(MPI_Status)*queuedepth); int depth; char row[1024]; char *prow = row; if (iamsender) { int i; sendbuffer = (char*)malloc(msgsz); sendHandle = (MPI_Request*)malloc(sizeof(MPI_Request)*queuedepth); assert(sendbuffer && sendHandle); for (i=0; i < queuedepth; i++) { sendHandle[i] = MPI_REQUEST_NULL; } sprintf(prow, "%-8i", msgsz); prow += strlen(prow); } if (iamreceiver) { recvbuffer = (char*)malloc(msgsz); recvHandle = (MPI_Request*)malloc(sizeof(MPI_Request)*queuedepth); assert(recvbuffer && recvHandle); } barrier(); for (depth = 1; depth <= queuedepth; depth *= 2) { int64_t totaltime = 0; int it; for (it = 0; it < iters; it++) { barrier(); if (iamreceiver) { /* prepost recieves */ int i; for (i=0; i < depth; i++) { recvHandle[i] = MPI_REQUEST_NULL; /* prepost recvs */ MPI_SAFE(MPI_Irecv(recvbuffer, msgsz, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvHandle[i])); assert(recvHandle[i] != MPI_REQUEST_NULL); } } barrier(); if (iamsender) { int i; int64_t starttime, endtime; /* measure time to inject depth operations of payload sz */ starttime = getMicrosecondTimeStamp(); for (i=0; i < depth; i++) { MPI_SAFE(MPI_Isend(sendbuffer, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD, &sendHandle[i])); assert(sendHandle[i] != MPI_REQUEST_NULL); } endtime = getMicrosecondTimeStamp(); totaltime += (endtime - starttime); } if (iamreceiver) { /* complete nb recvs */ int i; MPI_SAFE(MPI_Waitall(depth, recvHandle, statustmp)); for (i=0; i < depth; i++) { CHECKTAG(statustmp[i].MPI_TAG); } } if (iamsender) { /* complete nb sends */ MPI_SAFE(MPI_Waitall(depth, sendHandle, statustmp)); } } if (iamsender) { /* output */ double avgus = totaltime / (double)iters / (double)depth; int prec; if (avgus < 1000.0) prec = 3; else if (avgus < 10000.0) prec = 2; else if (avgus < 100000.0) prec = 1; else prec = 0; sprintf(prow, " %7.*f", prec, avgus); prow += strlen(prow); } } if (iamsender && printoutput) { printf("%s\n", row); fflush(stdout); } if (recvHandle) free(recvHandle); if (sendHandle) free(sendHandle); if (sendbuffer) free(sendbuffer); if (recvbuffer) free(recvbuffer); free(statustmp); return; }
/* run a pairwise flood test sending iters messages * of a message of size msgsz bytes and no acknowledgements - * messages are shoveled into a send queue of size queuesz, * as quickly as MPI will take them * uses nonblocking recvs and nonblocking sends * returns the total number of microseconds consumed during the test */ double floodtest(int iters, int msgsz) { int numsent = 0, numrecvd = 0, numrecvposted = 0; int64_t starttime, endtime; int iamsender = (rank % 2 == 0); int iamreceiver = !iamsender || peerid == rank; /* handle loopback */ MPI_Request *recvHandle = NULL; MPI_Request *sendHandle = NULL; char *sendbuffer = NULL; char *recvbuffer = NULL; int *indextmp = malloc(sizeof(int)*queuedepth); MPI_Status *statustmp = malloc(sizeof(MPI_Status)*queuedepth); if (iters < queuedepth) { fprintf(stderr, "ERROR: iters must be >= queuedepth\n"); abort(); } if (iamsender) { int i; sendbuffer = (char*)malloc(msgsz*queuedepth); sendHandle = (MPI_Request*)malloc(sizeof(MPI_Request)*queuedepth); assert(sendbuffer && sendHandle); for (i=0; i < queuedepth; i++) { sendHandle[i] = MPI_REQUEST_NULL; } } if (iamreceiver) { recvbuffer = (char*)malloc(msgsz*queuedepth); recvHandle = (MPI_Request*)malloc(sizeof(MPI_Request)*queuedepth); assert(recvbuffer && recvHandle); while(numrecvposted < queuedepth && numrecvposted < iters) { recvHandle[numrecvposted] = MPI_REQUEST_NULL; /* prepost recvs */ MPI_SAFE(MPI_Irecv(BUFFER_CALC(recvbuffer,msgsz*numrecvposted), msgsz, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvHandle[numrecvposted])); assert(recvHandle[numrecvposted] != MPI_REQUEST_NULL); numrecvposted++; } } barrier(); starttime = getMicrosecondTimeStamp(); if (iamsender) { /* fill the outgoing pipe */ while (numsent < iters && numsent < queuedepth) { char *buf = BUFFER_CALC(sendbuffer,msgsz*numsent); WRITEMSG(buf, msgsz); MPI_SAFE(MPI_Isend(buf, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD, &sendHandle[numsent])); assert(sendHandle[numsent] != MPI_REQUEST_NULL); numsent++; } } while ( (iamsender && numsent < iters) || (iamreceiver && numrecvd < iters)) { if (iamreceiver) { int numcomplete = 0; /* reap any completions and do more recvs */ MPI_SAFE(mpi_testwait_some(queuedepth, recvHandle, &numcomplete, indextmp, statustmp)); while (numcomplete != MPI_UNDEFINED && numcomplete > 0) { int idx = indextmp[--numcomplete]; char *buf = BUFFER_CALC(recvbuffer,msgsz*idx); CHECKTAG(statustmp[numcomplete].MPI_TAG); READMSG(buf, msgsz); numrecvd++; assert(recvHandle[idx] == MPI_REQUEST_NULL); if (numrecvposted < iters) { /* not done yet - recv another */ MPI_SAFE(MPI_Irecv(buf, msgsz, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvHandle[idx])); assert(recvHandle[idx] != MPI_REQUEST_NULL); numrecvposted++; } } } if (iamsender) { int numcomplete = 0; /* reap any completions and do more sends */ MPI_SAFE(mpi_testwait_some(queuedepth, sendHandle, &numcomplete, indextmp, statustmp)); while (numcomplete != MPI_UNDEFINED && numcomplete > 0) { int idx = indextmp[--numcomplete]; char *buf = BUFFER_CALC(sendbuffer,msgsz*idx); assert(sendHandle[idx] == MPI_REQUEST_NULL); if (numsent < iters) { /* not done yet - send another */ WRITEMSG(buf, msgsz); MPI_SAFE(MPI_Isend(buf, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD, &sendHandle[idx])); assert(sendHandle[idx] != MPI_REQUEST_NULL); numsent++; } } } } if (iamsender) { /* pause for all sends to complete locally */ MPI_SAFE(MPI_Waitall(queuedepth, sendHandle, statustmp)); } endtime = getMicrosecondTimeStamp(); if (recvHandle) free(recvHandle); if (sendHandle) free(sendHandle); if (sendbuffer) free(sendbuffer); if (recvbuffer) free(recvbuffer); free(indextmp); free(statustmp); return (double)(endtime - starttime); }
double pingpongtest(int iters, int msgsz) { int i; int64_t starttime, endtime; int iamsender = (rank % 2 == 0); int iamreceiver = !iamsender || peerid == rank; /* handle loopback */ char *sendMsgbuffer = (char*)malloc(msgsz); char *sendAckbuffer = (char*)malloc(msgsz); char *recvMsgbuffer = (char*)malloc(msgsz); char *recvAckbuffer = (char*)malloc(msgsz); MPI_Request recvMsgHandle = MPI_REQUEST_NULL; MPI_Request recvAckHandle = MPI_REQUEST_NULL; MPI_Request sendMsgHandle = MPI_REQUEST_NULL; MPI_Request sendAckHandle = MPI_REQUEST_NULL; MPI_Status status; #if USE_ZERO_BYTE_ACK #define ACKSZ 0 #else #define ACKSZ msgsz #endif if (iamreceiver) { /* prepost a recv */ MPI_SAFE(MPI_Irecv(recvMsgbuffer, msgsz, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvMsgHandle)); } barrier(); starttime = getMicrosecondTimeStamp(); for (i=0; i < iters; i++) { if (iamsender) { /* send message */ WRITEMSG(sendMsgbuffer, msgsz); #if USE_ISEND MPI_SAFE(MPI_Isend(sendMsgbuffer, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD, &sendMsgHandle)); #else MPI_SAFE(MPI_Send(sendMsgbuffer, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD)); #endif /* prepost a recv for acknowledgement */ MPI_SAFE(MPI_Irecv(recvAckbuffer, ACKSZ, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvAckHandle)); #if USE_ISEND MPI_SAFE(MPI_Wait(&sendMsgHandle, &status)); #endif } if (iamreceiver) { /* wait for message */ #if USE_TEST int flag = 0; while (!flag) MPI_SAFE(MPI_Test(&recvMsgHandle, &flag, &status)); #else MPI_SAFE(MPI_Wait(&recvMsgHandle, &status)); #endif CHECKTAG(status.MPI_TAG); READMSG(recvMsgbuffer, msgsz); /* send acknowledgement */ WRITEMSG(sendAckbuffer, 1); #if USE_ISEND MPI_SAFE(MPI_Isend(sendAckbuffer, ACKSZ, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD, &sendAckHandle)); #else MPI_SAFE(MPI_Send(sendAckbuffer, ACKSZ, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD)); #endif /* pre-post recv for next message */ MPI_SAFE(MPI_Irecv(recvMsgbuffer, msgsz, MPI_BYTE, peerid, MPI_ANY_TAG, MPI_COMM_WORLD, &recvMsgHandle)); #if USE_ISEND MPI_SAFE(MPI_Wait(&sendAckHandle, &status)); #endif } if (iamsender) { /* wait for acknowledgement */ MPI_SAFE(MPI_Wait(&recvAckHandle, &status)); CHECKTAG(status.MPI_TAG); READMSG(recvAckbuffer, 1); } } endtime = getMicrosecondTimeStamp(); /* last recv must be cancelled (not included in timing) */ #if 0 if (iamreceiver) MPI_SAFE(MPI_Cancel(&recvMsgHandle)); #else /* apparently some MPI impls don't implement cancel at all.. (grr..) */ /* use an extra send instead to get the same effect */ if (iamsender) MPI_SAFE(MPI_Send(sendMsgbuffer, msgsz, MPI_BYTE, peerid, peermpitag, MPI_COMM_WORLD)); #endif if (iamreceiver) MPI_SAFE(MPI_Wait(&recvMsgHandle, &status)); free(sendMsgbuffer); free(sendAckbuffer); free(recvMsgbuffer); free(recvAckbuffer); return (double)(endtime - starttime); }