Exemplo n.º 1
0
static const char *genimg_get_short_name(const table_entry_t *table, int val)
{
	table = get_table_entry(table, val);
	if (!table)
		return "unknown";
#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
	return table->sname;
#else
	return table->sname + gd->reloc_off;
#endif
}
Exemplo n.º 2
0
/**
 * get_table_entry_name - translate entry id to long name
 * @table: pointer to a translation table for entries of a specific type
 * @msg: message to be returned when translation fails
 * @id: entry id to be translated
 *
 * get_table_entry_name() will go over translation table trying to find
 * entry that matches given id. If matching entry is found, its long
 * name is returned to the caller.
 *
 * returns:
 *     long entry name if translation succeeds
 *     msg otherwise
 */
char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
{
	table = get_table_entry(table, id);
	if (!table)
		return msg;
#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
	return table->lname;
#else
	return table->lname + gd->reloc_off;
#endif
}
Exemplo n.º 3
0
/**
 * get_cat_table_entry_short_name - translate entry id to short name
 * @category: category to look up (enum ih_category)
 * @id: entry id to be translated
 *
 * This will scan the translation table trying to find the entry that matches
 * the given id.
 *
 * @retur short entry name if translation succeeds; error string on failure
 */
const char *genimg_get_cat_short_name(enum ih_category category, uint id)
{
	const table_entry_t *entry;

	entry = get_table_entry(table_info[category].table, id);
	if (!entry)
		return unknown_msg(category);
#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
	return entry->sname;
#else
	return entry->sname + gd->reloc_off;
#endif
}
Exemplo n.º 4
0
const char *genimg_get_type_short_name(uint8_t type)
{
	const table_entry_t *table;

	table = get_table_entry(uimage_type, type);
	if (!table)
		return "unknown";
#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
	return table->sname;
#else
	return table->sname + gd->reloc_off;
#endif
}
Exemplo n.º 5
0
void get_or_create_table_entry(HSQUIRRELVM vm, const std::string& name)
{
  sq_pushstring(vm, name.c_str(), -1);
  if(SQ_FAILED(sq_get(vm, -2)))
  {
    sq_pushstring(vm, name.c_str(), -1);
    sq_newtable(vm);
    if(SQ_FAILED(sq_createslot(vm, -3)))
    {
      std::ostringstream msg;
      msg << "failed to create '" << name << "' table entry";
      throw scripting::SquirrelError(vm, msg.str());
    }
    else
    {
      get_table_entry(vm, name);
    }
  }
  else
  {
    // successfully placed result on stack
  }
}
Exemplo n.º 6
0
void qs_filter_relations(sieve_conf_t *conf) {

	/* Perform all of the postprocessing on the list
	   of relations from the sieving phase. There are
	   two main jobs, reading in all the relations that
	   will be used and then determining the list of 
	   cycles in which partial relations appear. Care
	   should be taken to avoid wasting huge amounts of
	   memory */

	msieve_obj *obj = conf->obj;
	uint32 *hashtable = conf->cycle_hashtable;
	cycle_t *table = conf->cycle_table;
	uint32 num_poly_factors = conf->num_poly_factors;
	uint32 num_derived_poly = 1 << (num_poly_factors - 1);
	uint32 *final_poly_index;
	uint32 num_relations, num_cycles, num_poly;
	la_col_t *cycle_list;
	relation_t *relation_list;

	uint32 i, passes, start;
	uint32 curr_a_idx, curr_poly_idx, curr_rel; 
	uint32 curr_expected, curr_saved, curr_cycle; 
	uint32 total_poly_a;
	uint32 poly_saved;
	uint32 cycle_bins[NUM_CYCLE_BINS+1] = {0};
	char buf[LINE_BUF_SIZE];

 	/* Rather than reading all the relations in and 
	   then removing singletons, read only the large 
	   primes of each relation into an initial list,
	   remove the singletons, and then only read in
	   the relations that survive. This avoids reading
	   in useless relations (and usually the polynomials 
	   they would need) */

	savefile_open(&obj->savefile, SAVEFILE_READ);

	relation_list = (relation_t *)xmalloc(10000 * sizeof(relation_t));
	curr_rel = 10000;
	i = 0;
	total_poly_a = 0;
	/* skip over the first line */
	savefile_read_line(buf, sizeof(buf), &obj->savefile);

	while (!savefile_eof(&obj->savefile)) {
		char *start;

		switch (buf[0]) {
		case 'A':
			total_poly_a++;
			break;

		case 'R':
			start = strchr(buf, 'L');
			if (start != NULL) {
				uint32 prime1, prime2;
				read_large_primes(start, &prime1, &prime2);
				if (i == curr_rel) {
					curr_rel = 3 * curr_rel / 2;
					relation_list = (relation_t *)xrealloc(
							relation_list,
							curr_rel *
							sizeof(relation_t));
				}
				relation_list[i].poly_idx = i;
				relation_list[i].large_prime[0] = prime1;
				relation_list[i].large_prime[1] = prime2;
				i++;
			}
			break;
		}

		savefile_read_line(buf, sizeof(buf), &obj->savefile);
	}
	num_relations = i;
	num_relations = purge_singletons(obj, relation_list, num_relations,
					table, hashtable);
	relation_list = (relation_t *)xrealloc(relation_list, num_relations * 
							sizeof(relation_t));

	/* Now we know how many relations to expect. Also
	   initialize the lists of polynomial 'a' and 'b' values */

	num_poly = 10000;
	conf->poly_list = (poly_t *)xmalloc(num_poly * sizeof(poly_t));
	conf->poly_a_list = (mp_t *)xmalloc(total_poly_a * sizeof(mp_t));
	final_poly_index = (uint32 *)xmalloc(num_derived_poly * 
						sizeof(uint32));
	
	/* initialize the running counts of relations and
	   polynomials */

	i = 0;
	curr_expected = 0;
	curr_saved = 0;
	curr_rel = (uint32)(-1);
	curr_poly_idx = (uint32)(-1);
	curr_a_idx = (uint32)(-1);
	poly_saved = 0;
	logprintf(obj, "attempting to read %u relations\n", num_relations);

	/* Read in the relations and the polynomials they use
	   at the same time. */

	savefile_rewind(&obj->savefile);

	while (curr_expected < num_relations) {
		
		char *tmp;
		relation_t *r;

		/* read in the next entity */

		if (savefile_eof(&obj->savefile))
			break;
		savefile_read_line(buf, sizeof(buf), &obj->savefile);

		switch (buf[0]) {
		case 'A':
			/* Read in a new 'a' value */

			curr_a_idx++;
			read_poly_a(conf, buf);
			mp_copy(&conf->curr_a, conf->poly_a_list+curr_a_idx);

			/* build all of the 'b' values associated with it */

			build_derived_poly(conf);

			/* all 'b' values start off unused */

			memset(final_poly_index, -1, num_derived_poly *
							sizeof(uint32));
			break;

		case 'R':
			/* handle a new relation. First find the 
			   large primes; these will determine
	     		   if a relation is full or partial */

			tmp = strchr(buf, 'L');
			if (tmp == NULL)
				break;

			/* Check if this relation is needed. If it
			   survived singleton removal then its 
			   ordinal ID will be in the next entry 
			   of relation_list. 
		   
			   First move up the index of relation_list 
			   until the relation index to check is >= 
			   the one we have (it may have gotten behind 
			   because relations were corrupted) */

			curr_rel++;
			while (curr_expected < num_relations &&
				relation_list[curr_expected].poly_idx <
						curr_rel) {
				curr_expected++;
			}

			/* now check if the relation should be saved */

			if (curr_expected >= num_relations ||
			    relation_list[curr_expected].poly_idx != curr_rel)
				break;

			curr_expected++;

			/* convert the ASCII text of the relation to a
			   relation_t, verifying correctness in the process */

			r = relation_list + curr_saved;
			if (read_relation(conf, buf, r) != 0) {
				logprintf(obj, "failed to read relation %d\n", 
							curr_expected - 1);
				break;
			}

			curr_saved++;

			/* if necessary, save the b value corresponding 
			   to this relation */

			if (final_poly_index[r->poly_idx] == (uint32)(-1)) {
				if (i == num_poly) {
					num_poly *= 2;
					conf->poly_list = (poly_t *)xrealloc(
							conf->poly_list,
							num_poly *
							sizeof(poly_t));
				}
				conf->poly_list[i].a_idx = curr_a_idx;
				signed_mp_copy(&(conf->curr_b[r->poly_idx]), 
					&(conf->poly_list[i].b));
				final_poly_index[r->poly_idx] = i;
				r->poly_idx = i++;
			}
			else {
				r->poly_idx = final_poly_index[r->poly_idx];
			}

			break;  /* done with this relation */
		}
	}

	/* update the structures with the counts of relations
	   and polynomials actually recovered */

	num_relations = curr_saved;
	logprintf(obj, "recovered %u relations\n", num_relations);
	logprintf(obj, "recovered %u polynomials\n", i);
	savefile_close(&obj->savefile);
	free(final_poly_index);
	conf->poly_list = (poly_t *)xrealloc(conf->poly_list,
					   i * sizeof(poly_t));

	/* begin the cycle generation process by purging
	   duplicate relations. For the sake of consistency, 
	   always rebuild the graph afterwards */

	num_relations = purge_duplicate_relations(obj, 
				relation_list, num_relations);

	memset(hashtable, 0, sizeof(uint32) << LOG2_CYCLE_HASH);
	conf->vertices = 0;
	conf->components = 0;
	conf->cycle_table_size = 1;

	for (i = 0; i < num_relations; i++) {
		relation_t *r = relation_list + i;
		if (r->large_prime[0] != r->large_prime[1]) {
			add_to_cycles(conf, r->large_prime[0], 
					r->large_prime[1]);
		}
	}
	
	/* compute the number of cycles to expect. Note that
	   this number includes cycles from both full and partial
	   relations (the cycle for a full relation is trivial) */

	num_cycles = num_relations + conf->components - conf->vertices;

	/* The idea behind the cycle-finding code is this: the 
	   graph is composed of a bunch of connected components, 
	   and each component contains one or more cycles. To 
	   find the cycles, you build the 'spanning tree' for 
	   each component.

	   Think of the spanning tree as a binary tree; there are
	   no cycles in it because leaves are only connected to a
	   common root and not to each other. Any time you connect 
	   together two leaves of the tree, though, a cycle is formed.
	   So, for a spanning tree like this:

	         1
	         o
		/ \
	    2  o   o  3
	      / \   \
	     o   o   o
	     4   5   6

	   if you connect leaves 4 and 5 you get a cycle (4-2-5). If
	   you connect leaves 4 and 6 you get another cycle (4-2-1-3-6)
	   that will reuse two of the nodes in the first cycle. It's
	   this reuse that makes double large primes so powerful.

	   For our purposes, every edge in the tree above represents
	   a partial relation. Every edge that would create a cycle
	   comes from another partial relation. So to find all the cycles,
	   you begin with the roots of all of the connected components,
	   and then iterate through the list of partial relations until 
	   all have been 'processed'. A partial relation is considered 
	   processed when one or both of its primes is in the tree. If 
	   one prime is present then the relation gets added to the tree; 
	   if both primes are present then the relation creates one cycle 
	   but is *not* added to the tree. 
	   
	   It's really great to see such simple ideas do something so
	   complicated as finding cycles (and doing it very quickly) */

	/* First traverse the entire graph and remove any vertices
	   that are not the roots of connected components (i.e.
	   remove any primes whose cycle_t entry does not point
	   to itself */

	for (i = 0; i < (1 << LOG2_CYCLE_HASH); i++) {
		uint32 offset = hashtable[i];

		while (offset != 0) {
			cycle_t *entry = table + offset;
			if (offset != entry->data)
				entry->data = 0;
			offset = entry->next;
		}
	}

	logprintf(obj, "attempting to build %u cycles\n", num_cycles);
	cycle_list = (la_col_t *)xmalloc(num_cycles * sizeof(la_col_t));

	/* keep going until either all cycles are found, all
	   relations are processed, or cycles stop arriving. 
	   Normally these conditions all occur at the same time */

	for (start = passes = curr_cycle = 0; start < num_relations && 
			curr_cycle < num_cycles; passes++) {

		/* The list of relations up to index 'start' is con-
		   sidered processed. For all relations past that... */

		uint32 start_cycles = curr_cycle;

		for (i = start; i < num_relations &&
				curr_cycle < num_cycles; i++) {

			cycle_t *entry1, *entry2;
			relation_t rtmp = relation_list[i];
			
			if (rtmp.large_prime[0] == rtmp.large_prime[1]) {

				/* this is a full relation, and forms a
				   cycle just by itself. Move it to position 
				   'start' of the relation list and increment 
				   'start'. The relation is now frozen at 
				   that position */

				la_col_t *c = cycle_list + curr_cycle++;
				relation_list[i] = relation_list[start];
				relation_list[start] = rtmp;

				/* build a trivial cycle for the relation */

				c->cycle.num_relations = 1;
				c->cycle.list = (uint32 *)
						xmalloc(sizeof(uint32));
				c->cycle.list[0] = start++;
				continue;
			}

			/* retrieve the cycle_t entries associated
			   with the large primes in relation r. */

			entry1 = get_table_entry(table, hashtable, 
						rtmp.large_prime[0], 0);
			entry2 = get_table_entry(table, hashtable, 
						rtmp.large_prime[1], 0);

			/* if both vertices do not point to other
			   vertices, then neither prime has been added
			   to the graph yet, and r must remain unprocessed */

			if (entry1->data == 0 && entry2->data == 0)
				continue;

			/* if one or the other prime is part of the
			   graph, add r to the graph. The vertex not in
			   the graph points to the vertex that is, and
			   this entry also points to the relation that
			   is associated with rtmp.

			   If both primes are in the graph, recover the
			   cycle this generates */

			if (entry1->data == 0) {
				entry1->data = entry2 - table;
				entry1->count = start;
			}
			else if (entry2->data == 0) {
				entry2->data = entry1 - table;
				entry2->count = start;
			}
			else {
				la_col_t *c = cycle_list + curr_cycle;
				c->cycle.list = NULL;
				enumerate_cycle(obj, c, table, entry1,
						entry2, start);
				if (c->cycle.list)
					curr_cycle++;
			}

			/* whatever happened above, the relation is
			   processed now; move it to position 'start'
			   of the relation list and increment 'start'.
			   The relation is now frozen at that position */

			relation_list[i] = relation_list[start];
			relation_list[start++] = rtmp;
		}

		/* If this pass did not find any new cycles, then
		   we've reached steady state and are finished */

		if (curr_cycle == start_cycles)
			break;
	}
	num_cycles = curr_cycle;

	logprintf(obj, "found %u cycles in %u passes\n", num_cycles, passes);
	
	/* sort the list of cycles so that the cycles with
	   the largest number of relations will come last. 
	   If the linear algebra code skips any cycles it
	   can easily skip the most dense cycles */

	qsort(cycle_list, (size_t)num_cycles, sizeof(la_col_t), sort_cycles);

	conf->relation_list = relation_list;
	conf->num_relations = num_relations;
	conf->cycle_list = cycle_list;
	conf->num_cycles = num_cycles;

	/* print out a histogram of cycle lengths for infor-
	   mational purposes */

	for (i = 0; i < num_cycles; i++) {
		num_relations = cycle_list[i].cycle.num_relations;

		if (num_relations >= NUM_CYCLE_BINS)
			cycle_bins[NUM_CYCLE_BINS]++;
		else
			cycle_bins[num_relations - 1]++;
	}
	logprintf(obj, "distribution of cycle lengths:\n");
	for (i = 0; i < NUM_CYCLE_BINS; i++) {
		if (cycle_bins[i]) {
			logprintf(obj, "   length %d : %d\n", 
					i + 1, cycle_bins[i]);
		}
	}
	if (cycle_bins[i])
		logprintf(obj, "   length %u+: %u\n", i + 1, cycle_bins[i]);
	logprintf(obj, "largest cycle: %u relations\n",
			cycle_list[num_cycles-1].cycle.num_relations);
}
Exemplo n.º 7
0
/*--------------------------------------------------------------------*/
static uint32 purge_singletons(msieve_obj *obj, relation_t *list, 
				uint32 num_relations,
				cycle_t *table, uint32 *hashtable) {
	
	/* given a list of relations and the graph from the
	   sieving stage, remove any relation that contains
	   a prime that only occurs once in the graph. Because
	   removing a relation removes a second prime as well,
	   this process must be iterated until no more relations
	   are removed */

	uint32 num_left;
	uint32 i, j, k;
	uint32 passes = 0;

	logprintf(obj, "begin with %u relations\n", num_relations);

	do {
		num_left = num_relations;

		/* for each relation */

		for (i = j = 0; i < num_relations; i++) {
			relation_t *r = list + i;
			uint32 prime;
			cycle_t *entry;

			/* full relations always survive */

			if (r->large_prime[0] == r->large_prime[1]) {
				list[j++] = list[i];
				continue;
			}

			/* for each prime in that relation */

			for (k = 0; k < 2; k++) {
				prime = r->large_prime[k];
				entry = get_table_entry(table, hashtable,
							prime, 0);

				/* if the relation is due to be removed,
				   decrement the count of its other
				   primes in the graph. The following is
				   specialized for two primes */

				if (entry->count < 2) {
					prime = r->large_prime[k ^ 1];
					entry = get_table_entry(table, 
								hashtable, 
								prime, 0);
					entry->count--;
					break;
				}
			}

			if (k == 2)
				list[j++] = list[i];
		}
		num_relations = j;
		passes++;

	} while (num_left != num_relations);
				
	logprintf(obj, "reduce to %u relations in %u passes\n", 
				num_left, passes);
	return num_left;
}
Exemplo n.º 8
0
/*--------------------------------------------------------------------*/
static uint32 add_to_hashtable(cycle_t *table, uint32 *hashtable, 
			uint32 prime1, uint32 prime2, 
			uint32 default_table_entry, 
			uint32 *components, uint32 *vertices) {

	/* update the list of cycles to reflect the presence
	   of a partial relation with large primes 'prime1'
	   and 'prime2'.

	   There are three quantities to track, the number of
	   edges, components and vertices. The number of cycles 
	   in the graph is then e + c - v. There is one edge for
	   each partial relation, and one vertex for each prime
	   that appears in the graph (these are easy to count).

	   A connected component is a group of primes that are
	   all reachable from each other via edges in the graph.
	   All of the vertices that are in a cycle must belong
	   to the same connected component. Think of a component
	   as a tree of vertices; one prime is chosen arbitrarily
	   as the 'root' of that tree.
	   
	   The number of new primes added to the graph (0, 1, or 2)
	   is returned */

	uint32 root[2];
	uint32 root1, root2;
	uint32 i;
	uint32 num_new_entries = 0;

	/* for each prime */

	for (i = 0; i < 2; i++) {
		uint32 prime = ((i == 0) ? prime1 : prime2);
		uint32 offset; 
		cycle_t *entry;

		/* retrieve the cycle_t corresponding to that
		   prime from the graph (or allocate a new one) */

		entry = get_table_entry(table, hashtable,
					prime, default_table_entry);
		entry->count++;

		if (entry->data == 0) {

			/* if this prime has not occurred in the graph
			   before, increment the number of vertices and
			   the number of components, then make the table
			   entry point to itself. */

			num_new_entries++;
			default_table_entry++;

			offset = entry - table;
			entry->data = offset;
			(*components)++;
			(*vertices)++;
		}
		else {
			/* the prime is already in the table, which
			   means we can follow a linked list of pointers
			   to other primes until we reach a cycle_t
			   that points to itself. This last cycle_t is
			   the 'root' of the connected component that
			   contains 'prime'. Save its value */

			cycle_t *first_entry, *next_entry;

			first_entry = entry;
			next_entry = table + entry->data;
			while (entry != next_entry) {
				entry = next_entry;
				next_entry = table + next_entry->data;
			}
				
			/* Also perform path compression: now that we
			   know the value of the root for this prime,
			   make all of the pointers in the primes we
			   visited along the way point back to this root.
			   This will speed up future root lookups */

			offset = entry->data;
			entry = first_entry;
			next_entry = table + entry->data;
			while (entry != next_entry) {
				entry->data = offset;
				entry = next_entry;
				next_entry = table + next_entry->data;
			}
		}

		root[i] = offset;
	}
				
	/* If the roots for prime1 and prime2 are different,
	   then they lie within separate connected components.
	   We're about to connect this edge to one of these
	   components, and the presence of the other prime
	   means that these two components are about to be
	   merged together. Hence the total number of components
	   in the graph goes down by one. */

	root1 = root[0];
	root2 = root[1];
	if (root1 != root2)
		(*components)--;
	
	/* This partial relation represents an edge in the
	   graph; we have to attach this edge to one or the
	   other of the connected components. Attach it to
	   the component whose representative prime is smallest;
	   since small primes are more common, this will give
	   the smaller root more edges, and will potentially
	   increase the number of cycles the graph contains */

	if (table[root1].prime < table[root2].prime)
		table[root2].data = root1;
	else
		table[root1].data = root2;
	
	return num_new_entries;
}