Example #1
0
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;
}
Example #2
0
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;
}