OSMAND_CORE_API QString OSMAND_CORE_CALL OsmAnd::ICU::convertToVisualOrder(const QString& input) { QString output; const auto len = input.length(); UErrorCode icuError = U_ZERO_ERROR; bool ok = true; // Allocate ICU BiDi context const auto pContext = ubidi_openSized(len, 0, &icuError); if(pContext == nullptr || !U_SUCCESS(icuError)) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } // Configure context to reorder from logical to visual ubidi_setReorderingMode(pContext, UBIDI_REORDER_DEFAULT); // Set data ubidi_setPara(pContext, reinterpret_cast<const UChar*>(input.unicode()), len, UBIDI_DEFAULT_RTL, nullptr, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reordered(len); ubidi_writeReordered(pContext, reordered.data(), len, UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &icuError); ok = U_SUCCESS(icuError); if(ok) { QVector<UChar> reshaped(len); const auto newLen = u_shapeArabic(reordered.constData(), len, reshaped.data(), len, U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_AT_END, &icuError); ok = U_SUCCESS(icuError); if(ok) { output = qMove(QString(reinterpret_cast<const QChar*>(reshaped.constData()), newLen)); } } } // Release context ubidi_close(pContext); if(!ok) { LogPrintf(LogSeverityLevel::Error, "ICU error: %d", icuError); return input; } return output; }
void TestMda::testSizes() { qsrand(time(0)); for (int i = 0; i < 100; ++i) { int dims[6]; int totalSize = 1; for (int k = 0; k < 6; ++k) { dims[k] = qrand() % 10 + 1; totalSize *= dims[k]; } const Mda m(dims[0], dims[1], dims[2], dims[3], dims[4], dims[5]); QVERIFY(verify_sizes(m, dims, "Mda(int[])")); const Mda clone(m); QVERIFY(verify_sizes(clone, dims, "Mda(const Mda&)")); Mda assigned; assigned = m; QVERIFY(verify_sizes(assigned, dims, "operator = ")); QTemporaryFile file; QVERIFY(file.open()); QVERIFY(m.write32(file.fileName())); const Mda fromFile(file.fileName()); QVERIFY(verify_sizes(fromFile, dims, "Mda(const QString&)")); Mda fromRead; fromRead.read(file.fileName()); QVERIFY(verify_sizes(fromRead, dims, "Mda.read(const QString&)")); Mda fromAllocate; fromAllocate.allocate(dims[0], dims[1], dims[2], dims[3], dims[4], dims[5]); QVERIFY(verify_sizes(fromAllocate, dims, "Mda.allocate()")); Mda reshaped(dims[0], dims[1], dims[2], dims[3], dims[4], dims[5]); reshaped.reshape(totalSize, 1); QCOMPARE(reshaped.N1(), totalSize); QCOMPARE(reshaped.N2(), 1L); QCOMPARE(reshaped.N3(), 1L); QCOMPARE(reshaped.N4(), 1L); QCOMPARE(reshaped.N5(), 1L); QCOMPARE(reshaped.totalSize(), totalSize); } }
int main(int argc, char* argv[]) { unsigned num_replicas = 8; bool verbose = false; // bool out_of_place = false; bool batched_plan = false; int num_threads = 0; std::string cpu_name; int num_repeats = 5; std::string stack_dims = ""; po::options_description desc("Allowed options"); //clang-format off desc.add_options() // ("help,h", "produce help message") // ("verbose,v", "print lots of information in between") // ("header-only,H", "print header of stats only") // // ("stack_dimensions,s", // po::value<std::string>(&stack_dims)->default_value("64x64x64"), // "HxWxD of synthetic stacks to generate") // // ("repeats,r", // po::value<int>(&num_repeats)->default_value(10), // "number of repetitions per measurement") // // ("num_replicas,n", // po::value<unsigned>(&num_replicas)->default_value(8), // "number of replicas to use for batched processing") // // ("num_threads,t", // po::value<int>(&num_threads)->default_value(1), // "number of threads to use") // // ("cpu_name,c", // po::value<std::string>(&cpu_name)->default_value("i7-3520M"), // "cpu name to use in output") // ; // //clang-format on po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help")) { std::cout << desc << "\n"; return 1; } if (vm.count("header-only")) { print_header(); return 0; } static const int max_threads = boost::thread::hardware_concurrency(); if(num_threads > max_threads) num_threads = max_threads; verbose = vm.count("verbose"); // out_of_place = vm.count("out-of-place"); batched_plan = vm.count("batched_plan"); std::vector<unsigned> numeric_stack_dims; split<'x'>(stack_dims, numeric_stack_dims); if (verbose) { std::cout << "received " << numeric_stack_dims.size() << " dimensions: "; for (unsigned i = 0; i < numeric_stack_dims.size(); ++i) { std::cout << numeric_stack_dims[i] << " "; } std::cout << "\n"; } if (numeric_stack_dims.size() != 3) { std::cerr << ">> " << numeric_stack_dims.size() << "-D data, not supported yet!\n"; return 1; } unsigned long data_size_byte = std::accumulate(numeric_stack_dims.begin(), numeric_stack_dims.end(), 1u, std::multiplies<unsigned long>()) * sizeof(float); unsigned long memory_available = data_size_byte; // later float exp_mem_mb = (data_size_byte) / float(1 << 20); exp_mem_mb *= num_replicas; float av_mem_mb = memory_available / float(1 << 20); // if(exp_mem_mb>av_mem_mb){ // std::cerr << "not enough memory available on device, needed " << // exp_mem_mb // <<" MB), available: " << av_mem_mb << " MB\n"; // return 1; // } else { if (verbose) std::cout << "[NOT IMPLEMENTED YET] memory estimate: needed " << exp_mem_mb << " MB), available: " << av_mem_mb << " MB\n"; // } std::vector<unsigned> reshaped(numeric_stack_dims); reshaped.back() = (reshaped.back() / 2 + 1) * 2; multiviewnative::image_kernel_data raw(numeric_stack_dims); multiviewnative::image_kernel_data reference = raw; inplace_cpu_convolution(reference.stack_.data(), &reference.stack_shape_[0], reference.kernel_.data(), &reference.kernel_shape_[0], num_threads); std::vector<multiviewnative::image_kernel_data> stacks(num_replicas,raw); if (verbose) { std::cout << "[config]\t" << "\n" << "num_replicas\t:\t" << num_replicas << "\nnumeric size\t:\t"; std::copy(numeric_stack_dims.begin(), numeric_stack_dims.end(), std::ostream_iterator<unsigned>(std::cout, " ")); std::cout << "\nfftw size\t:\t"; std::copy(reshaped.begin(), reshaped.end(), std::ostream_iterator<unsigned>(std::cout, " ")); std::cout << "\n"; } stacks[0] = raw; //start measurement std::vector<ns_t> durations(num_repeats); ns_t time_ns = ns_t(0); tp_t start, end; for (int r = 0; r < num_repeats; ++r) { for ( multiviewnative::image_kernel_data& s : stacks ){ s.stack_ = raw.stack_; s.kernel_ = raw.kernel_; } start = boost::chrono::high_resolution_clock::now(); //batched fold comes here if (num_threads == 1) inplace_cpu_batched_fold<mvn::cpu::serial_tag>(stacks); else{ convolve<mvn::cpu::parallel_tag>::transform_type::set_n_threads(num_threads); inplace_cpu_batched_fold<mvn::cpu::parallel_tag>(stacks); } end = boost::chrono::high_resolution_clock::now(); durations[r] = boost::chrono::duration_cast<ns_t>(end - start); time_ns += boost::chrono::duration_cast<ns_t>(end - start); if (verbose) { std::cout << r << "\t" << boost::chrono::duration_cast<ns_t>(durations[r]).count() / double(1e6) << " ms\n"; } } bool data_valid = std::equal(reference.stack_.data(), reference.stack_.data() + reference.stack_.num_elements(), stacks[0].stack_.data()); std::string implementation_name = __FILE__; std::string comments = "global_plan"; if(data_valid) comments += ",OK"; else comments += ",NA"; if(batched_plan) comments += ",batched"; if(verbose) print_header(); print_info(num_threads, implementation_name, cpu_name, num_repeats, time_ns.count() / double(1e6), numeric_stack_dims, sizeof(float), comments ); return 0; }