| 90 | #if _OPENMP |
| 91 | |
| 92 | void Mod::SuggestShape_( // args same as non OpenMP version, see below |
| 93 | Shape& shape, // io |
| 94 | int ilev, // in |
| 95 | const Image& img, // in |
| 96 | const Shape& pinned) // in |
| 97 | const |
| 98 | { |
| 99 | static bool firsttime = true; |
| 100 | int ncatch = 0; |
| 101 | const Shape inshape(shape.clone()); |
| 102 | |
| 103 | // Call the search function DescSearch_ concurrently for multiple points. |
| 104 | // Note that dynamic OpenMP scheduling is faster here than static, |
| 105 | // because the time through the loop varies widely (mainly because |
| 106 | // classic descriptors are faster than HATs). |
| 107 | |
| 108 | #pragma omp parallel for schedule(dynamic) |
| 109 | |
| 110 | for (int ipoint = 0; ipoint < shape.rows; ipoint++) |
| 111 | if (pinned.rows == 0 || !PointUsed(pinned, ipoint)) // skip point if pinned |
| 112 | { |
| 113 | // You are not allowed to jump out of an OpenMP for loop. Thus |
| 114 | // we need this try block, to subsume the global try blocks in |
| 115 | // stasm_lib.cpp. Without this try, a call to Err would cause |
| 116 | // a jump to the global catch. |
| 117 | |
| 118 | try |
| 119 | { |
| 120 | if (firsttime && omp_get_thread_num() == 0) |
| 121 | { |
| 122 | firsttime = false; |
| 123 | logprintf("[nthreads %d]", omp_get_num_threads()); |
| 124 | } |
| 125 | descmods_[ilev][ipoint]-> |
| 126 | DescSearch_(shape(ipoint, IX), shape(ipoint, IY), |
| 127 | img, inshape, ilev, ipoint); |
| 128 | } |
| 129 | catch(...) |
| 130 | { |
| 131 | ncatch++; // a call was made to Err or a CV_Assert failed |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | if (ncatch) |
| 136 | { |
| 137 | if (ncatch > 1) |
| 138 | lprintf_always("\nMultiple errors, only the first will be printed\n"); |
| 139 | // does not matter what we throw, will be caught by global catch |
| 140 | throw "SuggestShape_"; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | #else // not _OPENMP |
| 145 |
nothing calls this directly
no test coverage detected