Example #1
0
/**
* Offer help to a randomly picked host
*/
void PROCESSOR::offer_help() {
	if(!help_messages
		&& n_idle_processors == n_processors 
		&& !use_abdada_cluster
		) {
			register int i, count = 0,dest;

			l_lock(lock_smp);
			for(i = 0;i < n_processors;i++) {
				if(processors[i]->state == WAIT) 
					count++;
			}
			l_unlock(lock_smp);
			
			if(count == n_processors) {
				while(true) {
					dest = (rand() % n_hosts);
					if((dest != host_id) && (dest != prev_dest)) 
						break;
				}
				ISend(dest,HELP);
				help_messages++;
				prev_dest = dest;
			}
	}
}
Example #2
0
int run(void) {
    printf("%s: starting...\n", get_instance_name());
    l_lock();
    printf("%s: got lock!\n", get_instance_name());
    l_unlock();
    printf("%s: released\n", get_instance_name());
    return 0;
}
Example #3
0
/**
* Handle messages
*/
void PROCESSOR::handle_message(int source,int message_id) {
	const PSEARCHER psb = processors[0]->searcher;

	/**************************************************
	* SPLIT  - Search from recieved position
	**************************************************/
	if(message_id == SPLIT) {
		SPLIT_MESSAGE split;
		Recv(source,message_id,&split,sizeof(SPLIT_MESSAGE));
		message_available = 0;

		/*setup board by undoing old moves and making new ones*/
		register int i,score,move,using_pvs;
		if(split.pv_length) {
			for(i = 0;i < split.pv_length && i < psb->ply;i++) {
				if(split.pv[i] != psb->hstack[psb->hply - psb->ply + i].move) 
					break;
			}
			while(psb->ply > i) {
				if(psb->hstack[psb->hply - 1].move) psb->POP_MOVE();
				else psb->POP_NULL();
			}
			for(;i < split.pv_length;i++) {
				if(split.pv[i]) psb->PUSH_MOVE(split.pv[i]);
				else psb->PUSH_NULL();
			}
		} else {
			psb->PUSH_MOVE(split.pv[0]);
		}
		/*reset*/
		SEARCHER::abort_search = 0;
		psb->clear_block();

		/**************************************
		* PVS-search on root node
		*************************************/
		processors[0]->state = GO;

		using_pvs = false;
		psb->pstack->extension = split.extension;
		psb->pstack->reduction = split.reduction;
		psb->pstack->depth = split.depth;
		psb->pstack->alpha = split.alpha;
		psb->pstack->beta = split.beta;
		psb->pstack->node_type = split.node_type;
		psb->pstack->search_state = split.search_state;
		if(psb->pstack->beta != psb->pstack->alpha + 1) {
			psb->pstack->node_type = CUT_NODE;
			psb->pstack->beta = psb->pstack->alpha + 1;
			using_pvs = true;
		}

		/*Search move and re-search if necessary*/
		move = psb->hstack[psb->hply - 1].move;
		while(true) {			
			psb->search();
			if(psb->stop_searcher || SEARCHER::abort_search) {
				move = 0;
				score = 0;
				break;
			}
			score = -psb->pstack->best_score;
			/*research with full depth*/
			if(psb->pstack->reduction
				&& score >= -split.alpha
				) {
					psb->pstack->depth += psb->pstack->reduction;
					psb->pstack->reduction = 0;

					psb->pstack->alpha = split.alpha;
					psb->pstack->beta = split.alpha + 1;
					psb->pstack->node_type = CUT_NODE;
					psb->pstack->search_state = NULL_MOVE;
					continue;
			}
			/*research with full window*/
			if(using_pvs 
				&& score > -split.beta
				&& score < -split.alpha
				) {
					using_pvs = false;

					psb->pstack->alpha = split.alpha;
					psb->pstack->beta = split.beta;
					psb->pstack->node_type = split.node_type;
					psb->pstack->search_state = NULL_MOVE;
					continue;
			}
			break;
		}

		/*undomove : Go to previous ply even if search was interrupted*/
		while(psb->ply > psb->stop_ply - 1) {
			if(psb->hstack[psb->hply - 1].move) psb->POP_MOVE();
			else psb->POP_NULL();
		}

		processors[0]->state = WAIT;

		/***********************************************************
		* Send result back and release all helper nodes we aquired
		***********************************************************/
		PROCESSOR::cancel_idle_hosts();

		MERGE_MESSAGE merge;
		merge.nodes = psb->nodes;
		merge.qnodes = psb->qnodes;
		merge.time_check = psb->time_check;
		merge.splits = psb->splits;
		merge.bad_splits = psb->bad_splits;
		merge.egbb_probes = psb->egbb_probes;

		/*pv*/
		merge.master = split.master;
		merge.best_move = move;
		merge.best_score = score;
		merge.pv_length = 0;

		if(move && score > -split.beta && score < -split.alpha) {
			merge.pv[0] = move;
			memcpy(&merge.pv[1],&(psb->pstack + 1)->pv[psb->ply + 1],
				((psb->pstack + 1)->pv_length - psb->ply ) * sizeof(MOVE));
			merge.pv_length = (psb->pstack + 1)->pv_length - psb->ply;
		}
		/*send it*/
		MPI_Request rq;
		ISend(source,PROCESSOR::MERGE,&merge,MERGE_MESSAGE_SIZE(merge),&rq);
		Wait(&rq);
	} else if(message_id == MERGE) {
		/**************************************************
		* MERGE  - Merge result of move at split point
		**************************************************/
		MERGE_MESSAGE merge;
		Recv(source,message_id,&merge,sizeof(MERGE_MESSAGE));
		

		/*update master*/
		PSEARCHER master = (PSEARCHER)merge.master;
		l_lock(master->lock);

		if(merge.best_move && merge.best_score > master->pstack->best_score) {
			master->pstack->best_score = merge.best_score;
			master->pstack->best_move = merge.best_move;
			if(merge.best_score > master->pstack->alpha) {
				if(merge.best_score > master->pstack->beta) {
					master->pstack->flag = LOWER;

					l_unlock(master->lock);
					master->handle_fail_high();
					l_lock(master->lock);
				} else {
					master->pstack->flag = EXACT;
					master->pstack->alpha = merge.best_score;

					memcpy(&master->pstack->pv[master->ply],&merge.pv[0],
							merge.pv_length * sizeof(MOVE));
					master->pstack->pv_length = merge.pv_length + master->ply;
				}
			}
		}

		/*update counts*/
		master->nodes += merge.nodes;
		master->qnodes += merge.qnodes;
		master->time_check += merge.time_check;
		master->splits += merge.splits;
		master->bad_splits += merge.bad_splits;
		master->egbb_probes += merge.egbb_probes;

		l_unlock(master->lock);
		/* 
		* We finished searching one move from the current split. 
		* Check for more moves there and keep on searching.
		* Otherwise remove the node from the split's helper list, 
		* and add it to the list of idle helpers.
		*/
		l_lock(lock_smp);
		SPLIT_MESSAGE& split = global_split[source];
		if(!master->stop_searcher && master->get_cluster_move(&split,true)) {
			l_unlock(lock_smp);
			ISend(source,PROCESSOR::SPLIT,&split,RESPLIT_MESSAGE_SIZE(split));
		} else {
			if(n_hosts > 2)
				ISend(source,CANCEL);
			else
				available_host_workers.push_back(source);
			l_unlock(lock_smp);
			/*remove from current split*/
			l_lock(master->lock);
			master->host_workers.remove(source);
			master->n_host_workers--;
			l_unlock(master->lock);
		}
		/******************************************************************
		* INIT  - Set up poistion from FEN and prepare threaded search
		******************************************************************/
	} else if(message_id == INIT) {
		INIT_MESSAGE init;
		Recv(source,message_id,&init,sizeof(INIT_MESSAGE));
		
		/*setup board*/
		psb->set_board((char*)init.fen);

		/*make moves*/
		register int i;
		for(i = 0;i < init.pv_length;i++) {
			if(init.pv[i]) psb->do_move(init.pv[i]);	
			else psb->do_null();
		}
#ifdef PARALLEL
		/*wakeup processors*/
		for(i = 0;i < n_processors;i++)
			processors[i]->state = WAIT;
#endif
		/***********************************
		* Distributed transposition table
		************************************/
#if DST_TT_TYPE == 1
	} else if(message_id == RECORD_TT) {
		TT_MESSAGE ttmsg;
		Recv(source,message_id,&ttmsg,sizeof(TT_MESSAGE));
		
		/*record*/
		psb->record_hash(ttmsg.col,ttmsg.hash_key,ttmsg.depth,ttmsg.ply,
					ttmsg.flags,ttmsg.score,ttmsg.move,
					ttmsg.mate_threat,ttmsg.singular);
	} else if(message_id == PROBE_TT) {
		TT_MESSAGE ttmsg;
		Recv(source,message_id,&ttmsg,sizeof(TT_MESSAGE));
		
		/*probe*/
		int proc_id = ttmsg.flags;
		int h_depth,score,mate_threat,singular;
		ttmsg.flags = psb->probe_hash(ttmsg.col,ttmsg.hash_key,ttmsg.depth,ttmsg.ply,
					score,ttmsg.move,ttmsg.alpha,ttmsg.beta,
					mate_threat,singular,h_depth,false);
		ttmsg.depth = h_depth;
		ttmsg.score = (BMP16)score;
		ttmsg.mate_threat = (UBMP8)mate_threat;
		ttmsg.singular = (UBMP8)singular;
		ttmsg.ply = proc_id;  //embed processor_id in message
		/*send*/
		MPI_Request rq;
		ISend(source,PROCESSOR::PROBE_TT_RESULT,&ttmsg,sizeof(TT_MESSAGE),&rq);
		Wait(&rq);
	} else if(message_id == PROBE_TT_RESULT) {
		TT_MESSAGE ttmsg;
		Recv(source,message_id,&ttmsg,sizeof(TT_MESSAGE));
		
		/*copy tt entry to processor*/
		int proc_id = ttmsg.ply;
		PPROCESSOR proc = processors[proc_id];
		proc->ttmsg = ttmsg;
		proc->ttmsg_recieved = true;
#endif
		/******************************************
		* Handle notification (zero-size) messages
		*******************************************/
	} else {
		Recv(source,message_id);
		
		if(message_id == HELP) {
			l_lock(lock_smp);
			if(n_idle_processors == n_processors)
				ISend(source,CANCEL);
			else
				available_host_workers.push_back(source);
			l_unlock(lock_smp);
		} else if(message_id == CANCEL) {
			help_messages--;
		} else if(message_id == QUIT) {
			SEARCHER::abort_search = 1;
		} else if(message_id == GOROOT) {
			message_available = 0;
			SEARCHER::chess_clock.infinite_mode = true;
			int save = processors[0]->state;
			processors[0]->state = GO;
			psb->find_best();
			processors[0]->state = save;
		} else if(message_id == PING) {
			ISend(source,PONG);
		}
	}
}