def test_generated_sfTCP():
    graph, existence_for_node_time, connectivity_demand = generate_scale_free_graph(
        num_nodes=1000, max_time=3, active_time_percent=1)
    model, edge_variables = generate_TCP_model(graph, existence_for_node_time,
                                               connectivity_demand)
    NUM_ITERATIONS = 10
    vertex_usage_count = {}
    solutions = []
    start_time = python_time.time()

    for _ in range(NUM_ITERATIONS):
        subgraph = solve_TCP_instance(model, graph, edge_variables)
        if not subgraph:
            break
        model = add_optimal_solution_constraint(model,
                                                subgraph,
                                                edge_variables,
                                                additional_constraint=2)
        solutions.append(subgraph)
        for vertex in subgraph.nodes():
            if vertex in vertex_usage_count:
                vertex_usage_count[vertex] += 1
            else:
                vertex_usage_count[vertex] = 1

    end_time = python_time.time()
    days, hours, minutes, seconds = execution_time(start_time, end_time)
    print(
        'Solving for multiple solutions %s days, %s hours, %s minutes, %s seconds'
        % (days, hours, minutes, seconds))

    return graph, vertex_usage_count
def solve_TCP_instance(model,
                       graph,
                       edge_variables,
                       detailed_output=True,
                       time_output=False):
    """
	Given a simple TCP problem instance, returns a minimum weight subgraph that satisfies the demand.

	:param graph: a directed graph with attribute 'weight' on all edges
	:param model: a Gurobi model to be optimized
	:param edge_variables: a dictionary of variables corresponding to the variables d_v,w
	:param detailed_output: flag which when True will print the edges in the optimal subgraph
	:param time_output: flag which when True will return the time taken to obtain result rather than the optimal subgraph
	:return: a optimal subgraph containing the path if the solution is Optimal, else None
	"""

    start_time = python_time.time()

    # SOLVE AND RECOVER SOLUTION
    print(
        '-----------------------------------------------------------------------'
    )
    model.optimize()
    print "Solution Count: " + str(model.SolCount)
    subgraph = retreive_and_print_subgraph(model, graph, edge_variables,
                                           detailed_output)

    end_time = python_time.time()
    days, hours, minutes, seconds = execution_time(start_time, end_time)
    print('sDCP solving took %s days, %s hours, %s minutes, %s seconds' %
          (days, hours, minutes, seconds))

    # Return solution iff found
    if time_output:
        return end_time - start_time

    return subgraph if model.status == GRB.status.OPTIMAL else None
def solve_TCP_instance(graph, existence_for_node_time, connectivity_demand, detailed_output=True, time_output=False):

	"""
	Given a simple TCP problem instance, returns a minimum weight subgraph that satisfies the demand.

	:param graph: a directed graph with attribute 'weight' on all edges
	:param existence_for_node_time: a dictionary from (node, time) to existence {True, False}
	:param connectivity_demand: a connectivity demand (source, demand)
	:param detailed_output: flag which when True will print the edges in the optimal subgraph
	:param time_output: flag which when True will return the time taken to obtain result rather than the optimal subgraph
	:return:
	"""

	start_time = python_time.time()

	# MODEL SETUP
	# Infer a list of times
	times = list(set([node_time[1] for node_time in existence_for_node_time.keys()]))

	# Sources get +1 sourceflow, destinations get -1, other nodes 0
	sourceflow = {(v, t): 0 for v in graph.nodes_iter() for t in times}
	source, destination = connectivity_demand
	sourceflow[source, 0] = 1
	sourceflow[destination, max(times)] = -1

	# Create empty optimization model
	model = Model('temporal_connectivity')

	# Create variables d_{uvtt'}
	edge_time_variables = {}
	for t in times:
		for t_prime in times:
			for u, v in graph.edges_iter():
				edge_time_variables[u, v, t, t_prime] = model.addVar(vtype=GRB.BINARY, name='edge_time_%s_%s_%s_%s' % (u, v, t, t_prime))

	# Create variables d_{uv}
	edge_variables = {}
	for u, v in graph.edges_iter():
		edge_variables[u, v] = model.addVar(vtype=GRB.BINARY, name='edge_%s_%s' % (u, v))

	model.update()

	# CONSTRAINTS
	# Edge decision constraints (an edge is chosen if it is chosen at any time)
	for t in times:
		for t_prime in times:
			for u, v in graph.edges_iter():
				model.addConstr(edge_variables[u, v] >= edge_time_variables[u, v, t, t_prime])

	# Existence constraints (can only route flow through active nodes)
	for t in times:
		for t_prime in times:
			for u, v in graph.edges_iter():
				model.addConstr(edge_time_variables[u, v, t, t_prime] <= existence_for_node_time[u, t])
				model.addConstr(edge_time_variables[u, v, t, t_prime] <= existence_for_node_time[v, t_prime])

	for t in times:
		for t_prime in times:
			if t != t_prime and t+1 != t_prime:
				model.addConstr(edge_time_variables[u, v, t, t_prime] == 0)

	# Flow conservation constraints
	for t in times:
		for v in graph.nodes_iter():
			if t != 0 and t != max(times):
				model.addConstr(
					quicksum(edge_time_variables[u, v, t-1, t] for u in graph.predecessors_iter(v)) +
					quicksum(edge_time_variables[u, v, t, t] for u in graph.predecessors_iter(v)) +
					sourceflow[v, t] ==
					quicksum(edge_time_variables[v, w, t, t] for w in graph.successors_iter(v)) +
					quicksum(edge_time_variables[v, w, t, t+1] for w in graph.successors_iter(v))
				)
			if t == 0:
				model.addConstr(
					quicksum(edge_time_variables[u, v, t, t] for u in graph.predecessors_iter(v)) +
					sourceflow[v, t] ==
					quicksum(edge_time_variables[v, w, t, t] for w in graph.successors_iter(v)) +
					quicksum(edge_time_variables[v, w, t, t + 1] for w in graph.successors_iter(v))
				)
			if t == max(times):
				model.addConstr(
					quicksum(edge_time_variables[u, v, t - 1, t] for u in graph.predecessors_iter(v)) +
					quicksum(edge_time_variables[u, v, t, t] for u in graph.predecessors_iter(v)) +
					sourceflow[v, t] ==
					quicksum(edge_time_variables[v, w, t, t] for w in graph.successors_iter(v))
				)



	# OBJECTIVE
	# Minimize total path weight
	objective_expression = quicksum(edge_variables[u, v] * graph[u][v]['weight'] for u, v in graph.edges_iter())
	model.setObjective(objective_expression, GRB.MINIMIZE)

	# SOLVE AND RECOVER SOLUTION
	print('-----------------------------------------------------------------------')
	model.optimize()

	subgraph = retreive_and_print_subgraph(model, graph, edge_variables, detailed_output)

	end_time = python_time.time()
	days, hours, minutes, seconds = execution_time(start_time, end_time)
	print('sDCP solving took %s days, %s hours, %s minutes, %s seconds' % (days, hours, minutes, seconds))

	# Return solution iff found
	if time_output:
		return end_time - start_time
	return subgraph if model.status == GRB.status.OPTIMAL else None
Esempio n. 4
0
def afire_dispatcher(afire_home, afire_data_dict, afire_options):
    """
    Dispatch one or more Active Fires jobs to the multiprocessing pool, and report back the final
    job statuses.
    """

    # Construct a list of task dicts...
    granule_id_list = sorted(afire_data_dict.keys())
    afire_tasks = []
    for granule_id in granule_id_list:
        args = {
            'granule_dict': afire_data_dict[granule_id],
            'afire_home': afire_home,
            'afire_options': afire_options
        }
        afire_tasks.append(args)

    # Setup the processing pool
    cpu_count = multiprocessing.cpu_count()
    LOG.info('There are {} available CPUs'.format(cpu_count))

    requested_cpu_count = afire_options['num_cpu']

    if requested_cpu_count is not None:
        LOG.info('We have requested {} {}'.format(
            requested_cpu_count,
            "CPU" if requested_cpu_count == 1 else "CPUs"))

        if requested_cpu_count > cpu_count:
            LOG.warn(
                '{} requested CPUs is greater than available, using {}'.format(
                    requested_cpu_count, cpu_count))
            cpus_to_use = cpu_count
        else:
            cpus_to_use = requested_cpu_count
    else:
        cpus_to_use = cpu_count

    LOG.info('We are using {}/{} available CPUs'.format(
        cpus_to_use, cpu_count))
    pool = multiprocessing.Pool(cpus_to_use)

    # Submit the Active Fire tasks to the processing pool
    timeout = 9999999
    result_list = []

    start_time = time.time()

    LOG.info("Submitting {} Active Fire {} to the pool...".format(
        len(afire_tasks), "task" if len(afire_tasks) == 1 else "tasks"))
    result_list = pool.map_async(afire_submitter, afire_tasks).get(timeout)

    end_time = time.time()

    total_afire_time = execution_time(start_time, end_time)
    LOG.debug("afire execution took {:9.6f} seconds".format(
        total_afire_time['delta']))
    LOG.info(
        "Active Fire execution took {} days, {} hours, {} minutes, {:8.6f} seconds"
        .format(total_afire_time['days'], total_afire_time['hours'],
                total_afire_time['minutes'], total_afire_time['seconds']))
    LOG.info('')

    rc_exe_dict = {}
    rc_problem_dict = {}

    # Loop through each of the Active Fire results collect error information
    for result in result_list:
        granule_id, afire_rc, problem_rc, exe_out = result
        LOG.debug(">>> granule_id {}: afire_rc = {}, problem_rc = {}".format(
            granule_id, afire_rc, problem_rc))

        # Did the actual afire binary succeed?
        rc_exe_dict[granule_id] = afire_rc
        rc_problem_dict[granule_id] = problem_rc

    return rc_exe_dict, rc_problem_dict
Esempio n. 5
0
def afire_submitter(args):
    '''
    This routine encapsulates the single unit of work, multiple instances of which are submitted to
    the multiprocessing queue. It takes as input whatever is required to complete the work unit,
    and returns return values and output logging from the external process.
    '''

    # This try block wraps all code in this worker function, to capture any exceptions.
    try:

        granule_dict = args['granule_dict']
        afire_home = args['afire_home']
        afire_options = args['afire_options']

        granule_id = granule_dict['granule_id']
        run_dir = granule_dict['run_dir']
        cmd = granule_dict['cmd']
        work_dir = afire_options['work_dir']
        env_vars = {}

        rc_exe = 0
        rc_problem = 0
        exe_out = "Finished the Active Fires granule {}".format(granule_id)

        LOG.debug("granule_id = {}".format(granule_id))
        LOG.debug("run_dir = {}".format(run_dir))
        LOG.debug("cmd = {}".format(cmd))
        LOG.debug("work_dir = {}".format(work_dir))
        LOG.debug("env_vars = {}".format(env_vars))

        current_dir = os.getcwd()

        LOG.info("Processing granule_id {}...".format(granule_id))

        # Create the run dir for this input file
        log_idx = 0
        while True:
            run_dir = pjoin(
                work_dir, "{}_run_{}".format(granule_dict['run_dir'], log_idx))
            if not exists(run_dir):
                os.makedirs(run_dir)
                break
            else:
                log_idx += 1

        os.chdir(run_dir)

        # Download and stage the required ancillary data for this input file
        LOG.info("\tStaging the required ancillary data for granule_id {}...".
                 format(granule_id))
        failed_ancillary = False
        try:
            rc_ancil, rc_ancil_dict, lwm_file = get_lwm(
                afire_options, granule_dict)
            failed_ancillary = True if rc_ancil != 0 else False
        except Exception as err:
            failed_ancillary = True
            LOG.warn('\tProblem generating LWM for granule_id {}'.format(
                granule_id))
            LOG.error(err)
            LOG.debug(traceback.format_exc())

        # Run the active fire binary
        if afire_options['ancillary_only']:

            LOG.info(
                '''\tAncillary only, skipping Active Fire execution for granule_id {}'''
                .format(granule_id))
            if failed_ancillary:
                LOG.warn(
                    '\tAncillary granulation failed for granule_id {}'.format(
                        granule_id))
                rc_problem = 1

            os.chdir(current_dir)

        elif failed_ancillary:

            LOG.warn('\tAncillary granulation failed for granule_id {}'.format(
                granule_id))
            os.chdir(current_dir)
            rc_problem = 1

        else:
            # Link the required files and directories into the work directory...
            paths_to_link = [
                pjoin(afire_home, 'vendor', afire_options['vfire_exe']),
                lwm_file,
            ] + [
                granule_dict[key]['file']
                for key in afire_options['input_prefixes']
            ]
            number_linked = link_files(run_dir, paths_to_link)
            LOG.debug("\tWe are linking {} files to the run dir:".format(
                number_linked))
            for linked_files in paths_to_link:
                LOG.debug("\t{}".format(linked_files))

            # Contruct a dictionary of error conditions which should be logged.
            error_keys = [
                'FAILURE', 'failure', 'FAILED', 'failed', 'FAIL', 'fail',
                'ERROR', 'error', 'ERR', 'err', 'ABORTING', 'aborting',
                'ABORT', 'abort'
            ]
            error_dict = {
                x: {
                    'pattern': x,
                    'count_only': False,
                    'count': 0,
                    'max_count': None,
                    'log_str': ''
                }
                for x in error_keys
            }
            error_dict['error_keys'] = error_keys

            start_time = time.time()

            rc_exe, exe_out = execute_binary_captured_inject_io(
                run_dir,
                cmd,
                error_dict,
                log_execution=False,
                log_stdout=False,
                log_stderr=False,
                **env_vars)

            end_time = time.time()

            afire_time = execution_time(start_time, end_time)
            LOG.debug("\tafire execution of {} took {:9.6f} seconds".format(
                granule_id, afire_time['delta']))
            LOG.info(
                "\tafire execution of {} took {} days, {} hours, {} minutes, {:8.6f} seconds"
                .format(granule_id, afire_time['days'], afire_time['hours'],
                        afire_time['minutes'], afire_time['seconds']))

            LOG.debug("\tGranule ID: {}, rc_exe = {}".format(
                granule_id, rc_exe))

            os.chdir(current_dir)

            # Write the afire output to a log file, and parse it to determine the output
            creation_dt = datetime.utcnow()
            timestamp = creation_dt.isoformat()
            logname = "{}_{}.log".format(run_dir, timestamp)
            log_dir = dirname(run_dir)
            logpath = pjoin(log_dir, logname)
            logfile_obj = open(logpath, 'w')
            for line in exe_out.splitlines():
                logfile_obj.write(str(line) + "\n")
            logfile_obj.close()

            # Update the various file global attributes
            try:

                old_output_file = pjoin(run_dir, granule_dict['AFEDR']['file'])
                creation_dt = granule_dict['creation_dt']

                # Check whether the target AF text file exists, and remove it.
                output_txt_file = '{}.txt'.format(splitext(old_output_file)[0])
                if exists(output_txt_file):
                    LOG.debug('{} exists, removing.'.format(output_txt_file))
                    os.remove(output_txt_file)

                #
                # Update the attributes, moving to the end
                #
                if afire_options['i_band']:

                    # Update the I-band attributes, and write the fire data to a text file.
                    h5_file_obj = h5py.File(old_output_file, "a")
                    h5_file_obj.attrs.create(
                        'date_created', np.string_(creation_dt.isoformat()))
                    h5_file_obj.attrs.create('granule_id',
                                             np.string_(granule_id))
                    history_string = 'CSPP Active Fires version: {}'.format(
                        afire_options['version'])
                    h5_file_obj.attrs.create('history',
                                             np.string_(history_string))
                    h5_file_obj.attrs.create(
                        'Metadata_Link', np.string_(basename(old_output_file)))
                    h5_file_obj.attrs.create(
                        'id', np.string_(getURID(creation_dt)['URID']))

                    # Extract desired data from the NetCDF4 file, for output to the text file
                    nfire = h5_file_obj.attrs['FirePix'][0]
                    if int(nfire) > 0:
                        fire_datasets = [
                            'FP_latitude', 'FP_longitude', 'FP_T4',
                            'FP_confidence', 'FP_power'
                        ]
                        fire_data = []
                        for dset in fire_datasets:
                            fire_data.append(h5_file_obj['/' + dset][:])

                    h5_file_obj.close()

                    # Check if there are any fire pixels, and write the associated fire data to
                    # a text file...

                    LOG.info("\tGranule {} has {} fire pixels".format(
                        granule_id, nfire))

                    if int(nfire) > 0:
                        Along_scan_pixel_dim = 0.375
                        Along_track_pixel_dim = 0.375
                        fire_pixel_res = [
                            Along_scan_pixel_dim, Along_track_pixel_dim
                        ]

                        format_str = '''{0:13.8f}, {1:13.8f}, {2:13.8f}, {5:6.3f}, {6:6.3f},''' \
                            ''' {3:4d}, {4:13.8f}'''

                        txt_file_header = \
                            '''# Active Fires I-band EDR\n''' \
                            '''#\n''' \
                            '''# source: {}\n''' \
                            '''# version: {}\n''' \
                            '''#\n''' \
                            '''# column 1: latitude of fire pixel (degrees)\n''' \
                            '''# column 2: longitude of fire pixel (degrees)\n''' \
                            '''# column 3: I04 brightness temperature of fire pixel (K)\n''' \
                            '''# column 4: Along-scan fire pixel resolution (km)\n''' \
                            '''# column 5: Along-track fire pixel resolution (km)\n''' \
                            '''# column 6: detection confidence ([7,8,9]->[lo,med,hi])\n''' \
                            '''# column 7: fire radiative power (MW)\n''' \
                            '''#\n# number of fire pixels: {}\n''' \
                            '''#'''.format(basename(old_output_file), history_string, nfire)

                        nasa_file = output_txt_file.replace('dev', 'dev_nasa')
                        if exists(nasa_file):
                            LOG.debug('{} exists, removing.'.format(nasa_file))
                            os.remove(nasa_file)

                        LOG.info("\tWriting output text file {}".format(
                            output_txt_file))
                        txt_file_obj = open(output_txt_file, 'x')

                        try:
                            txt_file_obj.write(txt_file_header + "\n")

                            for FP_latitude, FP_longitude, FP_R13, FP_confidence, FP_power in zip(
                                    *fire_data):
                                fire_vars = [
                                    FP_latitude, FP_longitude, FP_R13,
                                    FP_confidence, FP_power
                                ]
                                line = format_str.format(*(fire_vars +
                                                           fire_pixel_res))
                                txt_file_obj.write(line + "\n")

                            txt_file_obj.close()
                        except Exception:
                            txt_file_obj.close()
                            rc_problem = 1
                            LOG.warning(
                                "\tProblem writing Active fire text file: {}".
                                format(output_txt_file))
                            LOG.warn(traceback.format_exc())
                else:

                    # Update the M-band attributes, and write the fire data to a text file.

                    nc_file_obj = Dataset(old_output_file,
                                          "a",
                                          format="NETCDF4")
                    setattr(nc_file_obj, 'date_created',
                            creation_dt.isoformat())
                    setattr(nc_file_obj, 'granule_id', granule_id)
                    history_string = 'CSPP Active Fires version: {}'.format(
                        afire_options['version'])
                    setattr(nc_file_obj, 'history', history_string)
                    setattr(nc_file_obj, 'Metadata_Link',
                            basename(old_output_file))
                    setattr(nc_file_obj, 'id', getURID(creation_dt)['URID'])

                    # Extract desired data from the NetCDF4 file, for output to the text file
                    nfire = len(nc_file_obj['Fire Pixels'].dimensions['nfire'])
                    if int(nfire) > 0:
                        fire_datasets = [
                            'FP_latitude', 'FP_longitude', 'FP_T13',
                            'FP_confidence', 'FP_power'
                        ]
                        fire_data = []
                        for dset in fire_datasets:
                            fire_data.append(
                                nc_file_obj['Fire Pixels'].variables[dset][:])
                    nc_file_obj.close()

                    # Check if there are any fire pixels, and write the associated fire data to
                    # a text file...

                    LOG.info("\tGranule {} has {} fire pixels".format(
                        granule_id, nfire))

                    if int(nfire) > 0:
                        Along_scan_pixel_dim = 0.75
                        Along_track_pixel_dim = 0.75
                        fire_pixel_res = [
                            Along_scan_pixel_dim, Along_track_pixel_dim
                        ]

                        format_str = '''{0:13.8f}, {1:13.8f}, {2:13.8f}, {5:6.3f}, {6:6.3f},''' \
                            ''' {3:4d}, {4:13.8f}'''

                        txt_file_header = \
                            '''# Active Fires M-band EDR\n''' \
                            '''#\n''' \
                            '''# source: {}\n''' \
                            '''# version: {}\n''' \
                            '''#\n''' \
                            '''# column 1: latitude of fire pixel (degrees)\n''' \
                            '''# column 2: longitude of fire pixel (degrees)\n''' \
                            '''# column 3: M13 brightness temperature of fire pixel (K)\n''' \
                            '''# column 4: Along-scan fire pixel resolution (km)\n''' \
                            '''# column 5: Along-track fire pixel resolution (km)\n''' \
                            '''# column 6: detection confidence (%)\n''' \
                            '''# column 7: fire radiative power (MW)\n''' \
                            '''#\n# number of fire pixels: {}\n''' \
                            '''#'''.format(basename(old_output_file), history_string, nfire)

                        LOG.info("\tWriting output text file {}".format(
                            output_txt_file))
                        txt_file_obj = open(output_txt_file, 'x')

                        try:
                            txt_file_obj.write(txt_file_header + "\n")

                            for FP_latitude, FP_longitude, FP_T13, FP_confidence, FP_power in zip(
                                    *fire_data):
                                fire_vars = [
                                    FP_latitude, FP_longitude, FP_T13,
                                    FP_confidence, FP_power
                                ]
                                line = format_str.format(*(fire_vars +
                                                           fire_pixel_res))
                                txt_file_obj.write(line + "\n")

                            txt_file_obj.close()
                        except Exception:
                            txt_file_obj.close()
                            rc_problem = 1
                            LOG.warning(
                                "\tProblem writing Active fire text file: {}".
                                format(output_txt_file))
                            LOG.warn(traceback.format_exc())

            except Exception:
                rc_problem = 1
                LOG.warning(
                    "\tProblem setting attributes in output file {}".format(
                        old_output_file))
                LOG.debug(traceback.format_exc())

            # Move output files to the work directory
            LOG.debug("\tMoving output files from {} to {}".format(
                run_dir, work_dir))
            af_prefix = 'AFIMG' if afire_options['i_band'] else 'AFMOD'
            af_suffix = 'nc' if afire_options[
                'i_band'] else 'nc'  # FIXME: NOAA should fix NC output for I-band!
            outfiles = glob(pjoin(run_dir, '{}*.{}'.format(af_prefix, af_suffix))) \
                     + glob(pjoin(run_dir, '{}*.txt'.format(af_prefix)))

            for outfile in outfiles:
                try:
                    shutil.move(outfile, work_dir)
                except Exception:
                    rc_problem = 1
                    LOG.warning(
                        "\tProblem moving output {} from {} to {}".format(
                            outfile, run_dir, work_dir))
                    LOG.debug(traceback.format_exc())

        # If no problems, remove the run dir
        if (rc_exe == 0) and (rc_problem == 0) and afire_options['docleanup']:
            cleanup([run_dir])

    except Exception:
        LOG.warn("\tGeneral warning for {}".format(granule_id))
        LOG.debug(traceback.format_exc())
        os.chdir(current_dir)
        #raise

    return [granule_id, rc_exe, rc_problem, exe_out]
def nagg_submitter(args):
    '''
    This routine encapsulates the single unit of work, multiple instances of which are submitted to
    the multiprocessing queue. It takes as input whatever is required to complete the work unit,
    and returns return values and output logging from the external process.
    '''

    # This try block wraps all code in this worker function, to capture any exceptions.
    try:

        afire_home = args['afire_home']
        agg_input_file = args['agg_input_file']
        unagg_inputs_dir = args['unagg_inputs_dir']
        afire_options = args['afire_options']
        work_dir = afire_options['work_dir']
        env_vars = {}

        rc_exe = 0
        rc_problem = 0
        exe_out = "Finished running nagg on the aggregated VIIRS file: {}".format(
            agg_input_file)

        LOG.debug("afire_home = {}".format(afire_home))
        LOG.debug("agg_input_file = {}".format(agg_input_file))
        LOG.debug("unagg_inputs_dir = {}".format(unagg_inputs_dir))
        LOG.debug("work_dir = {}".format(work_dir))
        LOG.debug("env_vars = {}".format(env_vars))

        current_dir = os.getcwd()

        LOG.info("Processing aggregated file {}...".format(agg_input_file))

        os.chdir(unagg_inputs_dir)

        #nagg_exe = os.path.join(afire_home, 'vendor/nagg')
        nagg_exe = './nagg'
        prefix = os.path.basename(agg_input_file).split('_')[0]

        cmd_dict = {}
        cmd_dict['GEO'] = '{} -S -g {} -n 1 -O cspp -D dev -d {} {}'.format(
            nagg_exe, prefix, unagg_inputs_dir, agg_input_file)
        cmd_dict[
            'SVM'] = '{} -t {} -S -g no -n 1 -O cspp -D dev -d {} {}'.format(
                nagg_exe, prefix, unagg_inputs_dir, agg_input_file)

        if 'GMTCO' in os.path.basename(agg_input_file):
            cmd = cmd_dict['GEO']
        elif 'GITCO' in os.path.basename(agg_input_file):
            cmd = cmd_dict['GEO']
        elif 'SVM' in os.path.basename(agg_input_file):
            cmd = cmd_dict['SVM']
        elif 'SVI' in os.path.basename(agg_input_file):
            cmd = cmd_dict['SVM']
        elif 'IVCDB' in os.path.basename(agg_input_file):
            cmd = cmd_dict['SVM']
        else:
            cmd = None
        #cmd = '''sleep 0.5; echo "Running nagg on {0:}"; exit 0'''.format(
        #os.path.basename(agg_input_file))

        # Contruct a dictionary of error conditions which should be logged.
        error_keys = [
            'FAILURE', 'failure', 'FAILED', 'failed', 'FAIL', 'fail', 'ERROR',
            'error', 'ERR', 'err', 'ABORTING', 'aborting', 'ABORT', 'abort'
        ]
        error_dict = {
            x: {
                'pattern': x,
                'count_only': False,
                'count': 0,
                'max_count': None,
                'log_str': ''
            }
            for x in error_keys
        }
        error_dict['error_keys'] = error_keys

        if cmd is not None:
            start_time = time.time()

            rc_exe, exe_out = execute_binary_captured_inject_io(
                unagg_inputs_dir,
                cmd,
                error_dict,
                log_execution=False,
                log_stdout=False,
                log_stderr=False,
                **env_vars)

            end_time = time.time()

            nagg_time = execution_time(start_time, end_time)
            LOG.debug("\tnagg execution of {} took {:9.6f} seconds".format(
                os.path.basename(agg_input_file), nagg_time['delta']))
            LOG.info(
                "\tnagg execution for {} took {} days, {} hours, {} minutes, {:8.6f} seconds"
                .format(os.path.basename(agg_input_file), nagg_time['days'],
                        nagg_time['hours'], nagg_time['minutes'],
                        nagg_time['seconds']))

            LOG.debug("\tnagg({}), rc_exe = {}".format(
                os.path.basename(agg_input_file), rc_exe))
        else:
            exe_out = '''Aggregated file {} cannot be unaggregated by nagg,''' \
                ''' unrecognized prefix {}.'''.format(prefix, os.path.basename(agg_input_file))
            LOG.warn('\t' + exe_out)

        # Write the afire output to a log file, and parse it to determine the output
        creation_dt = datetime.utcnow()
        timestamp = creation_dt.isoformat()
        logname = "nagg_unaggregate-{}-{}.log".format(
            os.path.basename(agg_input_file), timestamp)
        logpath = os.path.join(unagg_inputs_dir, logname)
        logfile_obj = open(logpath, 'w')
        for line in exe_out.splitlines():
            logfile_obj.write(line + "\n")
        logfile_obj.close()

        os.chdir(current_dir)

    except Exception:
        LOG.warn("\tGeneral warning for {}".format(
            os.path.basename(agg_input_file)))
        LOG.debug(traceback.format_exc())
        os.chdir(current_dir)
        raise

    return [os.path.basename(agg_input_file), rc_exe, rc_problem, exe_out]
def unaggregate_inputs(afire_home, agg_input_files, afire_options):
    '''
    Create a dir for the unaggregated files in the work dir, and use nagg to unaggregate the
    aggregated input files.
    '''

    unagg_inputs_dir = os.path.join(afire_options['work_dir'],
                                    'unaggregated_inputs')
    unagg_inputs_dir = create_dir(unagg_inputs_dir)

    # Construct a list of task dicts...
    nagg_tasks = []
    for agg_input_file in agg_input_files:
        args = {
            'afire_home': afire_home,
            'agg_input_file': agg_input_file,
            'unagg_inputs_dir': unagg_inputs_dir,
            'afire_options': afire_options
        }
        nagg_tasks.append(args)

    # Link the nagg executable into the unaggregated inputs dir...
    paths_to_link = [os.path.join(afire_home, 'vendor/nagg')]
    number_linked = link_files(unagg_inputs_dir, paths_to_link)
    LOG.debug(
        "\tWe are linking {} files to the run dir:".format(number_linked))
    for linked_files in paths_to_link:
        LOG.debug("\t{}".format(linked_files))

    # Setup the processing pool
    cpu_count = multiprocessing.cpu_count()
    LOG.debug('There are {} available CPUs'.format(cpu_count))

    requested_cpu_count = afire_options['num_cpu']

    if requested_cpu_count is not None:
        LOG.debug('We have requested {} {}'.format(
            requested_cpu_count,
            "CPU" if requested_cpu_count == 1 else "CPUs"))

        if requested_cpu_count > cpu_count:
            LOG.warn(
                '{} requested CPUs is greater than available, using {}'.format(
                    requested_cpu_count, cpu_count))
            cpus_to_use = cpu_count
        else:
            cpus_to_use = requested_cpu_count
    else:
        cpus_to_use = cpu_count

    LOG.debug('We are using {}/{} available CPUs'.format(
        cpus_to_use, cpu_count))
    pool = multiprocessing.Pool(cpus_to_use)

    # Submit the Active Fire tasks to the processing pool
    timeout = 9999999
    result_list = []

    start_time = time.time()

    LOG.info("Submitting {} nagg {} to the pool...".format(
        len(nagg_tasks), "task" if len(nagg_tasks) == 1 else "tasks"))
    result_list = pool.map_async(nagg_submitter, nagg_tasks).get(timeout)

    end_time = time.time()

    total_afire_time = execution_time(start_time, end_time)
    LOG.debug("Unaggregation took {:9.6f} seconds".format(
        total_afire_time['delta']))
    LOG.info(
        "Unaggregation took {} days, {} hours, {} minutes, {:8.6f} seconds".
        format(total_afire_time['days'], total_afire_time['hours'],
               total_afire_time['minutes'], total_afire_time['seconds']))

    # Loop through each of the Active Fire results collect error information
    for result in result_list:
        agg_input_file, nagg_rc, problem_rc, exe_out = result
        LOG.debug(
            ">>> agg_input_file {}: nagg_rc = {}, problem_rc = {}".format(
                agg_input_file, nagg_rc, problem_rc))

    return unagg_inputs_dir
Esempio n. 8
0
import random
from utils import execution_time
from bubblesort import bubble_sorter
from mergesort import merge_sorter
from insertsort import insertion_sort
from shellsort import shell_sort
from selectionsort import selection_sort
from quicksort import quick_sort

lst = random.sample(range(0, 100000), 40000)
function_lst = [
    merge_sorter, insertion_sort, shell_sort, bubble_sorter, selection_sort
]

for f in function_lst:
    f = execution_time(f)
    f(lst)