Esempio n. 1
0
File: eval.c Progetto: linwukang/pcp
/* Mark expression as having invalid values */
void
clobber(Expr *x)
{
    int		i;
    Boolean	*t;
    double	*d;

    if (x->op < NOP) {
	if (x->arg1)
	    clobber(x->arg1);
	if (x->arg2)
	    clobber(x->arg2);
	x->valid = 0;
	/*
	 * numeric variable or variable?
	 */
	if (x->sem == PM_SEM_COUNTER ||
	    x->sem == PM_SEM_INSTANT || x->sem == PM_SEM_DISCRETE ||
	    x->sem == SEM_NUMVAR) {
	    d = (double *) x->ring;
	    for (i = 0; i < x->nvals; i++)
		*d++ = mynan;
	}
	else if (x->sem == SEM_BOOLEAN) {
	    t = (Boolean *) x->ring;
	    for (i = 0; i < x->nvals; i++)
		*t++ = B_UNKNOWN;
	}
    }
}
Esempio n. 2
0
int *foo(void)
{
  int i;
  int j;

  clobber (&a[0][0]);
  clobber (&b[0][0]);
  clobber (&c[0][0]);

  for (i = 0; i < N; i++) {
      for (j = 0; j < N; j++) {
	  c[j][i] += a[j][i] + c[j][i];
      }
  }
  return &c[0][0];
}
Esempio n. 3
0
/***********************************************************************//**
 * @brief Save counts cube
 *
 * This method saves the counts cube into a FITS file.
 ***************************************************************************/
void ctbin::save(void)
{
    // Write header
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Save observations");
        }
        else {
            log.header1("Save observation");
        }
    }

    // Get output filename
    m_outcube = (*this)["outcube"].filename();

    // Get CTA observation from observation container
    GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);

    // Save only if observation is valid
    if (obs != NULL) {
        obs->save(m_outcube, clobber());
    }

    // Return
    return;
}
Esempio n. 4
0
/***********************************************************************//**
 * @brief Save model cube
 *
 * Saves the model cube into a FITS file specified using the "outfile"
 * task parameter.
 ***************************************************************************/
void ctmodel::save(void)
{
    // Write header
    if (logTerse()) {
        log << std::endl;
        log.header1("Save cube");
    }

    // Make sure we have the FITS filename
    m_outcube = (*this)["outcube"].filename();

    // Save only if filename is non-empty
    if (m_outcube.length() > 0) {

        // Dump filename
        if (logTerse()) {
            log << "Save \""+m_outcube+"\"" << std::endl;
        }

        // Save model cube into FITS file
        m_cube.save(m_outcube, clobber());

    }

    // Return
    return;
}
Esempio n. 5
0
/***********************************************************************//**
 * @brief Save event list into FITS file
 *
 * @param[in] obs Pointer to CTA observation.
 * @param[in] infile Input file name.
 * @param[in] outfile Output file name.
 *
 * Saves an event list into a FITS file and copy all others extensions from
 * the input file to the output file.
 ***************************************************************************/
void ctselect::save_event_list(const GCTAObservation* obs,
                               const std::string&     infile,
                               const std::string&     outfile) const
{
    // Save only if observation is valid
    if (obs != NULL) {

        // Save observation into FITS file
        obs->save(outfile, clobber());

        // Copy all extensions other than EVENTS and GTI from the input to
        // the output event list. The EVENTS and GTI extensions are written
        // by the save method, all others that may eventually be present
        // have to be copied by hand.
        GFits infits(infile);
        GFits outfits(outfile);
        for (int extno = 1; extno < infits.size(); ++extno) {
            GFitsHDU* hdu = infits.hdu(extno);
            if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") {
                outfits.append(*hdu);
            }
        }

        // Close input file
        infits.close();

        // Save file to disk and close it (we need both operations)
        outfits.save(true);
        outfits.close();

    } // endif: observation was valid

    // Return
    return;
}
Esempio n. 6
0
/***********************************************************************//**
 * @brief Save event list(s) in XML format.
 *
 * Save the event list(s) into FITS files and write the file path information
 * into a XML file. The filename of the XML file is specified by the outfile
 * parameter, the filename(s) of the event lists are built by prepending a
 * prefix to the input event list filenames. Any path present in the input
 * filename will be stripped, i.e. the event list(s) will be written in the
 * local working directory (unless a path is specified in the prefix).
 ***************************************************************************/
void ctobssim::save_xml(void)
{
    // Get output filename and prefix
    m_outevents = (*this)["outevents"].filename();
    m_prefix  = (*this)["prefix"].string();

    // Issue warning if output filename has no .xml suffix
    std::string suffix = gammalib::tolower(m_outevents.substr(m_outevents.length()-4,4));
    if (suffix != ".xml") {
        log << "*** WARNING: Name of observation definition output file \""+
               m_outevents+"\"" << std::endl;
        log << "*** WARNING: does not terminate with \".xml\"." << std::endl;
        log << "*** WARNING: This is not an error, but might be misleading."
               " It is recommended" << std::endl;
        log << "*** WARNING: to use the suffix \".xml\" for observation"
               " definition files." << std::endl;
    }

    // Save only if event lists have not yet been saved and disposed
    if (!m_save_and_dispose) {

        // Loop over all observation in the container
        for (int i = 0; i < m_obs.size(); ++i) {

            // Get CTA observation
            GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

            // Handle only CTA observations
            if (obs != NULL) {

                // Continue only if there is an event list (it may have been disposed)
                if (obs->events()->size() != 0) {

                    // Set event output file name
                    std::string outfile = m_prefix + gammalib::str(i) + ".fits";

                    // Store output file name in observation
                    obs->eventfile(outfile);

                    // Save observation into FITS file
                    obs->save(outfile, clobber());

                }

            } // endif: observation was a CTA observations

        } // endfor: looped over observations

    } // endif: event list has not yet been saved and disposed

    // Save observations in XML file
    m_obs.save(m_outevents);

    // Return
    return;
}
Esempio n. 7
0
/***********************************************************************//**
 * @brief Save event list(s) in XML format.
 *
 * Save the event list(s) into FITS files and write the file path information
 * into a XML file. The filename of the XML file is specified by the outfile
 * parameter, the filename(s) of the event lists are built by prepending a
 * prefix to the input event list filenames. Any path present in the input
 * filename will be stripped, i.e. the event list(s) will be written in the
 * local working directory (unless a path is specified in the prefix).
 ***************************************************************************/
void ctobssim::save_xml(void)
{
    // Get output filename and prefix
    m_outfile = (*this)["outfile"].filename();
    m_prefix  = (*this)["prefix"].string();

    // Issue warning if output filename has no .xml suffix
    std::string suffix = gammalib::tolower(m_outfile.substr(m_outfile.length()-4,4));
    if (suffix != ".xml") {
        log << "*** WARNING: Name of observation definition output file \""+
               m_outfile+"\"" << std::endl;
        log << "*** WARNING: does not terminate with \".xml\"." << std::endl;
        log << "*** WARNING: This is not an error, but might be misleading."
               " It is recommended" << std::endl;
        log << "*** WARNING: to use the suffix \".xml\" for observation"
               " definition files." << std::endl;
    }

    // Initialise file number
    int file_num = 0;

    // Loop over all observation in the container
    for (int i = 0; i < m_obs.size(); ++i) {

        // Get CTA observation
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

        // Handle only CTA observations
        if (obs != NULL) {

            // Set event output file name
            std::string outfile = m_prefix + gammalib::str(file_num) + ".fits";

            // Store output file name in observation
            obs->eventfile(outfile);

            // Save observation into FITS file
            obs->save(outfile, clobber());

            // Increment file number
            file_num++;


        } // endif: observation was a CTA observations

    } // endfor: looped over observations

    // Save observations in XML file
    m_obs.save(m_outfile);

    // Return
    return;
}
Esempio n. 8
0
/***********************************************************************//**
 * @brief Save event list in FITS format.
 *
 * Save the event list as a FITS file. The filename of the FITS file is
 * specified by the outfile parameter.
 ***************************************************************************/
void ctobssim::save_fits(void)
{
    // Get output filename
    m_outfile = (*this)["outfile"].filename();

    // Get CTA observation from observation container
    GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);

    // Save observation into FITS file
    obs->save(m_outfile, clobber());

    // Return
    return;
}
Esempio n. 9
0
/***********************************************************************//**
 * @brief Save a single model map into a FITS file
 *
 * @param[in] obs Pointer to CTA observation.
 * @param[in] outfile Output file name.
 *
 * This method saves a single model map into a FITS file. The method does
 * nothing if the observation pointer is not valid.
 ***************************************************************************/
void ctmodel::save_model_map(const GCTAObservation* obs,
                             const std::string&     outfile) const
{
    // Save only if observation is valid
    if (obs != NULL) {

        // Save observation into FITS file
        obs->save(outfile, clobber());

    } // endif: observation was valid

    // Return
    return;
}
Esempio n. 10
0
/***********************************************************************//**
 * @brief Save PSF cube
 ***************************************************************************/
void ctpsfcube::save(void)
{
    // Write header
    if (logTerse()) {
        log << std::endl;
        log.header1("Save PSF cube");
    }

    // Get output filename
    m_outcube = (*this)["outcube"].filename();

    // Save PSF cube
    m_psfcube.save(m_outcube, clobber());

    // Return
    return;
}
Esempio n. 11
0
/***********************************************************************//**
 * @brief Save event list in FITS format.
 *
 * Save the event list as a FITS file. The filename of the FITS file is
 * specified by the outfile parameter.
 ***************************************************************************/
void ctobssim::save_fits(void)
{
    // Save only if event list has not yet been saved and disposed
    if (!m_save_and_dispose) {

        // Get output filename
        m_outevents = (*this)["outevents"].filename();

        // Get CTA observation from observation container
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]);

        // Save observation into FITS file
        obs->save(m_outevents, clobber());

    } // endif: event list has not yet been saved and disposed

    // Return
    return;
}
Esempio n. 12
0
File: eval.c Progetto: linwukang/pcp
/* invalidate all expressions being evaluated
   i.e. mark values as unknown */
void
invalidate(void)
{
    Task    *t;
    Expr    *x;
    Symbol  *s;
    int	    i;

    t = taskq;
    while (t) {
	s = t->rules;
	for (i = 0; i < t->nrules; i++) {
	    x = symValue(*s);
	    clobber(x);
	    s++;
	}
	t = t->next;
    }
}
Esempio n. 13
0
/*
 * find all expressions for a host that has just been marked "down"
 * and invalidate them
 */
static void
mark_all(Host *hdown)
{
    Task	*t;
    Symbol	*s;
    Metric	*m;
    Expr	*x;
    int		i;

    for (t = taskq; t != NULL; t = t->next) {
	s = t->rules;
	for (i = 0; i < t->nrules; i++, s++) {
	    x = (Expr *)symValue(*s);
	    for (m = x->metrics; m != NULL; m = m->next) {
		if (m->host == hdown)
		    clobber(x);
	    }
	}
    }
}
Esempio n. 14
0
/***********************************************************************//**
 * @brief Save exposure cube
 *
 * Saves the exposure cube into a FITS file.
 ***************************************************************************/
void ctexpcube::save(void)
{
    // Write header into logger
    log_header1(TERSE, "Save exposure cube");

    // Get exposure cube filename
    m_outcube = (*this)["outcube"].filename();

    // Save exposure cube if filename and the exposure cube are not empty
    if (!m_outcube.is_empty() && !m_expcube.cube().is_empty()) {
        m_expcube.save(m_outcube, clobber());
    }

    // Write into logger what has been done
    std::string fname = (m_outcube.is_empty()) ? "NONE" : m_outcube.url();
    if (m_expcube.cube().is_empty()) {
        fname.append(" (cube is empty, no file created)");
    }
    log_value(NORMAL, "Exposure cube file", fname);

    // Return
    return;
}
Esempio n. 15
0
    bool run()
    {
        for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
            VariableAccessData* variable = &m_graph.m_variableAccessData[i];
            if (!variable->isRoot())
                continue;
            variable->clearVotes();
        }
        
        // Identify the set of variables that are always subject to the same structure
        // checks. For now, only consider monomorphic structure checks (one structure).
        
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
            if (!block)
                continue;
            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                NodeIndex nodeIndex = block->at(indexInBlock);
                Node& node = m_graph[nodeIndex];
                if (!node.shouldGenerate())
                    continue;
                switch (node.op()) {
                case CheckStructure: {
                    Node& child = m_graph[node.child1()];
                    if (child.op() != GetLocal)
                        break;
                    VariableAccessData* variable = child.variableAccessData();
                    variable->vote(VoteStructureCheck);
                    if (variable->isCaptured() || variable->structureCheckHoistingFailed())
                        break;
                    if (!isCellSpeculation(variable->prediction()))
                        break;
                    noticeStructureCheck(variable, node.structureSet());
                    break;
                }
                    
                case ForwardCheckStructure:
                case ForwardStructureTransitionWatchpoint:
                    // We currently rely on the fact that we're the only ones who would
                    // insert this node.
                    ASSERT_NOT_REACHED();
                    break;
                    
                case GetByOffset:
                case PutByOffset:
                case PutStructure:
                case StructureTransitionWatchpoint:
                case AllocatePropertyStorage:
                case ReallocatePropertyStorage:
                case GetPropertyStorage:
                case GetByVal:
                case PutByVal:
                case PutByValAlias:
                case GetArrayLength:
                case CheckArray:
                case GetIndexedPropertyStorage:
                case Phantom:
                    // Don't count these uses.
                    break;
                    
                default:
                    m_graph.vote(node, VoteOther);
                    break;
                }
            }
        }
        
        // Disable structure hoisting on variables that appear to mostly be used in
        // contexts where it doesn't make sense.
        
        for (unsigned i = m_graph.m_variableAccessData.size(); i--;) {
            VariableAccessData* variable = &m_graph.m_variableAccessData[i];
            if (!variable->isRoot())
                continue;
            if (variable->voteRatio() >= Options::structureCheckVoteRatioForHoisting())
                continue;
            HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
            if (iter == m_map.end())
                continue;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
            dataLog("Zeroing the structure to hoist for %s because the ratio is %lf.\n",
                    m_graph.nameOfVariableAccessData(variable), variable->voteRatio());
#endif
            iter->second.m_structure = 0;
        }

        // Identify the set of variables that are live across a structure clobber.
        
        Operands<VariableAccessData*> live(
            m_graph.m_blocks[0]->variablesAtTail.numberOfArguments(),
            m_graph.m_blocks[0]->variablesAtTail.numberOfLocals());
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
            if (!block)
                continue;
            ASSERT(live.numberOfArguments() == block->variablesAtTail.numberOfArguments());
            ASSERT(live.numberOfLocals() == block->variablesAtTail.numberOfLocals());
            for (unsigned i = live.size(); i--;) {
                NodeIndex indexAtTail = block->variablesAtTail[i];
                VariableAccessData* variable;
                if (indexAtTail == NoNode)
                    variable = 0;
                else
                    variable = m_graph[indexAtTail].variableAccessData();
                live[i] = variable;
            }
            for (unsigned indexInBlock = block->size(); indexInBlock--;) {
                NodeIndex nodeIndex = block->at(indexInBlock);
                Node& node = m_graph[nodeIndex];
                if (!node.shouldGenerate())
                    continue;
                switch (node.op()) {
                case GetLocal:
                case Flush:
                    // This is a birth.
                    live.operand(node.local()) = node.variableAccessData();
                    break;
                    
                case SetLocal:
                case SetArgument:
                    ASSERT(live.operand(node.local())); // Must be live.
                    ASSERT(live.operand(node.local()) == node.variableAccessData()); // Must have the variable we expected.
                    // This is a death.
                    live.operand(node.local()) = 0;
                    break;
                    
                // Use the CFA's notion of what clobbers the world.
                case ValueAdd:
                    if (m_graph.addShouldSpeculateInteger(node))
                        break;
                    if (Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()]))
                        break;
                    clobber(live);
                    break;
                    
                case CompareLess:
                case CompareLessEq:
                case CompareGreater:
                case CompareGreaterEq:
                case CompareEq: {
                    Node& left = m_graph[node.child1()];
                    Node& right = m_graph[node.child2()];
                    if (Node::shouldSpeculateInteger(left, right))
                        break;
                    if (Node::shouldSpeculateNumber(left, right))
                        break;
                    if (node.op() == CompareEq) {
                        if ((m_graph.isConstant(node.child1().index())
                             && m_graph.valueOfJSConstant(node.child1().index()).isNull())
                            || (m_graph.isConstant(node.child2().index())
                                && m_graph.valueOfJSConstant(node.child2().index()).isNull()))
                            break;
                        
                        if (Node::shouldSpeculateFinalObject(left, right))
                            break;
                        if (Node::shouldSpeculateArray(left, right))
                            break;
                        if (left.shouldSpeculateFinalObject() && right.shouldSpeculateFinalObjectOrOther())
                            break;
                        if (right.shouldSpeculateFinalObject() && left.shouldSpeculateFinalObjectOrOther())
                            break;
                        if (left.shouldSpeculateArray() && right.shouldSpeculateArrayOrOther())
                            break;
                        if (right.shouldSpeculateArray() && left.shouldSpeculateArrayOrOther())
                            break;
                    }
                    clobber(live);
                    break;
                }
                    
                case GetByVal:
                case PutByVal:
                case PutByValAlias:
                    if (m_graph.byValIsPure(node))
                        break;
                    clobber(live);
                    break;
                    
                case GetMyArgumentsLengthSafe:
                case GetMyArgumentByValSafe:
                case GetById:
                case GetByIdFlush:
                case PutStructure:
                case PhantomPutStructure:
                case PutById:
                case PutByIdDirect:
                case Call:
                case Construct:
                case Resolve:
                case ResolveBase:
                case ResolveBaseStrictPut:
                case ResolveGlobal:
                    clobber(live);
                    break;
                    
                default:
                    ASSERT(node.op() != Phi);
                    break;
                }
            }
        }
        
        bool changed = false;

#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        for (HashMap<VariableAccessData*, CheckData>::iterator it = m_map.begin();
             it != m_map.end(); ++it) {
            if (!it->second.m_structure) {
                dataLog("Not hoisting checks for %s because of heuristics.\n", m_graph.nameOfVariableAccessData(it->first));
                continue;
            }
            if (it->second.m_isClobbered && !it->second.m_structure->transitionWatchpointSetIsStillValid()) {
                dataLog("Not hoisting checks for %s because the structure is clobbered and has an invalid watchpoint set.\n", m_graph.nameOfVariableAccessData(it->first));
                continue;
            }
            dataLog("Hoisting checks for %s\n", m_graph.nameOfVariableAccessData(it->first));
        }
#endif // DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        
        // Make changes:
        // 1) If a variable's live range does not span a clobber, then inject structure
        //    checks before the SetLocal.
        // 2) If a variable's live range spans a clobber but is watchpointable, then
        //    inject structure checks before the SetLocal and replace all other structure
        //    checks on that variable with structure transition watchpoints.
        
        InsertionSet<NodeIndex> insertionSet;
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
            BasicBlock* block = m_graph.m_blocks[blockIndex].get();
            if (!block)
                continue;
            for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
                NodeIndex nodeIndex = block->at(indexInBlock);
                Node& node = m_graph[nodeIndex];
                // Be careful not to use 'node' after appending to the graph. In those switch
                // cases where we need to append, we first carefully extract everything we need
                // from the node, before doing any appending.
                if (!node.shouldGenerate())
                    continue;
                switch (node.op()) {
                case SetArgument: {
                    ASSERT(!blockIndex);
                    // Insert a GetLocal and a CheckStructure immediately following this
                    // SetArgument, if the variable was a candidate for structure hoisting.
                    // If the basic block previously only had the SetArgument as its
                    // variable-at-tail, then replace it with this GetLocal.
                    VariableAccessData* variable = node.variableAccessData();
                    HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
                    if (iter == m_map.end())
                        break;
                    if (!iter->second.m_structure)
                        break;
                    if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid())
                        break;
                    
                    node.ref();

                    CodeOrigin codeOrigin = node.codeOrigin;
                    
                    Node getLocal(GetLocal, codeOrigin, OpInfo(variable), nodeIndex);
                    getLocal.predict(variable->prediction());
                    getLocal.ref();
                    NodeIndex getLocalIndex = m_graph.size();
                    m_graph.append(getLocal);
                    insertionSet.append(indexInBlock + 1, getLocalIndex);
                    
                    Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), getLocalIndex);
                    checkStructure.ref();
                    NodeIndex checkStructureIndex = m_graph.size();
                    m_graph.append(checkStructure);
                    insertionSet.append(indexInBlock + 1, checkStructureIndex);
                    
                    if (block->variablesAtTail.operand(variable->local()) == nodeIndex)
                        block->variablesAtTail.operand(variable->local()) = getLocalIndex;
                    
                    m_graph.substituteGetLocal(*block, indexInBlock, variable, getLocalIndex);
                    
                    changed = true;
                    break;
                }
                    
                case SetLocal: {
                    VariableAccessData* variable = node.variableAccessData();
                    HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable);
                    if (iter == m_map.end())
                        break;
                    if (!iter->second.m_structure)
                        break;
                    if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid())
                        break;

                    // First insert a dead SetLocal to tell OSR that the child's value should
                    // be dropped into this bytecode variable if the CheckStructure decides
                    // to exit.
                    
                    CodeOrigin codeOrigin = node.codeOrigin;
                    NodeIndex child1 = node.child1().index();
                    
                    Node setLocal(SetLocal, codeOrigin, OpInfo(variable), child1);
                    NodeIndex setLocalIndex = m_graph.size();
                    m_graph.append(setLocal);
                    insertionSet.append(indexInBlock, setLocalIndex);
                    m_graph[child1].ref();
                    // Use a ForwardCheckStructure to indicate that we should exit to the
                    // next bytecode instruction rather than reexecuting the current one.
                    Node checkStructure(ForwardCheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), child1);
                    checkStructure.ref();
                    NodeIndex checkStructureIndex = m_graph.size();
                    m_graph.append(checkStructure);
                    insertionSet.append(indexInBlock, checkStructureIndex);
                    changed = true;
                    break;
                }
                    
                case CheckStructure: {
                    Node& child = m_graph[node.child1()];
                    if (child.op() != GetLocal)
                        break;
                    HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(child.variableAccessData());
                    if (iter == m_map.end())
                        break;
                    if (!iter->second.m_structure)
                        break;
                    if (!iter->second.m_isClobbered) {
                        node.setOpAndDefaultFlags(Phantom);
                        ASSERT(node.refCount() == 1);
                        break;
                    }
                    if (!iter->second.m_structure->transitionWatchpointSetIsStillValid())
                        break;
                    ASSERT(iter->second.m_structure == node.structureSet().singletonStructure());
                    node.convertToStructureTransitionWatchpoint();
                    changed = true;
                    break;
                }
                    
                default:
                    break;
                }
            }
            insertionSet.execute(*block);
        }
        
        return changed;
    }
Esempio n. 16
0
/***********************************************************************//**
 * @brief Simulate event data
 *
 * This method runs the simulation. Results are not saved by this method.
 * Invoke "save" to save the results.
 ***************************************************************************/
void ctobssim::run(void)
{
    // Switch screen logging on in debug mode
    if (logDebug()) {
        log.cout(true);
    }

    // Get parameters
    get_parameters();

    // Write input parameters into logger
    if (logTerse()) {
        log_parameters();
        log << std::endl;
    }

    // Special mode: if read ahead is specified we know that we called
    // the execute() method, hence files are saved immediately and event
    // lists are disposed afterwards.
    if (read_ahead()) {
        m_save_and_dispose = true;
    }

    // Determine the number of valid CTA observations, set energy dispersion flag
    // for all CTA observations and save old values in save_edisp vector
    int               n_observations = 0;
    std::vector<bool> save_edisp;
    save_edisp.assign(m_obs.size(), false);
    for (int i = 0; i < m_obs.size(); ++i) {
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
        if (obs != NULL) {
            save_edisp[i] = obs->response()->apply_edisp();
            obs->response()->apply_edisp(m_apply_edisp);
            n_observations++;
        }
    }

    // If more than a single observation has been handled then make sure that
    // an XML file will be used for storage
    if (n_observations > 1) {
        m_use_xml = true;
    }

    // Write execution mode into logger
    if (logTerse()) {
        log << std::endl;
        log.header1("Execution mode");
        log << gammalib::parformat("Event list management");
        if (m_save_and_dispose) {
            log << "Save and dispose (reduces memory needs)" << std::endl;
        }
        else {
            log << "Keep events in memory" << std::endl;
        }
        log << gammalib::parformat("Output format");
        if (m_use_xml) {
            log << "Write Observation Definition XML file" << std::endl;
        }
        else {
            log << "Write single event list FITS file" << std::endl;
        }
    }

    // Write seed values into logger
    if (logTerse()) {
        log << std::endl;
        log.header1("Seed values");
        for (int i = 0; i < m_rans.size(); ++i) {
            log << gammalib::parformat("Seed "+gammalib::str(i));
            log << gammalib::str(m_rans[i].seed()) << std::endl;
        }
    }

    // Write observation(s) into logger
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Observations");
        }
        else {
            log.header1("Observation");
        }
        log << m_obs << std::endl;
    }

    // Write header
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Simulate observations");
        }
        else {
            log.header1("Simulate observation");
        }
    }

    // From here on the code can be parallelized if OpenMP support
    // is enabled. The code in the following block corresponds to the
    // code that will be executed in each thread
    #pragma omp parallel
    {
        // Each thread will have it's own logger to avoid conflicts
        GLog wrklog;
        if (logDebug()) {
            wrklog.cout(true);
        }

        // Allocate and initialize copies for multi-threading
        GModels models(m_obs.models());

        // Copy configuration from application logger to thread logger
        wrklog.date(log.date());
        wrklog.name(log.name());

        // Set a big value to avoid flushing
        wrklog.max_size(10000000);

        // Loop over all observation in the container. If OpenMP support
        // is enabled, this loop will be parallelized.
        #pragma omp for
        for (int i = 0; i < m_obs.size(); ++i) {

            // Get pointer on CTA observation
            GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

            // Continue only if observation is a CTA observation
            if (obs != NULL) {

                // Write header for observation
                if (logTerse()) {
                    if (obs->name().length() > 1) {
                        wrklog.header3("Observation "+obs->name());
                    }
                    else {
                        wrklog.header3("Observation");
                    }
                }

                // Work on a clone of the CTA observation. This makes sure that
                // any memory allocated for computing (for example a response
                // cache) is properly de-allocated on exit of this run
                GCTAObservation obs_clone = *obs;

                // Save number of events before entering simulation
                int events_before = obs_clone.events()->size();

                // Simulate source events
                simulate_source(&obs_clone, models, m_rans[i], &wrklog);

                // Simulate source events
                simulate_background(&obs_clone, models, m_rans[i], &wrklog);

                // Dump simulation results
                if (logNormal()) {
                    wrklog << gammalib::parformat("MC events");
                    wrklog << obs_clone.events()->size() - events_before;
                    wrklog << " (all models)";
                    wrklog << std::endl;
                }

                // Append the event list to the original observation
                obs->events(*(obs_clone.events()));

                // If requested, event lists are saved immediately
                if (m_save_and_dispose) {

                    // Set event output file name. If multiple observations are
                    // handled, build the filename from prefix and observation
                    // index. Otherwise use the outfile parameter.
                    std::string outfile;
                    if (m_use_xml) {
                        m_prefix = (*this)["prefix"].string();
                        outfile  = m_prefix + gammalib::str(i) + ".fits";
                    }
                    else {
                        outfile  = (*this)["outevents"].filename();
                    }

                    // Store output file name in original observation
                    obs->eventfile(outfile);

                    // Save observation into FITS file. This is a critical zone
                    // to avoid multiple threads writing simultaneously
                    #pragma omp critical
                    {
                        obs_clone.save(outfile, clobber());
                    }

                    // Dispose events
                    obs->dispose_events();

                }

                // ... otherwise append the event list to the original observation
                /*
                else {
                    obs->events(*(obs_clone.events()));
                }
                */

            } // endif: CTA observation found

        } // endfor: looped over observations

        // At the end, the content of the thread logger is added to
        // the application logger
        #pragma omp critical (log)
        {
            log << wrklog;
        }

    } // end pragma omp parallel

    // Restore energy dispersion flag for all CTA observations
    for (int i = 0; i < m_obs.size(); ++i) {
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
        if (obs != NULL) {
            obs->response()->apply_edisp(save_edisp[i]);
        }
    }

    // Return
    return;
}