/* * Read the configuration script, allocating and filling in the structure of * global parameters. */ IOR_test_t *ReadConfigScript(char *scriptName) { int test_num = 0; int runflag = 0; char linebuf[MAX_STR]; char empty[MAX_STR]; FILE *file; IOR_test_t *head = NULL; IOR_test_t *tail = NULL; IOR_test_t *newTest = NULL; /* Initialize the first test */ head = CreateTest(&initialTestParams, test_num++); tail = head; /* open the script */ file = fopen(scriptName, "r"); if (file == NULL) ERR("fopen() failed"); /* search for the "IOR START" line */ while (fgets(linebuf, MAX_STR, file) != NULL) { if (contains_only(linebuf, "ior start")) { break; } } /* Iterate over a block of IOR commands */ while (fgets(linebuf, MAX_STR, file) != NULL) { /* skip empty lines */ if (sscanf(linebuf, "%s", empty) == -1) continue; /* skip lines containing only comments */ if (sscanf(linebuf, " #%s", empty) == 1) continue; if (contains_only(linebuf, "ior stop")) { AllocResults(tail); break; } else if (contains_only(linebuf, "run")) { AllocResults(tail); runflag = 1; } else if (runflag) { /* If this directive was preceded by a "run" line, then create and initialize a new test structure */ runflag = 0; tail->next = CreateTest(&tail->params, test_num++); tail = tail->next; ParseLine(linebuf, &tail->params); } else { ParseLine(linebuf, &tail->params); } } /* close the script */ if (fclose(file) != 0) ERR("fclose() of script file failed"); return head; }
void AuditBuffer<T>::assert_guard_bytes() const { for (unsigned p = 0; p < (m_color ? 3U : 1U); ++p) { ASSERT_TRUE(contains_only(m_vector[p].begin(), m_vector[p].begin() + stride_T(p), m_guard_val)) << "header guard bytes corrupted"; for (unsigned i = 0; i < m_buffer_height[p]; ++i) { const T *line_base = (const T *)m_buffer.data[p] + (ptrdiff_t)i * stride_T(p); const T *line_guard_left = line_base - zimg::AlignmentOf<T>::value; const T *line_guard_right = line_guard_left + stride_T(p); ASSERT_TRUE(contains_only(line_guard_left, line_base, m_guard_val)) << "line guard header corrupted at: " << i; ASSERT_TRUE(contains_only(line_base + m_width[p], line_guard_right, m_guard_val)) << "line guard footer corrupted at: " << i; } ASSERT_TRUE(contains_only(m_vector[p].end() - stride_T(p), m_vector[p].end(), m_guard_val)) << "footer guard bytes corrupted"; } }
bool AuditBuffer<T>::detect_write(unsigned i, unsigned left, unsigned right) const { bool write = true; for (unsigned p = 0; p < (m_color ? 3U : 1U); ++p) { zimg::LineBuffer<const T> linebuf{ m_buffer, p }; unsigned i_plane = i >> (p ? m_subsample_h : 0); unsigned left_plane = left >> (p ? m_subsample_w : 0); unsigned right_plane = right >> (p ? m_subsample_h : 0); write = write && !contains_only(linebuf[i_plane] + left_plane, linebuf[i_plane] + right_plane, m_fill_val[p]); } return write; }
// Cast num/den to an int, rounding towards nearest. All inputs are destroyed. Take a sqrt if desired. // The values array must consist of r numerators followed by one denominator. void snap_divs(RawArray<Quantized> result, RawArray<mp_limb_t,2> values, const bool take_sqrt) { assert(result.size()+1==values.m); // For division, we seek x s.t. // x-1/2 <= num/den <= x+1/2 // 2x-1 <= 2num/den <= 2x+1 // 2x-1 <= floor(2num/den) <= 2x+1 // 2x <= 1+floor(2num/den) <= 2x+2 // x <= (1+floor(2num/den))//2 <= x+1 // x = (1+floor(2num/den))//2 // In the sqrt case, we seek a nonnegative integer x s.t. // x-1/2 <= sqrt(num/den) < x+1/2 // 2x-1 <= sqrt(4num/den) < 2x+1 // Now the leftmost and rightmost expressions are integral, so we can take floors to get // 2x-1 <= floor(sqrt(4num/den)) < 2x+1 // Since sqrt is monotonic and maps integers to integers, floor(sqrt(floor(x))) = floor(sqrt(x)), so // 2x-1 <= floor(sqrt(floor(4num/den))) < 2x+1 // 2x <= 1+floor(sqrt(floor(4num/den))) < 2x+2 // x <= (1+floor(sqrt(floor(4num/den))))//2 < x+1 // x = (1+floor(sqrt(floor(4num/den))))//2 // Thus, both cases look like // x = (1+f(2**k*num/den))//2 // where k = 1 or 2 and f is some truncating integer op (division or division+sqrt). // Adjust denominator to be positive const auto raw_den = values[result.size()]; const bool den_negative = mp_limb_signed_t(raw_den.back())<0; if (den_negative) mpn_neg(raw_den.data(),raw_den.data(),raw_den.size()); const auto den = trim(raw_den); assert(den.size()); // Zero should be prevented by the caller // Prepare for divisions const auto q = GEODE_RAW_ALLOCA(values.n-den.size()+1,mp_limb_t), r = GEODE_RAW_ALLOCA(den.size(),mp_limb_t); // Compute each component of the result for (int i=0;i<result.size();i++) { // Adjust numerator to be positive const auto num = values[i]; const bool num_negative = mp_limb_signed_t(num.back())<0; if (take_sqrt && num_negative!=den_negative && !num.contains_only(0)) throw RuntimeError("perturbed_ratio: negative value in square root"); if (num_negative) mpn_neg(num.data(),num.data(),num.size()); // Add enough bits to allow round-to-nearest computation after performing truncating operations mpn_lshift(num.data(),num.data(),num.size(),take_sqrt?2:1); // Perform division mpn_tdiv_qr(q.data(),r.data(),0,num.data(),num.size(),den.data(),den.size()); const auto trim_q = trim(q); if (!trim_q.size()) { result[i] = 0; continue; } // Take sqrt if desired, reusing the num buffer const auto s = take_sqrt ? sqrt_helper(num,trim_q) : trim_q; // Verify that result lies in [-exact::bound,exact::bound]; const int ratio = sizeof(ExactInt)/sizeof(mp_limb_t); static_assert(ratio<=2,""); if (s.size() > ratio) goto overflow; const auto nn = ratio==2 && s.size()==2 ? s[0]|ExactInt(s[1])<<8*sizeof(mp_limb_t) : s[0], n = (1+nn)/2; if (uint64_t(n) > uint64_t(exact::bound)) goto overflow; // Done! result[i] = (num_negative==den_negative?1:-1)*Quantized(n); } return; overflow: throw OverflowError("perturbed_ratio: overflow in l'Hopital expansion"); }