コード例 #1
0
ファイル: datalog.cpp プロジェクト: richard-evans/vampire
	// Data output wrapper function
	void data(){

		// check calling of routine if error checking is activated
		if(err::check==true){std::cout << "vout::data has been called" << std::endl;}

		// Calculate MPI Timings since last data output
		#ifdef MPICF
		if(vmpi::DetailedMPITiming){

			// Calculate Average times
			MPI_Reduce (&vmpi::TotalComputeTime,&vmpi::AverageComputeTime,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
			MPI_Reduce (&vmpi::TotalWaitTime,&vmpi::AverageWaitTime,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
			vmpi::AverageComputeTime/=double(vmpi::num_processors);
			vmpi::AverageWaitTime/=double(vmpi::num_processors);

			// Calculate Maximum times
			MPI_Reduce (&vmpi::TotalComputeTime,&vmpi::MaximumComputeTime,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);
			MPI_Reduce (&vmpi::TotalWaitTime,&vmpi::MaximumWaitTime,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD);

			// Save times for timing matrix
			vmpi::ComputeTimeArray.push_back(vmpi::TotalComputeTime);
			vmpi::WaitTimeArray.push_back(vmpi::TotalWaitTime);

			// reset until next data output
			vmpi::TotalComputeTime=0.0;
			vmpi::TotalWaitTime=0.0;
		}
		#endif

      // check for open ofstream on root process only
      if(vmpi::my_rank == 0){
         if(!zmag.is_open()){
            // check for checkpoint continue and append data
            if(sim::load_checkpoint_flag && sim::load_checkpoint_continue_flag) zmag.open("output",std::ofstream::app);
            // otherwise overwrite file
            else{
               zmag.open("output",std::ofstream::trunc);
               // write file header information
               write_output_file_header(zmag, file_output_list);
            }
         }
      }

		// Only output 1/output_rate time steps
		if(sim::time%vout::output_rate==0){

		// Output data to output
		if(vmpi::my_rank==0){

         // For gpu acceleration get statistics from device
         if(gpu::acceleration) gpu::stats::get();

			for(unsigned int item=0;item<file_output_list.size();item++){
				switch(file_output_list[item]){
					case 0:
						vout::time(zmag);
						break;
					case 1:
						vout::real_time(zmag);
						break;
					case 2:
						vout::temperature(zmag);
						break;
					case 3:
						vout::Happ(zmag);
						break;
					case 4:
						vout::Hvec(zmag);
						break;
					case 5:
						vout::mvec(zmag);
						break;
					case 6:
						vout::magm(zmag);
						break;
					case 7:
						vout::mean_magm(zmag);
						break;
					case 8:
						vout::mat_mvec(zmag);
						break;
					case 9:
						vout::mat_mean_magm(zmag);
						break;
					case 12:
						vout::mdoth(zmag);
						break;
					case 14:
						vout::systorque(zmag);
						break;
					case 15:
						vout::mean_systorque(zmag);
						break;
					case 16:
						vout::constraint_phi(zmag);
						break;
					case 17:
						vout::constraint_theta(zmag);
						break;
					case 18:
						vout::material_constraint_phi(zmag);
						break;
					case 19:
						vout::material_constraint_theta(zmag);
						break;
					case 20:
						vout::material_mean_systorque(zmag);
						break;
					case 21:
						vout::mean_system_susceptibility(zmag);
						break;
					case 22:
						vout::phonon_temperature(zmag);
						break;
					case 23:
						vout::material_temperature(zmag);
						break;
					case 24:
						vout::material_applied_field_strength(zmag);
						break;
					case 25:
						vout::material_fmr_field_strength(zmag);
						break;
					case 26:
						vout::mat_mdoth(zmag);
						break;
					case 27:
						vout::total_energy(zmag);
						break;
					case 28:
						vout::mean_total_energy(zmag);
						break;
					case 29:
						vout::total_anisotropy_energy(zmag);
						break;
					case 30:
						vout::mean_total_anisotropy_energy(zmag);
						break;
					case 31:
						vout::total_cubic_anisotropy_energy(zmag);
						break;
					case 32:
						vout::mean_total_cubic_anisotropy_energy(zmag);
						break;
					case 33:
						vout::total_surface_anisotropy_energy(zmag);
						break;
					case 34:
						vout::mean_total_surface_anisotropy_energy(zmag);
						break;
					case 35:
						vout::total_exchange_energy(zmag);
						break;
					case 36:
						vout::mean_total_exchange_energy(zmag);
						break;
					case 37:
						vout::total_applied_field_energy(zmag);
						break;
					case 38:
						vout::mean_total_applied_field_energy(zmag);
						break;
					case 39:
						vout::total_magnetostatic_energy(zmag);
						break;
					case 40:
						vout::mean_total_magnetostatic_energy(zmag);
						break;
					case 41:
						vout::total_so_anisotropy_energy(zmag);
						break;
					case 42:
						vout::mean_total_so_anisotropy_energy(zmag);
						break;
					case 43:
						vout::height_mvec(zmag);
						break;
					case 44:
						vout::material_height_mvec(zmag);
						break;
					case 45:
						vout::height_mvec_actual(zmag);
						break;
					case 46:
						vout::material_height_mvec_actual(zmag);
						break;
					case 47:
						vout::fmr_field_strength(zmag);
						break;
               case 48:
						vout::mean_mvec(zmag);
						break;
               case 49:
						vout::mat_mean_mvec(zmag);
						break;
               case 50:
						vout::mean_material_susceptibility(zmag);
						break;
					case 51:
						vout::mean_height_magnetisation_length(zmag);
						break;
					case 52:
						vout::mean_height_magnetisation(zmag);
						break;
					case 60:
						vout::MPITimings(zmag);
						break;
				}
			}
			// Carriage return
			if(file_output_list.size()>0) zmag << std::endl;

			} // end of code for rank 0 only
		} // end of if statement for output rate

		// Output data to cout
		if(vmpi::my_rank==0){
			if(sim::time%vout::output_rate==0){ // needs to be altered to separate variable at some point

            // For gpu acceleration get statistics from device (repeated here so additional performance cost for doing this)
            if(gpu::acceleration) gpu::stats::get();

				for(unsigned int item=0;item<screen_output_list.size();item++){
				switch(screen_output_list[item]){
					case 0:
						vout::time(std::cout);
						break;
					case 1:
						vout::real_time(std::cout);
						break;
					case 2:
						vout::temperature(std::cout);
						break;
					case 3:
						vout::Happ(std::cout);
						break;
					case 4:
						vout::Hvec(std::cout);
						break;
					case 5:
						vout::mvec(std::cout);
						break;
					case 6:
						vout::magm(std::cout);
						break;
					case 7:
						vout::mean_magm(std::cout);
						break;
					case 8:
						vout::mat_mvec(std::cout);
						break;
					case 9:
						vout::mat_mean_magm(std::cout);
						break;
					case 12:
						vout::mdoth(std::cout);
						break;
					case 14:
						vout::systorque(std::cout);
						break;
					case 15:
						vout::mean_systorque(std::cout);
						break;
					case 16:
						vout::constraint_phi(std::cout);
						break;
					case 17:
						vout::constraint_theta(std::cout);
						break;
					case 18:
						vout::material_constraint_phi(std::cout);
						break;
					case 19:
						vout::material_constraint_theta(std::cout);
						break;
					case 20:
						vout::material_mean_systorque(std::cout);
						break;
					case 21:
						vout::mean_system_susceptibility(std::cout);
						break;
					case 22:
						vout::phonon_temperature(std::cout);
						break;
					case 23:
						vout::material_temperature(std::cout);
						break;
					case 24:
						vout::material_applied_field_strength(std::cout);
						break;
					case 25:
						vout::material_fmr_field_strength(std::cout);
						break;
					case 26:
						vout::mat_mdoth(std::cout);
						break;
					case 27:
						vout::total_energy(std::cout);
						break;
					case 28:
						vout::mean_total_energy(std::cout);
						break;
					case 29:
						vout::total_anisotropy_energy(std::cout);
						break;
					case 30:
						vout::mean_total_anisotropy_energy(std::cout);
						break;
					case 31:
						vout::total_cubic_anisotropy_energy(std::cout);
						break;
					case 32:
						vout::mean_total_cubic_anisotropy_energy(std::cout);
						break;
					case 33:
						vout::total_surface_anisotropy_energy(std::cout);
						break;
					case 34:
						vout::mean_total_surface_anisotropy_energy(std::cout);
						break;
					case 35:
						vout::total_exchange_energy(std::cout);
						break;
					case 36:
						vout::mean_total_exchange_energy(std::cout);
						break;
					case 37:
						vout::total_applied_field_energy(std::cout);
						break;
					case 38:
						vout::mean_total_applied_field_energy(std::cout);
						break;
					case 39:
						vout::total_magnetostatic_energy(std::cout);
						break;
					case 40:
						vout::mean_total_magnetostatic_energy(std::cout);
						break;
					case 41:
						vout::total_so_anisotropy_energy(std::cout);
						break;
					case 42:
						vout::mean_total_so_anisotropy_energy(std::cout);
						break;
					case 47:
						vout::fmr_field_strength(std::cout);
						break;
               case 48:
						vout::mean_mvec(std::cout);
						break;
               case 49:
						vout::mat_mean_mvec(std::cout);
						break;
               case 50:
						vout::mean_material_susceptibility(std::cout);
						break;
					case 60:
						vout::MPITimings(std::cout);
						break;
				}
			}

			// Carriage return
			if(screen_output_list.size()>0) std::cout << std::endl;
			}

		} // End of if statement to output data to screen

		if(sim::time%vout::output_grain_rate==0){

		// calculate grain magnetisations
		grains::mag();

		// Output data to zgrain
		if(vmpi::my_rank==0){

			// check for open ofstream
			if(vout::grain_output_list.size() > 0 && !zgrain.is_open()){
				// check for checkpoint continue and append data
				if(sim::load_checkpoint_flag && sim::load_checkpoint_continue_flag) zgrain.open("grain",std::ofstream::app);
				// otherwise overwrite file
				else zgrain.open("grain",std::ofstream::trunc);
			}

			for(unsigned int item=0;item<vout::grain_output_list.size();item++){
			switch(vout::grain_output_list[item]){
				case 0:
					vout::time(zgrain);
					break;
				case 1:
					vout::real_time(zgrain);
					break;
				case 2:
					vout::temperature(zgrain);
					break;
				case 3:
					vout::Happ(zgrain);
					break;
				case 4:
					vout::Hvec(zgrain);
					break;
				case 10:
					vout::grain_mvec(zgrain);
					break;
				case 11:
					vout::grain_magm(zgrain);
					break;
				case 13:
					vout::grain_mat_mvec(zgrain);
					break;
				case 22:
					vout::phonon_temperature(zgrain);
					break;
			}
		}

		// Carriage return
		if(vout::grain_output_list.size()>0) zgrain << std::endl;
		}
		}

		// Output configuration files to disk
		config::output();

		// optionally save checkpoint file
		if(sim::save_checkpoint_flag==true && sim::save_checkpoint_continuous_flag==true && sim::time%sim::save_checkpoint_rate==0) save_checkpoint();

	} // end of data
コード例 #2
0
int main(int argc, char *argv[])
{
	char *msg;
	int seq;
	int argi;
	int alertcolors, alertinterval;
	char *configfn = NULL;
	char *checkfn = NULL;
	int checkpointinterval = 900;
	char acklogfn[PATH_MAX];
	FILE *acklogfd = NULL;
	char notiflogfn[PATH_MAX];
	FILE *notiflogfd = NULL;
	char *tracefn = NULL;
	struct sigaction sa;
	int configchanged;
	time_t lastxmit = 0;

	MEMDEFINE(acklogfn);
	MEMDEFINE(notiflogfn);

	libxymon_init(argv[0]);

	/* Dont save the error buffer */
	save_errbuf = 0;

	/* Load alert config */
	alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));
	alertinterval = 60*atoi(xgetenv("ALERTREPEAT"));

	/* Create our loookup-trees */
	hostnames = xtreeNew(strcasecmp);
	testnames = xtreeNew(strcasecmp);
	locations = xtreeNew(strcasecmp);

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--config=")) {
			configfn = strdup(strchr(argv[argi], '=')+1);
		}
		else if (argnmatch(argv[argi], "--checkpoint-file=")) {
			checkfn = strdup(strchr(argv[argi], '=')+1);
		}
		else if (argnmatch(argv[argi], "--checkpoint-interval=")) {
			char *p = strchr(argv[argi], '=') + 1;
			checkpointinterval = atoi(p);
		}
		else if (argnmatch(argv[argi], "--dump-config")) {
			load_alertconfig(configfn, alertcolors, alertinterval);
			dump_alertconfig(1);
			return 0;
		}
		else if (argnmatch(argv[argi], "--cfid")) {
			include_configid = 1;
		}
		else if (argnmatch(argv[argi], "--test")) {
			char *testhost = NULL, *testservice = NULL, *testpage = NULL, 
			     *testcolor = "red", *testgroups = NULL;
			void *hinfo;
			int testdur = 0;
			FILE *logfd = NULL;
			activealerts_t *awalk = NULL;
			int paramno = 0;

			argi++; if (argi < argc) testhost = argv[argi];
			argi++; if (argi < argc) testservice = argv[argi];
			argi++; 
			while (argi < argc) {
				if (strncasecmp(argv[argi], "--duration=", 11) == 0) {
					testdur = durationvalue(strchr(argv[argi], '=')+1);
				}
				else if (strncasecmp(argv[argi], "--color=", 8) == 0) {
					testcolor = strchr(argv[argi], '=')+1;
				}
				else if (strncasecmp(argv[argi], "--group=", 8) == 0) {
					testgroups = strchr(argv[argi], '=')+1;
				}
				else if (strncasecmp(argv[argi], "--time=", 7) == 0) {
					fakestarttime = (time_t)atoi(strchr(argv[argi], '=')+1);
				}
				else {
					paramno++;
					if (paramno == 1) testdur = atoi(argv[argi]);
					else if (paramno == 2) testcolor = argv[argi];
					else if (paramno == 3) fakestarttime = (time_t) atoi(argv[argi]);
				}

				argi++;
			}

			if ((testhost == NULL) || (testservice == NULL)) {
				printf("Usage: xymond_alert --test HOST SERVICE [options]\n");
				printf("Possible options:\n\t[--duration=MINUTES]\n\t[--color=COLOR]\n\t[--group=GROUPNAME]\n\t[--time=TIMESPEC]\n");

				return 1;
			}

			load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
			hinfo = hostinfo(testhost);
			if (hinfo) {
				testpage = strdup(xmh_item(hinfo, XMH_ALLPAGEPATHS));
			}
			else {
				errprintf("Host not found in hosts.cfg - assuming it is on the top page\n");
				testpage = "";
			}

			awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
			awalk->hostname = find_name(hostnames, testhost);
			awalk->testname = find_name(testnames, testservice);
			awalk->location = find_name(locations, testpage);
			awalk->ip = strdup("127.0.0.1");
			awalk->color = awalk->maxcolor = parse_color(testcolor);
			awalk->pagemessage = "Test of the alert configuration";
			awalk->eventstart = getcurrenttime(NULL) - testdur*60;
			awalk->groups = (testgroups ? strdup(testgroups) : NULL);
			awalk->state = A_PAGING;
			awalk->cookie = 12345;
			awalk->next = NULL;

			logfd = fopen("/dev/null", "w");
			starttrace(NULL);
			testonly = 1;

			load_alertconfig(configfn, alertcolors, alertinterval);
			load_holidays(0);
			send_alert(awalk, logfd);
			return 0;
		}
		else if (argnmatch(argv[argi], "--trace=")) {
			tracefn = strdup(strchr(argv[argi], '=')+1);
			starttrace(tracefn);
		}
		else if (net_worker_option(argv[argi])) {
			/* Handled in the subroutine */
		}
		else if (standardoption(argv[argi])) {
			if (showhelp) return 0;
		}
		else {
			errprintf("Unknown option '%s'\n", argv[argi]);
		}
	}

	/* Do the network stuff if needed */
	net_worker_run(ST_ALERT, LOC_SINGLESERVER, NULL);

	if (checkfn) {
		load_checkpoint(checkfn);
		nextcheckpoint = gettimer() + checkpointinterval;
		dbgprintf("Next checkpoint at %d, interval %d\n", (int) nextcheckpoint, checkpointinterval);
	}

	setup_signalhandler("xymond_alert");
	/* Need to handle these ourselves, so we can shutdown and save state-info */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_handler;
	sigaction(SIGPIPE, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT,  &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGUSR1, &sa, NULL);
	sigaction(SIGHUP,  &sa, NULL);

	if (xgetenv("XYMONSERVERLOGS")) {
		sprintf(acklogfn, "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS"));
		acklogfd = fopen(acklogfn, "a");
		sprintf(notiflogfn, "%s/notifications.log", xgetenv("XYMONSERVERLOGS"));
		notiflogfd = fopen(notiflogfn, "a");
	}

	/*
	 * The general idea here is that this loop handles receiving of alert-
	 * and ack-messages from the master daemon, and maintains a list of 
	 * host+test combinations that may have alerts going out.
	 *
	 * This module does not deal with any specific alert-configuration, 
	 * it just picks up the alert messages, maintains the list of 
	 * known tests that are in some sort of critical condition, and
	 * periodically pushes alerts to the do_alert.c module for handling.
	 *
	 * The only modification of alerts that happen here is the handling
	 * of when the next alert is due. It calls into the next_alert() 
	 * routine to learn when an alert should be repeated, and also 
	 * deals with Acknowledgments that stop alerts from going out for
	 * a period of time.
	 */
	while (running) {
		char *eoln, *restofmsg;
		char *metadata[20];
		char *p;
		int metacount;
		char *hostname = NULL, *testname = NULL;
		struct timespec timeout;
		time_t now, nowtimer;
		int anytogo;
		activealerts_t *awalk;
		int childstat;

		nowtimer = gettimer();
		if (checkfn && (nowtimer > nextcheckpoint)) {
			dbgprintf("Saving checkpoint\n");
			nextcheckpoint = nowtimer + checkpointinterval;
			save_checkpoint(checkfn);

			if (acklogfd) acklogfd = freopen(acklogfn, "a", acklogfd);
			if (notiflogfd) notiflogfd = freopen(notiflogfn, "a", notiflogfd);
		}

		timeout.tv_sec = 60; timeout.tv_nsec = 0;
		msg = get_xymond_message(C_PAGE, "xymond_alert", &seq, &timeout);
		if (msg == NULL) {
			running = 0;
			continue;
		}

		/* See what time it is - must happen AFTER the timeout */
		now = getcurrenttime(NULL);

		/* Split the message in the first line (with meta-data), and the rest */
 		eoln = strchr(msg, '\n');
		if (eoln) {
			*eoln = '\0';
			restofmsg = eoln+1;
		}
		else {
			restofmsg = "";
		}

		/* 
		 * Now parse the meta-data into elements.
		 * We use our own "gettok()" routine which works
		 * like strtok(), but can handle empty elements.
		 */
		metacount = 0; 
		memset(&metadata, 0, sizeof(metadata));
		p = gettok(msg, "|");
		while (p && (metacount < 19)) {
			metadata[metacount] = p;
			metacount++;
			p = gettok(NULL, "|");
		}
		metadata[metacount] = NULL;

		if (metacount > 3) hostname = metadata[3];
		if (metacount > 4) testname = metadata[4];

		if ((metacount > 10) && (strncmp(metadata[0], "@@page", 6) == 0)) {
			/* @@page|timestamp|sender|hostname|testname|hostip|expiretime|color|prevcolor|changetime|location|cookie|osname|classname|grouplist|modifiers */

			int newcolor, newalertstatus, oldalertstatus;

			dbgprintf("Got page message from %s:%s\n", hostname, testname);
			traceprintf("@@page %s:%s:%s=%s\n", hostname, testname, metadata[10], metadata[7]);

			awalk = find_active(hostname, testname);
			if (awalk == NULL) {
				char *hwalk = find_name(hostnames, hostname);
				char *twalk = find_name(testnames, testname);
				char *pwalk = find_name(locations, metadata[10]);

				awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
				awalk->hostname = hwalk;
				awalk->testname = twalk;
				awalk->location = pwalk;
				awalk->cookie = -1;
				awalk->state = A_DEAD;
				/*
				 * Use changetime here, if we restart the alert module then
				 * this gets the duration values more right than using "now".
				 * Also, define this only when a new alert arrives - we should
				 * NOT clear this when a status goes yellow->red, or if it
				 * flaps between yellow and red.
				 */
				awalk->eventstart = atoi(metadata[9]);
				add_active(awalk->hostname, awalk);
				traceprintf("New record\n");
			}

			newcolor = parse_color(metadata[7]);
			oldalertstatus = ((alertcolors & (1 << awalk->color)) != 0);
			newalertstatus = ((alertcolors & (1 << newcolor)) != 0);

			traceprintf("state %d->%d\n", oldalertstatus, newalertstatus);

			if (newalertstatus) {
				/* It's in an alert state. */
				awalk->color = newcolor;
				awalk->state = A_PAGING;

				if (newcolor > awalk->maxcolor) {
					if (awalk->maxcolor != 0) {
						/*
						 * Severity has increased (yellow -> red).
						 * Clear the repeat-interval, and set maxcolor to
						 * the new color. If it drops to yellow again,
						 * maxcolor stays at red, so a test that flaps
						 * between yellow and red will only alert on red
						 * the first time, and then follow the repeat
						 * interval.
						 */
						dbgprintf("Severity increased, cleared repeat interval: %s/%s %s->%s\n",
							awalk->hostname, awalk->testname,
							colorname(awalk->maxcolor), colorname(newcolor));
						clear_interval(awalk);
					}

					awalk->maxcolor = newcolor;
				}
			}
			else {
				/* 
				 * Send one "recovered" message out now, then go to A_DEAD.
				 * Dont update the color here - we want recoveries to go out 
				 * only if the alert color triggered an alert
				 */
				awalk->state = (newcolor == COL_BLUE) ? A_DISABLED : A_RECOVERED;
			}

			if (oldalertstatus != newalertstatus) {
				dbgprintf("Alert status changed from %d to %d\n", oldalertstatus, newalertstatus);
				clear_interval(awalk);
			}

			if (awalk->ip) xfree(awalk->ip);
			awalk->ip = strdup(metadata[5]);
			awalk->cookie = atoi(metadata[11]);
			if (awalk->osname) xfree(awalk->osname);
			awalk->osname    = (metadata[12] ? strdup(metadata[12]) : NULL);
			if (awalk->classname) xfree(awalk->classname);
			awalk->classname = (metadata[13] ? strdup(metadata[13]) : NULL);
			if (awalk->groups) xfree(awalk->groups);
			awalk->groups    = (metadata[14] ? strdup(metadata[14]) : NULL);
			if (awalk->pagemessage) xfree(awalk->pagemessage);
			if (metadata[15]) {
				/* Modifiers are more interesting than the message itself */
				awalk->pagemessage = (char *)malloc(strlen(awalk->hostname) + strlen(awalk->testname) + strlen(colorname(awalk->color)) + strlen(metadata[15]) + strlen(restofmsg) + 10);
				sprintf(awalk->pagemessage, "%s:%s %s\n%s\n%s",
					awalk->hostname, awalk->testname, colorname(awalk->color), metadata[15], restofmsg);
			}
			else {
				awalk->pagemessage = strdup(restofmsg);
			}
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@ack", 5) == 0)) {
 			/* @@ack|timestamp|sender|hostname|testname|hostip|expiretime */

			/*
			 * An ack is handled simply by setting the next
			 * alert-time to when the ack expires.
			 */
			time_t nextalert = atoi(metadata[6]);

			dbgprintf("Got ack message from %s:%s\n", hostname, testname);
			traceprintf("@@ack: %s:%s now=%d, ackeduntil %d\n",
				     hostname, testname, (int)now, (int)nextalert);

			awalk = find_active(hostname, testname);

			if (acklogfd) {
				int cookie = (awalk ? awalk->cookie : -1);
				int color  = (awalk ? awalk->color : 0);

				fprintf(acklogfd, "%d\t%d\t%d\t%d\t%s\t%s.%s\t%s\t%s\n",
					(int)now, cookie, 
					(int)((nextalert - now) / 60), cookie,
					"np_filename_not_used", 
					hostname, testname, 
					colorname(color),
					nlencode(restofmsg));
				fflush(acklogfd);
			}

			if (awalk && (awalk->state == A_PAGING)) {
				traceprintf("Record updated\n");
				awalk->state = A_ACKED;
				awalk->nextalerttime = nextalert;
				if (awalk->ackmessage) xfree(awalk->ackmessage);
				awalk->ackmessage = strdup(restofmsg);
			}
			else {
				traceprintf("No record\n");
			}
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@notify", 5) == 0)) {
			/* @@notify|timestamp|sender|hostname|testname|pagepath */

			char *hwalk = find_name(hostnames, hostname);
			char *twalk = find_name(testnames, testname);
			char *pwalk = find_name(locations, (metadata[5] ? metadata[5] : ""));

			awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
			awalk->hostname = hwalk;
			awalk->testname = twalk;
			awalk->location = pwalk;
			awalk->cookie = -1;
			awalk->pagemessage = strdup(restofmsg);
			awalk->eventstart = getcurrenttime(NULL);
			awalk->state = A_NOTIFY;
			add_active(awalk->hostname, awalk);
		}
		else if ((metacount > 3) && 
			 ((strncmp(metadata[0], "@@drophost", 10) == 0) || (strncmp(metadata[0], "@@dropstate", 11) == 0))) {
			/* @@drophost|timestamp|sender|hostname */
			/* @@dropstate|timestamp|sender|hostname */
			xtreePos_t handle;

			handle = xtreeFind(hostnames, hostname);
			if (handle != xtreeEnd(hostnames)) {
				alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle);
				for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD;
			}
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) {
			/* @@droptest|timestamp|sender|hostname|testname */

			awalk = find_active(hostname, testname);
			if (awalk) awalk->state = A_DEAD;
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) {
			/* @@renamehost|timestamp|sender|hostname|newhostname */

			/* 
			 * We handle rename's simply by dropping the alert. If there is still an
			 * active alert for the host, it will have to be dealt with when the next
			 * status update arrives.
			 */
			xtreePos_t handle;

			handle = xtreeFind(hostnames, hostname);
			if (handle != xtreeEnd(hostnames)) {
				alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle);
				for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD;
			}
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) {
			/* @@renametest|timestamp|sender|hostname|oldtestname|newtestname */

			/* 
			 * We handle rename's simply by dropping the alert. If there is still an
			 * active alert for the host, it will have to be dealt with when the next
			 * status update arrives.
			 */
			awalk = find_active(hostname, testname);
			if (awalk) awalk->state = A_DEAD;
		}
		else if (strncmp(metadata[0], "@@shutdown", 10) == 0) {
			running = 0;
			errprintf("Got a shutdown message\n");
			continue;
		}
		else if (strncmp(metadata[0], "@@logrotate", 11) == 0) {
			char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME");
			if (fn && strlen(fn)) {
				reopen_file(fn, "a", stdout);
				reopen_file(fn, "a", stderr);

				if (tracefn) {
					stoptrace();
					starttrace(tracefn);
				}
			}
			continue;
		}
		else if (strncmp(metadata[0], "@@reload", 8) == 0) {
			/* Nothing ... right now */
		}
		else if (strncmp(metadata[0], "@@idle", 6) == 0) {
			/* Timeout */
		}

		/*
		 * When a burst of alerts happen, we get lots of alert messages
		 * coming in quickly. So lets handle them in bunches and only 
		 * do the full alert handling once every 10 secs - that lets us
		 * combine a bunch of alerts into one transmission process.
		 */
		if (nowtimer < (lastxmit+10)) continue;
		lastxmit = nowtimer;

		/* 
		 * Loop through the activealerts list and see if anything is pending.
		 * This is an optimization, we could just as well just fork off the
		 * notification child and let it handle all of it. But there is no
		 * reason to fork a child process unless it is going to do something.
		 */
		configchanged = load_alertconfig(configfn, alertcolors, alertinterval);
		configchanged += load_holidays(0);
		anytogo = 0;
		for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
			int anymatch = 0;

			switch (awalk->state) {
			  case A_NORECIP:
				if (!configchanged) break;

				/* The configuration has changed - switch NORECIP -> PAGING */
				awalk->state = A_PAGING;
				clear_interval(awalk);
				/* Fall through */

			  case A_PAGING:
				if (have_recipient(awalk, &anymatch)) {
					if (awalk->nextalerttime <= now) anytogo++;
				}
				else {
					if (!anymatch) {
						awalk->state = A_NORECIP;
						cleanup_alert(awalk);
					}
				}
				break;

			  case A_ACKED:
				if (awalk->nextalerttime <= now) {
					/* An ack has expired, so drop the ack message and switch to A_PAGING */
					anytogo++;
					if (awalk->ackmessage) xfree(awalk->ackmessage);
					awalk->state = A_PAGING;
				}
				break;

			  case A_RECOVERED:
			  case A_DISABLED:
			  case A_NOTIFY:
				anytogo++;
				break;

			  case A_DEAD:
				break;
			}
		}
		dbgprintf("%d alerts to go\n", anytogo);

		if (anytogo) {
			pid_t childpid;

			childpid = fork();
			if (childpid == 0) {
				/* The child */
				start_alerts();
				for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
					switch (awalk->state) {
					  case A_PAGING:
						if (awalk->nextalerttime <= now) {
							send_alert(awalk, notiflogfd);
						}
						break;

					  case A_ACKED:
						/* Cannot be A_ACKED unless the ack is still valid, so no alert. */
						break;

					  case A_RECOVERED:
					  case A_DISABLED:
					  case A_NOTIFY:
						send_alert(awalk, notiflogfd);
						break;

					  case A_NORECIP:
					  case A_DEAD:
						break;
					}
				}
				finish_alerts();

				/* Child does not continue */
				exit(0);
			}
			else if (childpid < 0) {
				errprintf("Fork failed, cannot send alerts: %s\n", strerror(errno));
			}
		}

		/* Update the state flag and the next-alert timestamp */
		for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
			switch (awalk->state) {
			  case A_PAGING:
				if (awalk->nextalerttime <= now) awalk->nextalerttime = next_alert(awalk);
				break;

			  case A_NORECIP:
				break;

			  case A_ACKED:
				/* Still cannot get here except if ack is still valid */
				break;

			  case A_RECOVERED:
			  case A_DISABLED:
			  case A_NOTIFY:
				awalk->state = A_DEAD;
				/* Fall through */

			  case A_DEAD:
				cleanup_alert(awalk); 
				break;
			}
		}

		clean_all_active();

		/* Pickup any finished child processes to avoid zombies */
		while (wait3(&childstat, WNOHANG, NULL) > 0) ;
	}

	if (checkfn) save_checkpoint(checkfn);
	if (acklogfd) fclose(acklogfd);
	if (notiflogfd) fclose(notiflogfd);
	stoptrace();

	MEMUNDEFINE(notiflogfn);
	MEMUNDEFINE(acklogfn);

	if (termsig >= 0) {
		errprintf("Terminated by signal %d\n", termsig);
	}

	return 0;
}
コード例 #3
0
ファイル: sim.cpp プロジェクト: richard-evans/vampire
/// @brief Function to run one a single program
///
/// @callgraph
/// @callergraph
///
/// @section License
/// Use of this code, either in source or compiled form, is subject to license from the authors.
/// Copyright \htmlonly &copy \endhtmlonly Richard Evans, 2009-2011. All Rights Reserved.
///
/// @section Information
/// @author  Richard Evans, [email protected]
/// @version 1.1
/// @date    09/03/2011
///
/// @return EXIT_SUCCESS
///
/// @internal
///	Created:		02/10/2008
///	Revision:	1.1 09/03/2011
///=====================================================================================
///
int run(){
	// Check for calling of function
	if(err::check==true) std::cout << "sim::run has been called" << std::endl;

	// Initialise simulation data structures
	sim::initialize(mp::num_materials);

   anisotropy::initialize(atoms::num_atoms, atoms::type_array, mp::mu_s_array);

   // now seed generator
	mtrandom::grnd.seed(vmpi::parallel_rng_seed(mtrandom::integration_seed));

   // Check for load spin configurations from checkpoint
   if(sim::load_checkpoint_flag) load_checkpoint();

   {
      // Set up statistical data sets
      #ifdef MPICF
         int num_atoms_for_statistics = vmpi::num_core_atoms+vmpi::num_bdry_atoms;
      #else
         int num_atoms_for_statistics = atoms::num_atoms;
      #endif
      // unroll list of non-magnetic materials
      std::vector<bool> non_magnetic_materials_array(mp::num_materials, false);
      for(int m = 0; m < mp::num_materials; m++){
         if( mp::material[m].non_magnetic == 2 ) non_magnetic_materials_array[m] = true;
      }
      stats::initialize(num_atoms_for_statistics, mp::num_materials, atoms::m_spin_array, atoms::type_array, atoms::category_array, non_magnetic_materials_array);
   }

   // Precalculate initial statistics
   stats::update(atoms::x_spin_array, atoms::y_spin_array, atoms::z_spin_array, atoms::m_spin_array);

   // initialise dipole field calculation
   dipole::initialize(cells::num_atoms_in_unit_cell,
                     cells::num_cells,
                     cells::num_local_cells,
                     cells::macro_cell_size,
                     cells::local_cell_array,
                     cells::num_atoms_in_cell,
                     cells::num_atoms_in_cell_global, // <----
                     cells::index_atoms_array,
                     cells::volume_array,
                     cells::pos_and_mom_array,
                     cells::atom_in_cell_coords_array_x,
                     cells::atom_in_cell_coords_array_y,
                     cells::atom_in_cell_coords_array_z,
                     atoms::type_array,
                     cells::atom_cell_id_array,
                     atoms::x_coord_array,
                     atoms::y_coord_array,
                     atoms::z_coord_array,
                     atoms::num_atoms
   );

   // Initialize GPU acceleration if enabled
   if(gpu::acceleration) gpu::initialize();

   // For MPI version, calculate initialisation time
	if(vmpi::my_rank==0){
		#ifdef MPICF
			std::cout << "Time for initialisation: " << MPI_Wtime()-vmpi::start_time << std::endl;
			zlog << zTs() << "Time for initialisation: " << MPI_Wtime()-vmpi::start_time << std::endl;
			vmpi::start_time=MPI_Wtime(); // reset timer
		#endif
   }

   // Set timer for runtime
   stopwatch_t stopwatch;
   stopwatch.start();

   // Precondition spins at equilibration temperature
   sim::internal::monte_carlo_preconditioning();

   // For MPI version, calculate initialisation time
   if(vmpi::my_rank==0){
		std::cout << "Starting Simulation with Program ";
		zlog << zTs() << "Starting Simulation with Program ";
	}

	// Now set initial compute time
	#ifdef MPICF
	vmpi::ComputeTime=MPI_Wtime();
	vmpi::WaitTime=MPI_Wtime();
	vmpi::TotalComputeTime=0.0;
	vmpi::TotalWaitTime=0.0;
	#endif

	// Select program to run
	switch(sim::program){
		case 0:
			if(vmpi::my_rank==0){
				std::cout << "Benchmark..." << std::endl;
				zlog << "Benchmark..." << std::endl;
			}
			program::bmark();
			break;

		case 1:
			if(vmpi::my_rank==0){
				std::cout << "Time-Series..." << std::endl;
				zlog << "Time-Series..." << std::endl;
			}
			program::time_series();
			break;

		case 2:
			if(vmpi::my_rank==0){
				std::cout << "Hysteresis-Loop..." << std::endl;
				zlog << "Hysteresis-Loop..." << std::endl;
			}
			program::hysteresis();
			break;

		case 3:
			if(vmpi::my_rank==0){
				std::cout << "Static-Hysteresis-Loop..." << std::endl;
				zlog << "Static-Hysteresis-Loop..." << std::endl;
			}
			program::static_hysteresis();
			break;

		case 4:
			if(vmpi::my_rank==0){
				std::cout << "Curie-Temperature..." << std::endl;
				zlog << "Curie-Temperature..." << std::endl;
			}
			program::curie_temperature();
			break;

		case 5:
			if(vmpi::my_rank==0){
				std::cout << "Field-Cool..." << std::endl;
				zlog << "Field-Cool..." << std::endl;
			}
			program::field_cool();
			break;

		case 6:
			if(vmpi::my_rank==0){
				std::cout << "Temperature-Pulse..." << std::endl;
				zlog << "Temperature-Pulse..." << std::endl;
			}
			program::temperature_pulse();
			break;

		case 7:
			if(vmpi::my_rank==0){
				std::cout << "HAMR-Simulation..." << std::endl;
				zlog << "HAMR-Simulation..." << std::endl;
			}
			program::hamr();
			break;

		case 8:
			if(vmpi::my_rank==0){
				std::cout << "CMC-Anisotropy..." << std::endl;
				zlog << "CMC-Anisotropy..." << std::endl;
			}
			program::cmc_anisotropy();
			break;

		case 9:
			if(vmpi::my_rank==0){
				std::cout << "Hybrid-CMC..." << std::endl;
				zlog << "Hybrid-CMC..." << std::endl;
			}
			program::hybrid_cmc();
			break;

      case 10:
         if(vmpi::my_rank==0){
            std::cout << "Reverse-Hybrid-CMC..." << std::endl;
            zlog << "Reverse-Hybrid-CMC..." << std::endl;
         }
         program::reverse_hybrid_cmc();
         break;

      case 11:
         if(vmpi::my_rank==0){
            std::cout << "LaGrange-Multiplier..." << std::endl;
            zlog << "LaGrange-Multiplier..." << std::endl;
         }
         program::lagrange_multiplier();
         break;

      case 12:
         if(vmpi::my_rank==0){
            std::cout << "partial-hysteresis-loop..." << std::endl;
            zlog << "partial-hysteresis-loop..." << std::endl;
         }
         program::partial_hysteresis_loop();
         break;

      case 13:
         if(vmpi::my_rank==0){
            std::cout << "localised-temperature-pulse..." << std::endl;
            zlog << "localised-temperature-pulse..." << std::endl;
         }
         program::localised_temperature_pulse();
         break;

      case 14:
         if(vmpi::my_rank==0){
            std::cout << "effective-damping..." << std::endl;
            zlog << "effective-damping..." << std::endl;
         }
         program::effective_damping();
         break;

		case 15:
	  		if(vmpi::my_rank==0){
	    		std::cout << "fmr..." << std::endl;
	    		zlog << "fmr..." << std::endl;
	  		}
	  		program::fmr();
	  		break;

		case 16:
	  		if(vmpi::my_rank==0){
	    		std::cout << "localised-field-cool..." << std::endl;
	    		zlog << "localised-field-cool..." << std::endl;
	  		}
	  		program::local_field_cool();
	  		break;

		case 50:
			if(vmpi::my_rank==0){
				std::cout << "Diagnostic-Boltzmann..." << std::endl;
				zlog << "Diagnostic-Boltzmann..." << std::endl;
			}
			program::boltzmann_dist();
			break;

	    case 51:
		  	if(vmpi::my_rank==0){
		       std::cout << "Setting..." << std::endl;
		       zlog << "Setting..." << std::endl;
	     	}
		  	program::setting_process();
		    break;

		default:{
			std::cerr << "Unknown Internal Program ID "<< sim::program << " requested, exiting" << std::endl;
			zlog << "Unknown Internal Program ID "<< sim::program << " requested, exiting" << std::endl;
			exit (EXIT_FAILURE);
			}
	}

   std::cout <<     "Simulation run time [s]: " << stopwatch.elapsed_seconds() << std::endl;
   zlog << zTs() << "Simulation run time [s]: " << stopwatch.elapsed_seconds() << std::endl;

   //------------------------------------------------
   // Output Monte Carlo statistics if applicable
   //------------------------------------------------
   if(sim::integrator==1){
      std::cout << "Monte Carlo statistics:" << std::endl;
      std::cout << "\tTotal moves: " << long(sim::mc_statistics_moves) << std::endl;
      std::cout << "\t" << ((sim::mc_statistics_moves - sim::mc_statistics_reject)/sim::mc_statistics_moves)*100.0 << "% Accepted" << std::endl;
      std::cout << "\t" << (sim::mc_statistics_reject/sim::mc_statistics_moves)*100.0                              << "% Rejected" << std::endl;
      zlog << zTs() << "Monte Carlo statistics:" << std::endl;
      zlog << zTs() << "\tTotal moves: " << sim::mc_statistics_moves << std::endl;
      zlog << zTs() << "\t" << ((sim::mc_statistics_moves - sim::mc_statistics_reject)/sim::mc_statistics_moves)*100.0 << "% Accepted" << std::endl;
      zlog << zTs() << "\t" << (sim::mc_statistics_reject/sim::mc_statistics_moves)*100.0                              << "% Rejected" << std::endl;
   }
   if(sim::integrator==3 || sim::integrator==4){
      std::cout << "Constrained Monte Carlo statistics:" << std::endl;
      std::cout << "\tTotal moves: " << cmc::mc_total << std::endl;
      std::cout << "\t" << (cmc::mc_success/cmc::mc_total)*100.0    << "% Accepted" << std::endl;
      std::cout << "\t" << (cmc::energy_reject/cmc::mc_total)*100.0 << "% Rejected (Energy)" << std::endl;
      std::cout << "\t" << (cmc::sphere_reject/cmc::mc_total)*100.0 << "% Rejected (Sphere)" << std::endl;
      zlog << zTs() << "Constrained Monte Carlo statistics:" << std::endl;
      zlog << zTs() << "\tTotal moves: " << cmc::mc_total << std::endl;
      zlog << zTs() << "\t" << (cmc::mc_success/cmc::mc_total)*100.0    << "% Accepted" << std::endl;
      zlog << zTs() << "\t" << (cmc::energy_reject/cmc::mc_total)*100.0 << "% Rejected (Energy)" << std::endl;
      zlog << zTs() << "\t" << (cmc::sphere_reject/cmc::mc_total)*100.0 << "% Rejected (Sphere)" << std::endl;
   }

	//program::LLB_Boltzmann();

   // De-initialize GPU
   if(gpu::acceleration) gpu::finalize();

   // optionally save checkpoint file
   if(sim::save_checkpoint_flag && !sim::save_checkpoint_continuous_flag) save_checkpoint();

	return EXIT_SUCCESS;
}