jint 
eventFilter_setFieldOnlyFilter(HandlerNode *node, jint index, 
                               jclass clazz, jfieldID field)
{
    JNIEnv *env = getEnv();
    FieldFilter *filter = &FILTER(node, index).u.FieldOnly;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((KIND(node) != JVMDI_EVENT_FIELD_ACCESS) && 
        (KIND(node) != JVMDI_EVENT_FIELD_MODIFICATION)) {

        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    clazz = (*env)->NewGlobalRef(env, clazz);
    if (clazz == NULL) {
        return JVMDI_ERROR_OUT_OF_MEMORY;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(FieldOnly);
    filter->clazz = clazz;
    filter->field = field;
    return JVMDI_ERROR_NONE;
}
jint 
eventFilter_setClassOnlyFilter(HandlerNode *node, jint index, 
                               jclass clazz)
{
    JNIEnv *env = getEnv();
    ClassFilter *filter = &FILTER(node, index).u.ClassOnly;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((KIND(node) == JVMDI_EVENT_USER_DEFINED) || 
        (KIND(node) == JVMDI_EVENT_CLASS_UNLOAD) ||
        (KIND(node) == JVMDI_EVENT_THREAD_START) ||
        (KIND(node) == JVMDI_EVENT_THREAD_END)) {

        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    clazz = (*env)->NewGlobalRef(env, clazz);
    if (clazz == NULL) {
        return JVMDI_ERROR_OUT_OF_MEMORY;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(ClassOnly);
    filter->clazz = clazz;
    return JVMDI_ERROR_NONE;
}
/**
 * Clear a watchpoint if this is the last one on this field.
 */
static jint
clearWatchpoint(HandlerNode *node)
{
    jint error = JVMDI_ERROR_NONE;
    Filter *filter;

    filter = findFilter(node, JDWP_REQUEST_MODIFIER(FieldOnly));
    if (filter == NULL) {
        /* event with no field filter */
        error = JVMDI_ERROR_INTERNAL; 
    } else {
        FieldFilter *ff = &(filter->u.FieldOnly);

        /* if this is the last handler for this 
         * field, clear wp at jvmdi level 
         */
        if (!eventHandlerRestricted_iterator(
                KIND(node), matchWatchpoint, ff)) {
            error = (KIND(node) == JVMDI_EVENT_FIELD_ACCESS) ?
                jvmdi->ClearFieldAccessWatch(ff->clazz, 
                                             ff->field) :
                jvmdi->ClearFieldModificationWatch(ff->clazz,
                                                   ff->field);
        }
    }
    return error;
}
jint 
eventFilter_setLocationOnlyFilter(HandlerNode *node, jint index, 
                                  jclass clazz, jmethodID method,
                                  jlocation location)
{
    JNIEnv *env = getEnv();
    LocationFilter *filter = &FILTER(node, index).u.LocationOnly;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((KIND(node) != JVMDI_EVENT_BREAKPOINT) && 
        (KIND(node) != JVMDI_EVENT_FIELD_ACCESS) && 
        (KIND(node) != JVMDI_EVENT_FIELD_MODIFICATION) && 
        (KIND(node) != JVMDI_EVENT_SINGLE_STEP) && 
        (KIND(node) != JVMDI_EVENT_EXCEPTION)) {

        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a class ref that will live beyond */
    /* the end of this call */
    clazz = (*env)->NewGlobalRef(env, clazz);
    if (clazz == NULL) {
        return JVMDI_ERROR_OUT_OF_MEMORY;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(LocationOnly);
    filter->clazz = clazz;
    filter->method = method;
    filter->location = location;
    return JVMDI_ERROR_NONE;
}
Beispiel #5
0
void 
CalcBitCost (WordData ** discard_word, int discard_num,
	     WordData ** keep_word, int keep_num, double freqs_trans[2],
	     u_long escape[2], int num_trans)
{
  char *char_lens[2];
  char *len_lens[2];
  double esc[2];
  int j;
  CalcCharCounts (discard_word, discard_num, char_lens, len_lens, escape);
  esc[0] = -log2 (escape[0] / (freqs_trans[0] + escape[0]));
  esc[1] = -log2 (escape[1] / (freqs_trans[1] + escape[1]));
  for (j = 0; j < discard_num; j++, discard_word++)
    {
      float cbc, wbc;
      u_char *buf = (*discard_word)->word;
      int len = *buf++;
      u_long freq = (*discard_word)->freq;
      int idx = KIND (*discard_word);

      cbc = len_lens[idx][len];
      for (; len; len--, buf++)
	cbc += char_lens[idx][(u_long) (*buf)];

      (*discard_word)->char_bit_cost = (cbc + esc[idx]) * freq;

      wbc = -log2 (freq / (freqs_trans[idx] + escape[idx])) * freq;

      (*discard_word)->saving = ((*discard_word)->char_bit_cost - wbc) /
	(sizeof (char *) + (*discard_word)->word[0]);

      (*discard_word)->num_trans = num_trans;
    }
  for (j = 0; j < keep_num; j++, keep_word++)
    {
      float cbc, wbc;
      u_char *buf = (*keep_word)->word;
      int len = *buf++;
      u_long freq = (*keep_word)->freq;
      int idx = KIND (*keep_word);

      cbc = len_lens[idx][len];
      for (; len; len--, buf++)
	cbc += char_lens[idx][(u_long) (*buf)];

      (*keep_word)->char_bit_cost = (cbc + esc[idx]) * freq;

      wbc = -log2 (freq / (freqs_trans[idx] + escape[idx])) * freq;

      (*keep_word)->saving = ((*keep_word)->char_bit_cost - wbc) /
	(sizeof (char *) + (*keep_word)->word[0]);

      (*keep_word)->num_trans = num_trans;
    }
  Xfree (char_lens[0]);
  Xfree (char_lens[1]);
  Xfree (len_lens[0]);
  Xfree (len_lens[1]);
}
Beispiel #6
0
static void 
Select_on (int k, heap_comp hc)
{
  int i, num, mem;
  WordData **wd;

  Alloc_keep_discard ();

  num = Num[0] + Num[1];
  wd = Xmalloc (num * sizeof (WordData *));
  for (i = 0; i < Num[0]; i++)
    wd[i] = Words[0] + i;
  for (i = 0; i < Num[1]; i++)
    wd[i + Num[0]] = Words[1] + i;

  heap_build (wd, sizeof (*wd), num, hc);

  mem = 0;
  while (k > mem && num)
    {
      int idx;
      WordData *word = wd[0];
#ifdef DEBUG
      fprintf (stderr, "%4d:%4d:%8d :%8d :%8d : \"%s\"\n",
	       keep[0].num_wds, keep[1].num_wds,
	       mem, word->freq, word->occur_num, word2str (word->word));
#endif
      mem += sizeof (u_char *) + word->word[0];
      heap_deletehead (wd, sizeof (*wd), &num, hc);
      idx = KIND (word);
      keep[idx].wd[keep[idx].num_wds++] = word;
    }

  for (i = 0; i < num; i++)
    {
      WordData *word = wd[i];
      int idx = KIND (word);
      discard[idx].wd[discard[idx].num_wds++] = word;
    }
  SortAndCount_DictData (&keep[0]);
  SortAndCount_DictData (&keep[1]);
  SortAndCount_DictData (&discard[0]);
  SortAndCount_DictData (&discard[1]);

  assert (keep[0].num_wds + discard[0].num_wds == Num[0]);
  assert (keep[1].num_wds + discard[1].num_wds == Num[1]);

}
Beispiel #7
0
static void 
CalcCharCounts (WordData ** wd, int num,
		char *char_lens[2], char *len_lens[2],
		u_long escape[2])
{
  long char_freqs[2][256];
  long len_freqs[2][16];
  huff_data hd;
  int i;
  escape[0] = 0;
  escape[1] = 0;
  bzero ((char *) char_freqs, sizeof (char_freqs));
  bzero ((char *) len_freqs, sizeof (len_freqs));
  for (i = 0; i < num; i++, wd++)
    {
      u_long freq = (*wd)->freq;
      u_char *buf = (*wd)->word;
      int len = *buf++;
      int idx = KIND (*wd);
      len_freqs[idx][len] += freq;
      escape[idx] += freq;
      for (; len; len--, buf++)
	char_freqs[idx][(u_long) (*buf)] += freq;
    }
  Generate_Huffman_Data (256, char_freqs[0], &hd, NULL);
  char_lens[0] = hd.clens;
  Generate_Huffman_Data (256, char_freqs[1], &hd, NULL);
  char_lens[1] = hd.clens;

  Generate_Huffman_Data (16, len_freqs[0], &hd, NULL);
  len_lens[0] = hd.clens;
  Generate_Huffman_Data (16, len_freqs[1], &hd, NULL);
  len_lens[1] = hd.clens;
}
jint 
eventFilter_setStepFilter(HandlerNode *node, jint index, 
                          jthread thread, jint size, jint depth)
{
    jint error;
    JNIEnv *env = getEnv();
    StepFilter *filter = &FILTER(node, index).u.Step;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if (KIND(node) != JVMDI_EVENT_SINGLE_STEP) { 
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    /* Create a thread ref that will live beyond */
    /* the end of this call */
    thread = (*env)->NewGlobalRef(env, thread);
    if (thread == NULL) {
        return JVMDI_ERROR_OUT_OF_MEMORY;
    }
    error = stepControl_beginStep(thread, size,depth, node);
    if (error != JVMDI_ERROR_NONE) {
        (*env)->DeleteGlobalRef(env, thread);
        return error;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(Step);
    filter->thread = thread;
    filter->depth = depth;
    filter->size = size;
    return JVMDI_ERROR_NONE;
}
jint 
eventFilter_setExceptionOnlyFilter(HandlerNode *node, jint index, 
                                   jclass exceptionClass, 
                                   jboolean caught,
                                   jboolean uncaught)
{
    JNIEnv *env = getEnv();
    ExceptionFilter *filter = &FILTER(node, index).u.ExceptionOnly;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if (KIND(node) != JVMDI_EVENT_EXCEPTION) { 
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    if (exceptionClass != NULL) {
        /* Create a class ref that will live beyond */
        /* the end of this call */
        exceptionClass = (*env)->NewGlobalRef(env, exceptionClass);
        if (exceptionClass == NULL) {
            return JVMDI_ERROR_OUT_OF_MEMORY;
        }
    }
    FILTER(node, index).modifier = 
                       JDWP_REQUEST_MODIFIER(ExceptionOnly);
    filter->exception = exceptionClass;
    filter->caught = caught;
    filter->uncaught = uncaught;
    return JVMDI_ERROR_NONE;
}
/**
 * Do any disabling of events (including clearing breakpoints etc)
 * needed to no longer get the events requested by this handler node.
 */
static jint
disableEvents(HandlerNode *node)
{
    jint error = JVMDI_ERROR_NONE;
    jint error2 = JVMDI_ERROR_NONE;
    jthread thread;


    switch (KIND(node)) {
        /* The stepping code directly enables/disables stepping as
         * necessary 
         */
        case JVMDI_EVENT_SINGLE_STEP:
        /* Internal thread event handlers are always present
         * (hardwired in the event hook), so we don't change the
         * notification mode here.  
         */
        case JVMDI_EVENT_THREAD_START:
        case JVMDI_EVENT_THREAD_END:
            return error;

        case JVMDI_EVENT_FIELD_ACCESS:
        case JVMDI_EVENT_FIELD_MODIFICATION:
            error = clearWatchpoint(node);
            break;

        case JVMDI_EVENT_BREAKPOINT:
            error = clearBreakpoint(node);
            break;
    }

    thread = requestThread(node);

    /* If this is the last request of it's kind on this thread
     * (or all threads (thread == NULL)) then disable these
     * events on this thread.
     *
     * Disable even if the above caused an error
     */
    if (!eventHandlerRestricted_iterator(KIND(node), matchThread, thread)) {
        error2 = threadControl_setEventMode(JVMDI_DISABLE, 
                                            KIND(node), thread);
    }
    return error != JVMDI_ERROR_NONE? error : error2;
}
/**
 * Do any enabling of events (including setting breakpoints etc)
 * needed to get the events requested by this handler node.
 */
static jint
enableEvents(HandlerNode *node)
{
    jint error = JVMDI_ERROR_NONE;

    switch (KIND(node)) {
        /* The stepping code directly enables/disables stepping as
         * necessary 
         */
        case JVMDI_EVENT_SINGLE_STEP:
        /* Internal thread event handlers are always present
         * (hardwired in the event hook), so we don't change the
         * notification mode here.  
         */
        case JVMDI_EVENT_THREAD_START:
        case JVMDI_EVENT_THREAD_END:
            return error;

        case JVMDI_EVENT_FIELD_ACCESS:
        case JVMDI_EVENT_FIELD_MODIFICATION:
            error = setWatchpoint(node);
            break;

        case JVMDI_EVENT_BREAKPOINT:
            error = setBreakpoint(node);
            break;
    }

    /* Don't globally enable if the above failed */
    if (error == JVMDI_ERROR_NONE) {
        jthread thread = requestThread(node);

        /* If this is the first request of it's kind on this
         * thread (or all threads (thread == NULL)) then enable
         * these events on this thread.
         */
        if (!eventHandlerRestricted_iterator(
                KIND(node), matchThread, thread)) {
            error = threadControl_setEventMode(JVMDI_ENABLE, 
                                               KIND(node), thread);
        }
    }
    return error;
}
jint 
eventFilter_setClassExcludeFilter(HandlerNode *node, jint index, 
                                  char *classPattern)
{
    MatchFilter *filter = &FILTER(node, index).u.ClassExclude;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if ((KIND(node) == JVMDI_EVENT_USER_DEFINED) || 
        (KIND(node) == JVMDI_EVENT_THREAD_START) ||
        (KIND(node) == JVMDI_EVENT_THREAD_END)) {

        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }

    FILTER(node, index).modifier = 
                       JDWP_REQUEST_MODIFIER(ClassExclude);
    filter->classPattern = classPattern;
    return JVMDI_ERROR_NONE;
}
jint 
eventFilter_setThreadOnlyFilter(HandlerNode *node, jint index,
                                jthread thread)
{
    JNIEnv *env = getEnv();
    ThreadFilter *filter = &FILTER(node, index).u.ThreadOnly;
    if (index >= FILTER_COUNT(node)) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    }
    if (KIND(node) == JVMDI_EVENT_CLASS_UNLOAD) {
        return JVMDI_ERROR_ILLEGAL_ARGUMENT;
    } 
    
    /* Create a thread ref that will live beyond */
    /* the end of this call */
    thread = (*env)->NewGlobalRef(env, thread);
    if (thread == NULL) {
        return JVMDI_ERROR_OUT_OF_MEMORY;
    }
    FILTER(node, index).modifier = JDWP_REQUEST_MODIFIER(ThreadOnly);
    filter->thread = thread;
    return JVMDI_ERROR_NONE;
}
Beispiel #14
0
static void 
Method3 (int k)
{
  int i, keep_num, discard_num, mem, num_trans, recalc_reqd;
  int keep_to_discard = 0;
  int discard_to_keep = 0;
  int recalcs = 0;
  double freqs_trans[2], total;
  u_long escape[2];
  WordData **keep_heap, **discard_heap;

  freqs_trans[0] = freqs_trans[1] = 0;
  num_trans = 0;

  discard_num = Num[0] + Num[1];
  discard_heap = Xmalloc (discard_num * sizeof (WordData *));

  keep_num = 0;
  keep_heap = Xmalloc (discard_num * sizeof (WordData *));


  for (i = 0; i < Num[0]; i++)
    discard_heap[i] = Words[0] + i;
  for (i = 0; i < Num[1]; i++)
    discard_heap[i + Num[0]] = Words[1] + i;

  heap_build (discard_heap, sizeof (*discard_heap), discard_num, DecFreqIncWL);

  mem = 0;
  while (k > mem && discard_num)
    {
      WordData *word = discard_heap[0];
      mem += sizeof (u_char *) + word->word[0];
      heap_deletehead (discard_heap, sizeof (word), &discard_num, DecFreqIncWL);
      keep_heap[keep_num++] = word;
      freqs_trans[KIND (word)] += word->freq;
      num_trans++;
    }

  CalcBitCost (discard_heap, discard_num, keep_heap, keep_num,
	       freqs_trans, escape, num_trans);
  heap_build (discard_heap, sizeof (*discard_heap), discard_num, BigSaving);
  heap_build (keep_heap, sizeof (*keep_heap), keep_num, SmallSaving);

  total = 0;
  recalc_reqd = 0;
  while (keep_num && discard_num)
    {
      if ((keep_num && keep_heap[0]->num_trans < num_trans) ||
	  (discard_num && discard_heap[0]->num_trans < num_trans))
	{
	  if (keep_num && keep_heap[0]->num_trans < num_trans)
	    {
	      WordData *word = keep_heap[0];
	      int idx = KIND (word);
	      float wbc;
#ifdef DEBUG1
	      fprintf (stderr, "KEEP \"%s\" %.2f ->", word2str (word->word),
		       word->saving);
#endif
	      wbc = -log2 (word->freq / (freqs_trans[idx] + escape[idx])) *
		word->freq;
	      word->saving = (word->char_bit_cost - wbc) /
		(sizeof (char *) + word->word[0]);
#ifdef DEBUG1
	      fprintf (stderr, " %.2f\n", word->saving);
#endif
	      word->num_trans = num_trans;
	      heap_changedhead (keep_heap, sizeof (word), keep_num, SmallSaving);
	    }

	  if (discard_num && discard_heap[0]->num_trans < num_trans)
	    {
	      WordData *word = discard_heap[0];
	      int idx = KIND (word);
	      float wbc;
#ifdef DEBUG1
	      fprintf (stderr, "DISCARD \"%s\" %.2f ->", word2str (word->word),
		       word->saving);
#endif
	      wbc = -log2 (word->freq / (freqs_trans[idx] + escape[idx])) *
		word->freq;
	      word->saving = (word->char_bit_cost - wbc) /
		(sizeof (char *) + word->word[0]);
#ifdef DEBUG1
	      fprintf (stderr, " %.2f\n", word->saving);
#endif
	      word->num_trans = num_trans;
	      heap_changedhead (discard_heap, sizeof (word),
				discard_num, BigSaving);
	    }
	}
      else if (keep_heap[0]->saving < discard_heap[0]->saving)
	{
	  assert (keep_num && discard_num);
	  if (keep_num && mem + sizeof (char *) + discard_heap[0]->word[0] > k)
	    {
	      /* Transfer the word at the top of the keep heap to the
	         discard heap. */
	      WordData *word = keep_heap[0];
	      int idx = KIND (word);
	      heap_deletehead (keep_heap, sizeof (word), &keep_num, SmallSaving);
	      discard_heap[discard_num] = word;
	      heap_additem (discard_heap, sizeof (word), &discard_num,
			    BigSaving);
	      freqs_trans[idx] -= word->freq;
	      mem -= sizeof (u_char *) + word->word[0];
	      num_trans++;
	      total += word->saving;
	      keep_to_discard++;
#ifdef DEBUG
	      fprintf (stderr,
		       "KEEP -> DISCARD %8d :%8d :%8.0f :%8.0f : \"%s\"\n",
		       mem, word->freq, word->char_bit_cost,
		       word->saving, word2str (word->word));
#endif
	    }
	  else
	    {
	      /* Transfer the word at the top of the discard heap to the
	         keep heap. */
	      WordData *word = discard_heap[0];
	      int idx = KIND (word);
	      heap_deletehead (discard_heap, sizeof (word),
			       &discard_num, BigSaving);
	      keep_heap[keep_num] = word;
	      heap_additem (keep_heap, sizeof (word), &keep_num, SmallSaving);
	      freqs_trans[idx] += word->freq;
	      mem += sizeof (u_char *) + word->word[0];
	      num_trans++;
	      total += word->saving;
	      discard_to_keep++;
#ifdef DEBUG
	      fprintf (stderr,
		       "DISCARD -> KEEP %8d :%8d :%8.0f :%8.0f : \"%s\"\n",
		       mem, word->freq, word->char_bit_cost,
		       word->saving, word2str (word->word));
#endif
	    }

	  recalc_reqd = 1;

	}
      else
	{
	  if (recalc_reqd == 0)
	    break;
#ifdef DEBUG1
	  fprintf (stderr, "--------------\n");
#endif
	  if (recalcs == MAX_RECALCULATIONS)
	    break;
	  CalcBitCost (discard_heap, discard_num, keep_heap, keep_num,
		       freqs_trans, escape, num_trans);
	  heap_build (discard_heap, sizeof (*discard_heap),
		      discard_num, BigSaving);
	  heap_build (keep_heap, sizeof (keep_heap), keep_num, SmallSaving);
	  recalc_reqd = 0;
	  recalcs++;
	}
    }

  Alloc_keep_discard ();

  for (i = 0; i < discard_num; i++)
    {
      WordData *word = discard_heap[i];
      int idx = KIND (word);
      assert (IsWord (word) || IsNonWord (word));
      discard[idx].wd[discard[idx].num_wds++] = word;
    }
  for (i = 0; i < keep_num; i++)
    {
      WordData *word = keep_heap[i];
      int idx = KIND (word);
      assert (IsWord (word) || IsNonWord (word));
      keep[idx].wd[keep[idx].num_wds++] = word;
    }
  SortAndCount_DictData (&keep[0]);
  SortAndCount_DictData (&keep[1]);
  SortAndCount_DictData (&discard[0]);
  SortAndCount_DictData (&discard[1]);

  assert (keep[0].num_wds + discard[0].num_wds == Num[0]);
  assert (keep[1].num_wds + discard[1].num_wds == Num[1]);
  Message ("Keep -> Discard        : %8d", keep_to_discard);
  Message ("Discard -> Keep        : %8d", discard_to_keep);
  Message ("Huffman Recalculations : %8d", recalcs);
  if (recalcs == MAX_RECALCULATIONS)
    Message ("WARNING: The number of recalculations == %d", MAX_RECALCULATIONS);
}
Beispiel #15
0
TEMPLATE_PLEASE
int prepare_vecs_Sprimme(int basisSize, int i0, int blockSize, SCALAR *H,
      int ldH, EVAL *hVals, REAL *hSVals, SCALAR *hVecs, int ldhVecs,
      int targetShiftIndex, int *arbitraryVecs, double smallestResNorm,
      int *flags, int RRForAll, SCALAR *hVecsRot, int ldhVecsRot,
      primme_context ctx) {

   primme_params *primme = ctx.primme;
   int i, j, k;         /* Loop indices */
   int candidates;      /* Number of eligible pairs */
   int someCandidate;   /* If there is an eligible pair in the cluster */
   double aNorm, eps;

   /* Quick exit */

   if (primme->projectionParams.projection != primme_proj_refined ||
         basisSize == 0) {
      /* Find next candidates, starting from iev(*blockSize)+1 */

      if (flags) {
         for (i = i0, j = 0; i < basisSize && j < blockSize; i++) {
            if (flags[i] == UNCONVERGED) j++;
         }
      }

      return 0;
   }

   /* Quick exit */

   if (blockSize == 0) {
      return 0;
   }

   aNorm = (primme->aNorm <= 0.0) ?
      primme->stats.estimateLargestSVal : primme->aNorm;

   /* Before the first eigenpair converges, there's no information about the  */
   /* requested tolerance. In that case eps is set as ten times less than the */
   /* the current smallest residual norm, if smallestResNorm provides that    */
   /* information.                                                            */
   eps = primme->stats.maxConvTol > 0.0 ? primme->stats.maxConvTol : (
         smallestResNorm < HUGE_VAL ? smallestResNorm/10.0 : 0.0);
   /* NOTE: the constant 6.28 is needed to pass                               */
   /* testi-100-LOBPCG_OrthoBasis-2-primme_closest_abs-primme_proj_refined.F  */
   eps = max(6.28*MACHINE_EPSILON, eps);

   for (candidates=0, i=min(*arbitraryVecs,basisSize), j=i0;
         j < basisSize && candidates < blockSize; ) {

      double ip;
      /* -------------------------------------------------------------------- */
      /* Count all eligible values (candidates) from j up to i.               */
      /* -------------------------------------------------------------------- */

      for ( ; j < i; j++) {
         if (!flags || flags[j] == UNCONVERGED)
            candidates++;
      }
     
      if (candidates >= blockSize) break;
 
      /* -------------------------------------------------------------------- */
      /* Find the first i-th vector i>j with enough good conditioning, ie.,   */
      /* the singular value is separated enough from the rest (see the header */
      /* comment in this function). Also check if there is an unconverged     */
      /* value in the block.                                                  */
      /* -------------------------------------------------------------------- */

      for (i=j+1, someCandidate=0, ip=0.0; i<basisSize; i++) {

         /* Check that this approximation:                                    */
         /* sin singular vector: max(hSVals)*machEps/(hSvals[i]-hSVals[i+1])  */
         /* is less than the next one:                                        */
         /* sin eigenvector    : aNorm*eps/(hVals[i]-hVals[i+1]).             */
         /* Also try to include enough coefficient vectors into the cluster   */
         /* so that the cluster is close the last included vectors into the   */
         /* basis.                                                            */
         /* TODO: check the angle with all vectors added to the basis in the  */
         /* previous iterations; for now only the last one is considered.     */
         /* NOTE: we don't want to check hVecs(end,i) just after restart, so  */
         /* we don't use the value when it is zero.                           */

         double minDiff = sqrt(2.0)*hSVals[basisSize-1]*MACHINE_EPSILON/
            (aNorm*eps/EVAL_ABS(hVals[i]-hVals[i-1]));
         double ip0 = ABS(hVecs[(i-1)*ldhVecs+basisSize-1]);
         double ip1 = ((ip += ip0*ip0) != 0.0) ? ip : HUGE_VAL;

         someCandidate = 1;

         if (fabs(hSVals[i]-hSVals[i-1]) >= minDiff
               && (smallestResNorm >= HUGE_VAL
                  || sqrt(ip1) >= smallestResNorm/aNorm/3.16)) 
            break;
      }
      i = min(i, basisSize);

      /* ----------------------------------------------------------------- */
      /* If the cluster j:i-1 is larger than one vector and there is some  */
      /* unconverged pair in there, compute the approximate eigenvectors   */
      /* with Rayleigh-Ritz. If RRForAll do also this when there is no     */
      /* candidate in the cluster.                                         */
      /* ----------------------------------------------------------------- */

      if (i-j > 1 && (someCandidate || RRForAll)) {
         SCALAR *aH, *ahVecs;
         int aBasisSize = i-j;
         CHKERR(Num_malloc_Sprimme((size_t)basisSize*aBasisSize, &aH, ctx));
         ahVecs = &hVecsRot[ldhVecsRot*j+j];

         /* Zero hVecsRot(:,arbitraryVecs:i-1) */
         Num_zero_matrix_Sprimme(&hVecsRot[ldhVecsRot*(*arbitraryVecs)],
               primme->maxBasisSize, i-*arbitraryVecs, ldhVecsRot, ctx);

         /* hVecsRot(:,arbitraryVecs:i-1) = I */
         for (k=*arbitraryVecs; k<i; k++)
            hVecsRot[ldhVecsRot*k+k] = 1.0;
 
         /* aH = hVecs(:,j:i-1)'*H*hVecs(:,j:i-1) */
         CHKERR(compute_submatrix_Sprimme(&hVecs[ldhVecs * j], aBasisSize,
               ldhVecs, H, basisSize, ldH,
               KIND(1 /* Hermitian */, 0 /* non-Hermitian */), aH, aBasisSize,
               ctx));

         /* Compute and sort eigendecomposition aH*ahVecs = ahVecs*diag(hVals(j:i-1)) */
         CHKERR(solve_H_RR_Sprimme(aH, aBasisSize, NULL, 0, ahVecs, ldhVecsRot,
               &hVals[j], aBasisSize, targetShiftIndex, ctx));

         /* hVecs(:,j:i-1) = hVecs(:,j:i-1)*ahVecs */
         Num_zero_matrix_Sprimme(aH, basisSize, aBasisSize, basisSize, ctx);
         CHKERR(Num_gemm_Sprimme("N", "N", basisSize, aBasisSize, aBasisSize,
               1.0, &hVecs[ldhVecs*j], ldhVecs, ahVecs, ldhVecsRot, 0.0,
               aH, basisSize, ctx));
         Num_copy_matrix_Sprimme(aH, basisSize, aBasisSize, basisSize,
               &hVecs[ldhVecs*j], ldhVecs, ctx);
         CHKERR(Num_free_Sprimme(aH, ctx));

         /* Indicate that before i may not be singular vectors */
         *arbitraryVecs = i;
      }
   }

   return 0;
}
Beispiel #16
0
STATIC int solve_H_brcast_Sprimme(int basisSize, SCALAR *hU, int ldhU,
                                  SCALAR *hVecs, int ldhVecs, EVAL *hVals,
                                  REAL *hSVals, primme_context ctx) {


   SCALAR *rwork0;             /* next SCALAR free */
   SCALAR *rwork;
   const size_t c = sizeof(SCALAR)/sizeof(REAL);

   /* Quick exit */

   if (basisSize <= 0) return 0;

   /* Allocate memory */

   int n=0;  /* number of SCALAR packed */
   if (hVecs) n += basisSize*basisSize;
   if (hU) n += basisSize*basisSize;
   if (hVals) n += KIND((basisSize + c - 1) / c, basisSize);
   if (hSVals) n += (basisSize + c-1)/c;
   CHKERR(Num_malloc_Sprimme(n, &rwork, ctx));
   rwork0 = rwork;

   /* Pack hVecs */

   if (hVecs) {
      if (ctx.primme->procID == 0) {
         Num_copy_matrix_Sprimme(hVecs, basisSize, basisSize, ldhVecs, rwork0,
               basisSize, ctx);
      }
      rwork0 += basisSize*basisSize;
   }

   /* Pack hU */

   if (hU) {
      if (ctx.primme->procID == 0) {
         Num_copy_matrix_Sprimme(hU, basisSize, basisSize, ldhU, rwork0,
               basisSize, ctx);
      }
      rwork0 += basisSize*basisSize;
   }

   /* Pack hVals */

   if (hVals) {
      if (ctx.primme->procID == 0) {
#ifdef USE_HERMITIAN
         //  When complex, avoid to reduce with an uninitialized value
         rwork0[(basisSize + c-1)/c-1] = 0.0; 
         Num_copy_matrix_Rprimme(hVals, basisSize, 1, basisSize, (REAL*)rwork0,
               basisSize, ctx);
         rwork0 += (basisSize + c - 1) / c;
#else
         Num_copy_matrix_Sprimme(
               hVals, basisSize, 1, basisSize, rwork0, basisSize, ctx);
         rwork0 += basisSize;
#endif
      }
   }

   /* Pack hSVals */

   if (hSVals) {
      if (ctx.primme->procID == 0) {
         rwork0[(basisSize + c-1)/c-1] = 0.0; /* When complex, avoid to reduce with an   */
                                              /* uninitialized value                     */
         Num_copy_matrix_Rprimme(hSVals, basisSize, 1, basisSize, (REAL*)rwork0,
               basisSize, ctx);
      }
      rwork0 += (basisSize + c-1)/c;
   }

   /* Perform the broadcast */

   CHKERR(broadcast_Sprimme(rwork, n, ctx));
   rwork0 = rwork;

   /* Unpack hVecs */

   if (hVecs) {
      Num_copy_matrix_Sprimme(rwork0, basisSize, basisSize, basisSize, hVecs,
            ldhVecs, ctx);
      rwork0 += basisSize*basisSize;
   }

   /* Unpack hU */

   if (hU) {
      Num_copy_matrix_Sprimme(rwork0, basisSize, basisSize, basisSize, hU,
            ldhU, ctx);
      rwork0 += basisSize*basisSize;
   }

   /* Unpack hVals */

   if (hVals) {
#ifdef USE_HERMITIAN
      Num_copy_matrix_Rprimme((REAL*)rwork0, basisSize, 1, basisSize, hVals,
            basisSize, ctx);
      rwork0 += (basisSize + c-1)/c;
#else
      Num_copy_matrix_Sprimme(
            rwork0, basisSize, 1, basisSize, hVals, basisSize, ctx);
      rwork0 += basisSize;
#endif
   }

   /* Unpack hSVals */

   if (hSVals) {
      Num_copy_matrix_Rprimme((REAL*)rwork0, basisSize, 1, basisSize, hSVals,
               basisSize, ctx);
      rwork0 += (basisSize + c-1)/c;
   }

   CHKERR(Num_free_Sprimme(rwork, ctx));

   return 0;
}