Commit 3641144c authored by Giovanni La Mura's avatar Giovanni La Mura
Browse files

Compute the ram overhead estimate at the beginning of inclusion()

parent 437d1a74
Loading
Loading
Loading
Loading
+60 −2
Original line number Diff line number Diff line
@@ -146,10 +146,12 @@ void inclusion(const string& config_file, const string& data_file, const string&
  }
  Logger *logger = new Logger(LOG_DEBG);
  int device_count = 0;
  const double ram_overhead_factor = get_ram_overhead();

#ifdef USE_MAGMA
  //===========
  // Initialise MAGMA
  //===========
#ifdef USE_MAGMA
  const magma_int_t d_array_max_size = 32; // TEMPORARY: can become configurable parameter
  magma_device_t *device_array = new magma_device_t[d_array_max_size];
  magma_int_t num_devices;
@@ -228,8 +230,64 @@ void inclusion(const string& config_file, const string& data_file, const string&
    int nsph = gconf->number_of_spheres;
    // Sanity check on number of sphere consistency, should always be verified
    if (s_nsph == nsph) {
      // Shortcuts to variables stored in configuration objects
      char virtual_line[256];
      sprintf(virtual_line, "%.5lg.\n", sconf->get_particle_radius(gconf));
      message = "INFO: particle radius is " + (string)virtual_line;
      logger->log(message);
      // Memory requirements test
      long cid_size_bytes = InclusionIterationData::get_size(gconf, sconf);
      double cid_size_gb = cid_size_bytes / 1024.0 / 1024.0 / 1024.0;
      sprintf(virtual_line, "%.5lg", cid_size_gb);
      message = "INFO: iteration data requires " + (string)virtual_line + "GiB of RAM.\n";
      logger->log(message);
      int omp_wavelength_threads = 1;
#ifdef _OPENMP
#pragma omp parallel
      {
	int threadId = omp_get_thread_num();
	if (threadId == 0) {
	  omp_wavelength_threads = omp_get_num_threads();
	}
      }
#endif //_OPENMP
      double requested_ram_gb = (ram_overhead_factor + omp_wavelength_threads) * cid_size_gb;
      sprintf(virtual_line, "%.5lg", requested_ram_gb);
      message = "INFO: code execution needs " + (string)virtual_line + "GiB of RAM.\n";
      logger->log(message);
      if (gconf->host_ram_gb > 0.0) {
	if (requested_ram_gb > gconf->host_ram_gb) {
	  // ERROR: host system does not have the necessary RAM
	  message = "ERROR: the requested model saturates the system RAM!\n";
	  logger->log(message);
	  fclose(timing_file);
	  delete time_logger;
	  delete logger;
	  delete sconf;
	  delete gconf;
	  exit(1);
	}
      }
      if (gconf->gpu_ram_gb > 0.0) {
	// mat_size_bytes = sizeof(dcomplex) * 2 * 2 * NSPH * NSPH * LI * LI * (LI + 2) * (LI + 2)
	long matrix_size_bytes = sizeof(dcomplex)
	  * 4 * gconf->number_of_spheres * gconf->number_of_spheres
	  * gconf->li * gconf->li * (gconf->li + 2) * (gconf->li + 2);
	double matrix_size_gb = matrix_size_bytes / 1024.0 / 1024.0 / 1024.0;
	int refinement_factor = (gconf->refine_flag) ? 3 : 1;
	if (refinement_factor * omp_wavelength_threads * matrix_size_gb > gconf->gpu_ram_gb) {
	  // ERROR: GPU does not have the necessary RAM
	  message = "ERROR: the requested model saturates the GPU RAM!\n";
	  logger->log(message);
	  fclose(timing_file);
	  delete time_logger;
	  delete logger;
	  delete sconf;
	  delete gconf;
	  exit(1);
	}
      }
      ScatteringAngles *p_scattering_angles = new ScatteringAngles(gconf);
      // Shortcuts to variables stored in configuration objects
      double wp = sconf->wp;
      // Open empty virtual ascii file for output
      InclusionOutputInfo *p_output = new InclusionOutputInfo(sconf, gconf, mpidata);