template <class T> void MRFEnergy<T>::AddEdge(NodeId i, NodeId j, EdgeData data) { if (m_isEnergyConstructionCompleted) { m_errorFn( const_cast<char *>("Error in AddNode(): graph construction completed - nodes cannot be added") ); } MRFEdge* e; int actualEdgeSize = Edge::GetSizeInBytes(m_Kglobal, i->m_K, j->m_K, data); if (actualEdgeSize < 0) { m_errorFn( const_cast<char *>("Error in AddEdge() (invalid parameter?)")); } int MRFedgeSize = sizeof(MRFEdge) - sizeof(Edge) + actualEdgeSize; e = (MRFEdge*) Malloc(MRFedgeSize); e->m_message.Initialize(m_Kglobal, i->m_K, j->m_K, data, &i->m_D, &j->m_D); e->m_tail = i; e->m_nextForward = i->m_firstForward; i->m_firstForward = e; e->m_head = j; e->m_nextBackward = j->m_firstBackward; j->m_firstBackward = e; m_edgeNum ++; }
unsigned CRunFile::outputThreadProc() { char buf[BUFSIZ*10]; int size; if(m_outFd>=0) SetBlock(m_outFd,false); if(m_errFd>=0) SetBlock(m_errFd,false); do { while(m_errFd>=0 && (size=read(m_errFd,buf,BUFSIZ*10))>0) { if(m_errorFn && m_errorFn != StandardError) m_errorFn(buf,size,m_errorData); if(m_debugFn) m_debugFn(2,buf,size,m_debugData); } while(m_outFd>=0 && (size=read(m_outFd,buf,BUFSIZ*10))>0) { if(m_outputFn && m_outputFn != StandardOutput) m_outputFn(buf,size,m_outputData); if(m_debugFn) m_debugFn(1,buf,size,m_debugData); } } while(WaitForSingleObject(m_hProcess,100)==WAIT_TIMEOUT); while(m_errFd>=0 && (size=read(m_errFd,buf,BUFSIZ*10))>0) { if(m_errorFn && m_errorFn != StandardError) m_errorFn(buf,size,m_errorData); if(m_debugFn) m_debugFn(2,buf,size,m_debugData); } while(m_outFd>=0 && (size=read(m_outFd,buf,BUFSIZ*10))>0) { if(m_outputFn && m_outputFn != StandardOutput) m_outputFn(buf,size,m_outputData); if(m_debugFn) m_debugFn(1,buf,size,m_debugData); } if(m_outFd>=0) close(m_outFd); if(m_errFd>=0) close(m_errFd); return 0; }
template <class T> typename MRFEnergy<T>::NodeId MRFEnergy<T>::AddNode(LocalSize K, NodeData data) { if (m_isEnergyConstructionCompleted) { m_errorFn(const_cast<char *>("Error in AddNode(): graph construction completed - nodes cannot be added")); } int actualVectorSize = Vector::GetSizeInBytes(m_Kglobal, K); if (actualVectorSize < 0) { m_errorFn( const_cast<char *>("Error in AddNode() (invalid parameter?)")); } if (m_vectorMaxSizeInBytes < actualVectorSize) { m_vectorMaxSizeInBytes = actualVectorSize; } int nodeSize = sizeof(Node) - sizeof(Vector) + actualVectorSize; Node* i = (Node *) Malloc(nodeSize); i->m_K = K; i->m_D.Initialize(m_Kglobal, K, data); i->m_firstForward = NULL; i->m_firstBackward = NULL; i->m_prev = m_nodeLast; if (m_nodeLast) { m_nodeLast->m_next = i; } else { m_nodeFirst = i; } m_nodeLast = i; i->m_next = NULL; i->m_ordering = m_nodeNum ++; return i; }
template <class T> void MRFEnergy<T>::CompleteGraphConstruction() { Node* i; Node* j; MRFEdge* e; MRFEdge* ePrev; if (m_isEnergyConstructionCompleted) { m_errorFn( const_cast<char *>("Fatal error in CompleteGraphConstruction") ); } //printf("Completing graph construction... "); if (m_buf) { m_errorFn( const_cast<char *>("CompleteGraphConstruction(): fatal error") ); } m_buf = (char *) Malloc(m_vectorMaxSizeInBytes + ( m_vectorMaxSizeInBytes > Edge::GetBufSizeInBytes(m_vectorMaxSizeInBytes) ? m_vectorMaxSizeInBytes : Edge::GetBufSizeInBytes(m_vectorMaxSizeInBytes) ) ); // set forward and backward edges properly #ifdef _DEBUG int ordering; for (i=m_nodeFirst, ordering=0; i; i=i->m_next, ordering++) { if ( (i->m_ordering != ordering) || (i->m_ordering == 0 && i->m_prev) || (i->m_ordering != 0 && i->m_prev->m_ordering != ordering-1) ) { m_errorFn("CompleteGraphConstruction(): fatal error (wrong ordering)"); } } if (ordering != m_nodeNum) { m_errorFn("CompleteGraphConstruction(): fatal error"); } #endif for (i=m_nodeFirst; i; i=i->m_next) { i->m_firstBackward = NULL; } for (i=m_nodeFirst; i; i=i->m_next) { ePrev = NULL; for (e=i->m_firstForward; e; ) { assert(i == e->m_tail); j = e->m_head; if (i->m_ordering < j->m_ordering) { e->m_nextBackward = j->m_firstBackward; j->m_firstBackward = e; ePrev = e; e = e->m_nextForward; } else { e->m_message.Swap(m_Kglobal, i->m_K, j->m_K); e->m_tail = j; e->m_head = i; MRFEdge* eNext = e->m_nextForward; if (ePrev) { ePrev->m_nextForward = e->m_nextForward; } else { i->m_firstForward = e->m_nextForward; } e->m_nextForward = j->m_firstForward; j->m_firstForward = e; e->m_nextBackward = i->m_firstBackward; i->m_firstBackward = e; e = eNext; } } } m_isEnergyConstructionCompleted = true; // ZeroMessages(); //printf("done\n"); }
template <class T> void MRFEnergy<T>::SetAutomaticOrdering() { int dMin; Node* i; Node* iMin; Node* list; Node* listBoundary; MRFEdge* e; if (m_isEnergyConstructionCompleted) { m_errorFn("Error in SetAutomaticOrdering(): function cannot be called after graph construction is completed"); } printf("Setting automatic ordering... "); list = m_nodeFirst; listBoundary = NULL; m_nodeFirst = m_nodeLast = NULL; for (i=list; i; i=i->m_next) { i->m_ordering = 2*m_nodeNum; // will contain remaining degree mod m_nodeNum (i.e. number of edges connecting to nodes in 'listBoundary' and 'list') // if i->m_ordering \in [2*m_nodeNum; 3*m_nodeNum) - not assigned yet, belongs to 'list' // if i->m_ordering \in [m_nodeNum; 2*m_nodeNum) - not assigned yet, belongs to 'listBoundary' // if i->m_ordering \in [0; m_nodeNum ) - assigned, belongs to 'm_nodeFirst' for (e=i->m_firstForward; e; e=e->m_nextForward) { i->m_ordering ++; } for (e=i->m_firstBackward; e; e=e->m_nextBackward) { i->m_ordering ++; } } while (list) { // find node with the smallest remaining degree in list dMin = m_nodeNum; for (i=list; i; i=i->m_next) { assert(i->m_ordering >= 2*m_nodeNum); if (dMin > i->m_ordering - 2*m_nodeNum) { dMin = i->m_ordering - 2*m_nodeNum; iMin = i; } } i = iMin; // remove i from list if (i->m_prev) i->m_prev->m_next = i->m_next; else list = i->m_next; if (i->m_next) i->m_next->m_prev = i->m_prev; // add i to listBoundary listBoundary = i; i->m_prev = NULL; i->m_next = NULL; i->m_ordering -= m_nodeNum; while (listBoundary) { // find node with the smallest remaining degree in listBoundary dMin = m_nodeNum; for (i=listBoundary; i; i=i->m_next) { assert(i->m_ordering >= m_nodeNum && i->m_ordering < 2*m_nodeNum); if (dMin > i->m_ordering - m_nodeNum) { dMin = i->m_ordering - m_nodeNum; iMin = i; } } i = iMin; // remove i from listBoundary if (i->m_prev) i->m_prev->m_next = i->m_next; else listBoundary = i->m_next; if (i->m_next) i->m_next->m_prev = i->m_prev; // add i to m_nodeFirst if (m_nodeLast) { m_nodeLast->m_next = i; i->m_ordering = m_nodeLast->m_ordering + 1; } else { m_nodeFirst = i; i->m_ordering = 0; } i->m_prev = m_nodeLast; m_nodeLast = i; i->m_next = NULL; // process neighbors of i=m_nodeLast: decrease their remaining degree, // put them into listBoundary (if they are in list) for (e=m_nodeLast->m_firstForward; e; e=e->m_nextForward) { assert(m_nodeLast == e->m_tail); i = e->m_head; if (i->m_ordering >= m_nodeNum) { i->m_ordering --; // decrease remaining degree of i if (i->m_ordering >= 2*m_nodeNum) { // remove i from list if (i->m_prev) i->m_prev->m_next = i->m_next; else list = i->m_next; if (i->m_next) i->m_next->m_prev = i->m_prev; // add i to listBoundary if (listBoundary) listBoundary->m_prev = i; i->m_prev = NULL; i->m_next = listBoundary; listBoundary = i; i->m_ordering -= m_nodeNum; } } } for (e=m_nodeLast->m_firstBackward; e; e=e->m_nextBackward) { assert(m_nodeLast == e->m_head); i = e->m_tail; if (i->m_ordering >= m_nodeNum) { i->m_ordering --; // decrease remaining degree of i if (i->m_ordering >= 2*m_nodeNum) { // remove i from list if (i->m_prev) i->m_prev->m_next = i->m_next; else list = i->m_next; if (i->m_next) i->m_next->m_prev = i->m_prev; // add i to listBoundary if (listBoundary) listBoundary->m_prev = i; i->m_prev = NULL; i->m_next = listBoundary; listBoundary = i; i->m_ordering -= m_nodeNum; } } } } } printf("done\n"); CompleteGraphConstruction(); }