avtContract_p avtLagrangianFilter::ModifyContract(avtContract_p in_contract) { avtContract_p rv; const char *pipelineVariable = in_contract->GetDataRequest()->GetVariable(); if (strncmp(pipelineVariable, "operators/Lagrangian", strlen("operators/Lagrangian")) == 0) { outVarName = pipelineVariable; const char *justTheVar = pipelineVariable + strlen("operators/Lagrangian"); avtDataRequest_p dr = new avtDataRequest(in_contract->GetDataRequest(), justTheVar); rv = new avtContract(in_contract, dr); } else { rv = new avtContract(in_contract); } if (atts.GetYAxisSample() == LagrangianAttributes::Variable) { avtDataRequest_p in_dr = rv->GetDataRequest(); avtDataRequest_p out_dr = new avtDataRequest(in_dr); out_dr->AddSecondaryVariable(atts.GetVariable().c_str()); avtContract_p out_contract; out_contract = new avtContract(rv, out_dr); return avtPICSFilter::ModifyContract(out_contract); } else return avtPICSFilter::ModifyContract(rv); }
void avtOriginatingSource::InitPipeline(avtContract_p spec) { if (!ArtificialPipeline()) { if (!CanDoStreaming()) { spec->NoStreaming(); } // // Determine if the data specification is *all* of the data. This is // important to things like facelists. // avtDataRequest_p data = spec->GetDataRequest(); bool uad = data->GetSIL().UsesAllData(); GetOutput()->GetInfo().GetValidity().SetUsingAllData(uad); bool uadom = data->GetSIL().UsesAllDomains(); GetOutput()->GetInfo().GetValidity().SetUsingAllDomains(uadom); if (initializeProgressCallback != NULL && streamingCheckFunction != NULL) { // // Each filter is a stage, plus a stage to get the data. // With streaming, there are only calculate/send stages. // int nstages; if (streamingCheckFunction(streamingCheckFunctionArgs,spec)) { nstages = 1; GetOutput()->GetInfo().GetValidity().SetWhetherStreaming(true); } else { int sourceStages = NumStagesForFetch(data); nstages = spec->GetNFilters() + sourceStages; GetOutput()->GetInfo().GetValidity().SetWhetherStreaming(false); if (numberOfExecutions > 1) nstages *= numberOfExecutions; } bool shouldIssue = false; if (numberOfExecutions <= 1) shouldIssue = true; else if (numberOfExecutions > 1) { if (!haveIssuedProgress) { shouldIssue = true; haveIssuedProgress = true; } } if (shouldIssue) initializeProgressCallback(initializeProgressCallbackArgs, nstages); } } }
avtContract_p avtChannelCommFilter::ModifyContract(avtContract_p c) { const char *meshname = c->GetDataRequest()->GetVariable()+strlen("operators/ChannelComm/"); //avtDataRequest_p dr = new avtDataRequest(c->GetDataRequest(), meshname); ////dr->AddSecondaryVariable(atts.GetVelocity().c_str()); avtDataRequest_p dr = new avtDataRequest(c->GetDataRequest(), atts.GetVelocity().c_str()); return new avtContract(c, dr); }
avtContract_p avtStructuredChunkDataTreeIterator::ModifyContract(avtContract_p spec) { downstreamRectilinearMeshOptimizations = spec->GetHaveRectilinearMeshOptimizations(); downstreamCurvilinearMeshOptimizations = spec->GetHaveCurvilinearMeshOptimizations(); downstreamGhostType = spec->GetDataRequest()->GetDesiredGhostDataType(); return spec; }
avtContract_p avtDeformSphereGlyphFilter::ModifyContract(avtContract_p contract) { // // Get the old contract. // avtDataRequest_p ds = contract->GetDataRequest(); const char *primaryVariable = ds->GetVariable(); // // Make a new one // avtDataRequest_p ndr = new avtDataRequest(ds); // If we're using the default variable, save its name if (atts.GetVar() == "Default") { var = primaryVariable; } else { var = atts.GetVar(); ndr->AddSecondaryVariable(strdup(atts.GetVar().c_str())); } // // Create the new pipeline contract from the data request, and return // avtContract_p rv = new avtContract(contract, ndr); return rv; }
avtContract_p avtContextFilter::ModifyContract(avtContract_p spec) { avtDataRequest_p ds = spec->GetDataRequest(); ds->AddSecondaryVariable(atts.GetContext().c_str()); return spec; }
void avtConnectedComponentsFilter::InferVariableNameFromContract(avtContract_p c) { avtDataRequest_p in_dr = c->GetDataRequest(); bool foundIt = false; if (strncmp(in_dr->GetVariable(), "operators/ConnectedComponents/", strlen("operators/ConnectedComponents/")) == 0) { foundIt = true; varname = in_dr->GetVariable()+strlen("operators/ConnectedComponents/"); } if (!foundIt) { std::vector<CharStrRef> vars2nd = in_dr->GetSecondaryVariablesWithoutDuplicates(); for (size_t i = 0 ; i < vars2nd.size() ; i++) if (strncmp(*(vars2nd[i]), "operators/ConnectedComponents/", strlen("operators/ConnectedComponents/")) == 0) { foundIt = true; varname = *(vars2nd[i])+strlen("operators/ConnectedComponents/"); } } if (!foundIt) { EXCEPTION1(VisItException, "Unable to determine variable name from contract"); } }
avtContract_p avtMatvfExpression::ModifyContract(avtContract_p spec) { // request post ghost material info, as long as we are not doing mir if( !spec->GetDataRequest()->MustDoMaterialInterfaceReconstruction() ) { spec->GetDataRequest()->SetNeedPostGhostMaterialInfo(true); doPostGhost = true; } else { doPostGhost = false; } return spec; }
LoadBalanceScheme LoadBalancer::DetermineAppropriateScheme(avtContract_p input) { // // See if we have already have decided. If so, just return our cached // decision. // int index = input->GetPipelineIndex(); const LBInfo &lbinfo = pipelineInfo[index]; std::string dbname = lbinfo.db; avtDatabase *db = dbMap[dbname]; avtDataRequest_p data = input->GetDataRequest(); avtDatabaseMetaData *md = db->GetMetaData(db->GetMostRecentTimestep()); string meshName; TRY { meshName = md->MeshForVar(data->GetVariable()); } CATCHALL { // Probably a CMFE. return scheme; } ENDTRY; if (md->GetFormatCanDoDomainDecomposition()) return LOAD_BALANCE_DBPLUGIN_DYNAMIC; const avtMeshMetaData *mmd = md->GetMesh(meshName); if (mmd && mmd->loadBalanceScheme != LOAD_BALANCE_UNKNOWN) { debug1 << "Default load balance scheme \"" << LoadBalanceSchemeToString(scheme).c_str() << "\"" << " being overridden in favor of \"" << LoadBalanceSchemeToString(mmd->loadBalanceScheme).c_str() << "\"" << " for mesh \"" << meshName.c_str() << "\"" << endl; return mmd->loadBalanceScheme; } return scheme; }
avtContract_p avtMeshFilter::ModifyContract(avtContract_p spec) { avtContract_p rv = new avtContract(spec); if (GetInput()->GetInfo().GetAttributes().GetTopologicalDimension() != 0) { rv->GetDataRequest()->TurnZoneNumbersOn(); } else { std::string pointVar = atts.GetPointSizeVar(); avtDataRequest_p dataRequest = spec->GetDataRequest(); // // Find out if we REALLY need to add the secondary variable. // if (atts.GetPointSizeVarEnabled() && pointVar != "default" && pointVar != "\0" && pointVar != dataRequest->GetVariable() && !dataRequest->HasSecondaryVariable(pointVar.c_str())) { rv->GetDataRequest()->AddSecondaryVariable(pointVar.c_str()); rv->SetCalculateVariableExtents(pointVar, true); } avtDataAttributes &data = GetInput()->GetInfo().GetAttributes(); if (spec->GetDataRequest()->MayRequireZones() || spec->GetDataRequest()->MayRequireNodes()) { keepNodeZone = true; rv->GetDataRequest()->TurnNodeNumbersOn(); } else { keepNodeZone = false; } } return rv; }
avtContract_p avtNMatsExpression::ModifyContract(avtContract_p spec) { avtContract_p rv = avtSingleInputExpressionFilter::ModifyContract(spec); avtDataRequest_p ds = spec->GetDataRequest(); ds->TurnZoneNumbersOn(); return rv; }
avtContract_p avtStreamlinePlot::EnhanceSpecification(avtContract_p in_contract) { avtDataRequest_p in_dr = in_contract->GetDataRequest(); const char *var = in_dr->GetVariable(); avtDataRequest_p out_dr = new avtDataRequest(in_dr, "colorVar"); out_dr->AddSecondaryVariable(var); out_dr->SetOriginalVariable(var); avtContract_p out_contract = new avtContract(in_contract, out_dr); return out_contract; }
std::string LoadBalancer::GetMeshName(avtContract_p input, int stateIndex) { const LBInfo &lbinfo = pipelineInfo[input->GetPipelineIndex()]; avtDatabase *db = dbMap[lbinfo.db]; avtDataRequest_p data = input->GetDataRequest(); avtDatabaseMetaData *md = db->GetMetaData(stateIndex); string meshName; TRY { meshName = md->MeshForVar(data->GetVariable()); } CATCHALL { } ENDTRY return meshName; }
avtContract_p avtIsovolumeFilter::ModifyContract(avtContract_p in_spec) { avtContract_p spec = new avtContract(in_spec); const char *varname = NULL; if (atts.GetVariable() != "default") varname = atts.GetVariable().c_str(); else varname = in_spec->GetDataRequest()->GetVariable(); // // We will need the ghost zones so that we can interpolate along domain // boundaries and get no cracks in our isosurface. // avtDataAttributes &in_atts = GetInput()->GetInfo().GetAttributes(); bool skipGhost = false; if (in_atts.ValidVariable(varname) && in_atts.GetCentering(varname) == AVT_NODECENT) skipGhost = true; if (!skipGhost) spec->GetDataRequest()->SetDesiredGhostDataType(GHOST_ZONE_DATA); std::string iso_var(atts.GetVariable()); if (iso_var == "default") iso_var = in_spec->GetDataRequest()->GetVariable(); avtIntervalTree *it = GetMetaData()->GetDataExtents(iso_var.c_str()); if (it != NULL) { double min = atts.GetLbound(); double max = atts.GetUbound(); std::vector<int> dl; it->GetElementsListFromRange(&min, &max, dl); spec->GetDataRequest()->GetRestriction()->RestrictDomains(dl); } return spec; }
avtContract_p avtResampleFilter::ModifyContract(avtContract_p oldataRequest) { // // Best copy constructor we have?? // avtContract_p spec = new avtContract(oldataRequest, oldataRequest->GetDataRequest()); // // First tell the file format reader that we are going to be doing a // resample selection. // avtResampleSelection *sel = new avtResampleSelection; int counts[3]; counts[0] = atts.GetWidth(); counts[1] = atts.GetHeight(); counts[2] = atts.GetDepth(); sel->SetCounts(counts); double starts[3]; starts[0] = atts.GetMinX(); starts[1] = atts.GetMinY(); starts[2] = atts.GetMinZ(); sel->SetStarts(starts); double stops[3]; stops[0] = atts.GetMaxX(); stops[1] = atts.GetMaxY(); stops[2] = atts.GetMaxZ(); sel->SetStops(stops); selID = spec->GetDataRequest()->AddDataSelection(sel); spec->NoStreaming(); spec->SetHaveRectilinearMeshOptimizations(true); spec->GetDataRequest()->SetDesiredGhostDataType(NO_GHOST_DATA); if (atts.GetUseArbitrator()) { if (atts.GetArbitratorVarName() != "default") spec->GetDataRequest()-> AddSecondaryVariable(atts.GetArbitratorVarName().c_str()); } if (primaryVariable != NULL) { delete [] primaryVariable; } const char *pv = spec->GetDataRequest()->GetVariable(); primaryVariable = new char[strlen(pv)+1]; strcpy(primaryVariable, pv); return spec; }
avtContract_p avtExtremeValueAnalysisFilter::ModifyContract(avtContract_p in_contract) { avtContract_p rv; if (strncmp(pipelineVariable, "operators/ExtremeValueAnalysis", strlen("operators/ExtremeValueAnalysis")) == 0) { outVarName = pipelineVariable; const char *justTheVar = pipelineVariable + strlen("operators/ExtremeValueAnalysis/"); avtDataRequest_p dr = new avtDataRequest(in_contract->GetDataRequest(), justTheVar); rv = new avtContract(in_contract, dr); } else { rv = new avtContract(in_contract); } return rv; }
avtContract_p avtPeaksOverThresholdFilter::ModifyContract(avtContract_p in_contract) { avtContract_p rv; if (strncmp(pipelineVariable, "operators/PeaksOverThreshold", strlen("operators/PeaksOverThreshold")) == 0) { outVarName = pipelineVariable; const char *justTheVar = pipelineVariable + strlen("operators/PeaksOverThreshold/"); avtDataRequest_p dr = new avtDataRequest(in_contract->GetDataRequest(), justTheVar); rv = new avtContract(in_contract, dr); } else { rv = new avtContract(in_contract); } return rv; }
avtContract_p avtModelBasedClusteringFilter::ModifyContract(avtContract_p in_contract) { avtContract_p rv; if (strncmp(pipelineVariable, "operators/ModelBasedClustering", strlen("operators/ModelBasedClustering")) == 0) { outVarName = pipelineVariable; const char *justTheVar = pipelineVariable + strlen("operators/ModelBasedClustering/"); avtDataRequest_p dr = new avtDataRequest(in_contract->GetDataRequest(), justTheVar); rv = new avtContract(in_contract, dr); } else { rv = new avtContract(in_contract); } return rv; }
avtContract_p avtLineoutFilter::ModifyContract(avtContract_p in_contract) { avtContract_p rv; const char *opLineout = "operators/Lineout/"; if (strncmp(pipelineVariable, opLineout, strlen(opLineout)) == 0) { const char *var = pipelineVariable + strlen(opLineout); avtDataRequest_p dr = new avtDataRequest(in_contract->GetDataRequest(), var); rv = new avtContract(in_contract, dr); } else { rv = new avtContract(in_contract); } useOriginalCells = false; if (!GetInput()->GetInfo().GetValidity().GetZonesPreserved()) { rv->GetDataRequest()->TurnZoneNumbersOn(); useOriginalCells = true; return rv; } // // Get the interval tree. // avtIntervalTree *it = GetMetaData()->GetSpatialExtents(); if (it == NULL) { return rv; } double rayDir[3] = {point2[0]-point1[0], point2[1]-point1[1], point2[2]-point1[2]}; intVector domains; it->GetElementsList(point1, rayDir, domains); rv->GetDataRequest()->GetRestriction()->RestrictDomains(domains); return rv; }
void avtFluxFilter::InferVariableNameFromContract(avtContract_p c) { avtDataRequest_p in_dr = c->GetDataRequest(); bool foundIt = false; if (strncmp(in_dr->GetVariable(), "operators/Flux/", strlen("operators/Flux/")) == 0) { foundIt = true; if (atts.GetFlowField() == "default") { EXCEPTION1(VisItException, "You can't set the flow field as \"default\" " "since the default field is not a vector."); } if (atts.GetWeight() && atts.GetWeightField() == "default") { EXCEPTION1(VisItException, "You can't set the weighting field as \"default\" " "since that would lead to a recursive definition."); } varname = in_dr->GetVariable()+strlen("operators/Flux/"); } if (!foundIt) { std::vector<CharStrRef> vars2nd = in_dr->GetSecondaryVariablesWithoutDuplicates(); for (size_t i = 0 ; i < vars2nd.size() ; i++) if (strncmp(*(vars2nd[i]), "operators/Flux/", strlen("operators/Flux/")) == 0) { foundIt = true; varname = *(vars2nd[i])+strlen("operators/Flux/"); } } if (!foundIt) { EXCEPTION1(VisItException, "Unable to determine variable name from contract"); } }
avtContract_p avtApplyDataBinningExpression::ModifyContract(avtContract_p spec) { if (theDataBinning == NULL) { // We should have failed before getting to this point... EXCEPTION2(ExpressionException, outputVariableName, "Could not locate the data binning."); } avtDataRequest_p ds = spec->GetDataRequest(); avtDataRequest_p new_ds = new avtDataRequest(ds); avtDataBinningFunctionInfo *info = theDataBinning->GetFunctionInfo(); int nVars = info->GetDomainNumberOfTuples(); for (int i = 0 ; i < nVars ; i++) new_ds->AddSecondaryVariable(info->GetDomainTupleName(i).c_str()); new_ds->AddSecondaryVariable(info->GetCodomainName().c_str()); avtContract_p rv = new avtContract(spec, new_ds); rv = avtSingleInputExpressionFilter::ModifyContract(rv); return rv; }
avtContract_p avtLabelPlot::EnhanceSpecification(avtContract_p spec) { debug3 << "avtLabelPlot::EnhanceSpecification: 0" << endl; avtDataRequest_p ds = spec->GetDataRequest(); // // The pipeline specification should really be const -- it is used // elsewhere, so we can't modify it and return it. Make a copy and in // the new copy, indicate that we need structured indices. // avtDataRequest_p nds = new avtDataRequest(ds); nds->TurnZoneNumbersOn(); nds->TurnNodeNumbersOn(); nds->SetNeedStructuredIndices(true); nds->SetTransformVectorsDuringProject(false); avtContract_p rv = new avtContract(spec, nds); debug3 << "avtLabelPlot::EnhanceSpecification: 1" << endl; return rv; }
avtContract_p avtSurfaceFilter::ModifyContract(avtContract_p spec) { double dataExtents[2]; double spatialExtents[6]; if (TryDataExtents(dataExtents)) { avtDataset_p input = GetTypedInput(); avtDatasetExaminer::GetSpatialExtents(input, spatialExtents); UnifyMinMax(spatialExtents,6); CalculateScaleValues(dataExtents, spatialExtents); stillNeedExtents = false; } else { spec->NoStreaming(); } if (spec->GetDataRequest()->MayRequireZones()) { spec->GetDataRequest()->TurnZoneNumbersOn(); } if (spec->GetDataRequest()->MayRequireNodes()) { spec->GetDataRequest()->TurnNodeNumbersOn(); } // // We will need the ghost zones so that we can interpolate along domain // boundaries and get no cracks in our isosurface. // const char *varname = spec->GetDataRequest()->GetVariable(); avtDataAttributes &in_atts = GetInput()->GetInfo().GetAttributes(); bool skipGhost = false; if (in_atts.ValidVariable(varname) && in_atts.GetCentering(varname) == AVT_NODECENT) skipGhost = true; if (!skipGhost) spec->GetDataRequest()->SetDesiredGhostDataType(GHOST_ZONE_DATA); return spec; }
avtContract_p avtMissingDataFilter::ModifyContract(avtContract_p c0) { canDoCollectiveCommunication = ! c0->DoingOnDemandStreaming(); // Store the contract. contract = new avtContract(c0); if (generateMode) { // Determine the list of variables that are missing data. stringVector varsMissingData(MissingDataVariables(contract->GetDataRequest(), &metadata)); if(!varsMissingData.empty()) { // Turn on both Nodes and Zones, to prevent another re-execution if // user switches between zone and node pick. contract->GetDataRequest()->TurnZoneNumbersOn(); contract->GetDataRequest()->TurnNodeNumbersOn(); } } // Return a copy of the modified contract. return new avtContract(contract); }
void avtDatasetToDatasetFilter::ExamineContract(avtContract_p s) { avtDataRequest_p ds = s->GetDataRequest(); // // We need to know what the pipeline variable is so we can switch it // back when we are done. It's also a nice thing to keep track of. // if (pipelineVariable != NULL) delete[]pipelineVariable; const char *var = ds->GetVariable(); pipelineVariable = new char[strlen(var) + 1]; strcpy(pipelineVariable, var); if (switchVariables) { // // Determine if the pipeline already knows if it needs the // active variable. // bool haveVariable = false; if (strcmp(activeVariable, pipelineVariable) == 0) { haveVariable = true; } const std::vector<CharStrRef> &var2nd = ds->GetSecondaryVariables(); for (int i = 0; i < var2nd.size(); i++) { const char *v2 = *(var2nd[i]); if (strcmp(v2, activeVariable) == 0) { haveVariable = true; } } // // Tell the pipeline about our active variable (if necessary) and // decide if we should remove the active variable when we are done. // if (!haveVariable) { ds->AddSecondaryVariable(activeVariable); removeActiveVariableWhenDone = true; debug5 << GetType() << ": ExamineContract: Setting primary " << "variable " << activeVariable << " to be removed at PostExecute." << endl; } else { removeActiveVariableWhenDone = false; debug5 << GetType() << ": ExamineContract: Leaving primary " << "variable " << activeVariable << " where it is at PostExecute." << endl; } } // Iterate through the secondary variables. // Determine if the pipline already knows about each of them. for (int i = 0; i < secondaryVarList.size(); i++) { bool haveVariable = false; if (strcmp(pipelineVariable, secondaryVarList[i]) == 0) { haveVariable = true; } const std::vector<CharStrRef> &var2nd = ds->GetSecondaryVariables(); for (int j = 0; j < var2nd.size(); j++) { const char *v2 = *(var2nd[j]); if (strcmp(v2, secondaryVarList[i]) == 0) haveVariable = true; } if (!haveVariable) { ds->AddSecondaryVariable(secondaryVarList[i]); removeSecondaryVariable[i] = true; debug5 << GetType() << ": ExamineContract: Setting secondary " << "variable " << secondaryVarList[i] << " to be removed at PostExecute." << endl; } else { removeSecondaryVariable[i] = false; debug5 << GetType() << ": ExamineContract: Leaving secondary " << "variable " << secondaryVarList[i] << " where it is at PostExecute." << endl; } } }
avtDataRequest_p LoadBalancer::Reduce(avtContract_p input) { avtDataRequest_p data = input->GetDataRequest(); // // It is difficult for the load balancer to communicate with the originating // source because it is done through callbacks. // So we do it by setting a Boolean in the contract. Since there is only // one path that involves actually doing data replication, and many that don't, // we will unset the Boolean now and reset it in the case we actually do // data replication. // #ifdef PARALLEL // only used in parallel bool dataReplicationRequested = input->ReplicateSingleDomainOnAllProcessors(); #endif input->SetReplicateSingleDomainOnAllProcessors(false); // // Pipeline index 0 is reserved for meta-data. It should already be // load balanced. // if (input->GetPipelineIndex() == 0) { return data; } // // Assess load balancing specially for serial engines. // if (nProcs <= 1) { bool doDynLB = CheckDynamicLoadBalancing(input); if (!doDynLB && scheme != LOAD_BALANCE_STREAM) { pipelineInfo[input->GetPipelineIndex()].complete = true; return data; } else { avtDataObjectSource::RegisterProgressCallback(NULL,NULL); avtSILRestriction_p orig_silr = data->GetRestriction(); avtSILRestriction_p silr = new avtSILRestriction(orig_silr); avtDataRequest_p new_data = new avtDataRequest(data, silr); avtSILRestrictionTraverser trav(silr); vector<int> list; trav.GetDomainList(list); if (pipelineInfo[input->GetPipelineIndex()].current < 0) pipelineInfo[input->GetPipelineIndex()].current = 0; int domain = list[pipelineInfo[input->GetPipelineIndex()].current]; int sggDomain = avtStreamingGhostGenerator::LBGetNextDomain(); if (sggDomain >= 0) domain = sggDomain; vector<int> domainList(1, domain); new_data->GetRestriction() ->RestrictDomainsForLoadBalance(domainList); UpdateProgress(pipelineInfo[input->GetPipelineIndex()].current, (int)list.size()); pipelineInfo[input->GetPipelineIndex()].current++; if (pipelineInfo[input->GetPipelineIndex()].current == (int)list.size()) pipelineInfo[input->GetPipelineIndex()].complete = true; return new_data; } } #ifdef PARALLEL avtSILRestriction_p orig_silr = data->GetRestriction(); avtSILRestriction_p silr = new avtSILRestriction(orig_silr); avtDataRequest_p new_data = new avtDataRequest(data, silr); avtSILRestrictionTraverser trav(silr); // set up MPI message tags static int lastDomDoneMsg = GetUniqueMessageTag(); static int newDomToDoMsg = GetUniqueMessageTag(); // Make sure that we have domain to file mapping available. LBInfo &lbInfo(pipelineInfo[input->GetPipelineIndex()]); std::string meshName = GetMeshName(input, dbState[lbInfo.db]); GetIOInformation(lbInfo.db, dbState[lbInfo.db], meshName); if (scheme == LOAD_BALANCE_STREAM) { if (pipelineInfo[input->GetPipelineIndex()].current < 0) { pipelineInfo[input->GetPipelineIndex()].current = 0; // // We probably want to do something more sophisticated in the future // (like walking through a SIL). For now, just use the "chunks" // mechanism set up with convenience methods. // vector<int> list; trav.GetDomainList(list); int amountPer = list.size() / nProcs; int oneExtraUntil = list.size() % nProcs; int lastDomain = 0; for (int i = 0 ; i < nProcs ; i++) { if (i == rank) { int amount = amountPer + (i < oneExtraUntil ? 1 : 0); for (int j = 0 ; j < amount ; j++) { domainListForStreaming.push_back(list[j+lastDomain]); } } lastDomain += amountPer + (i < oneExtraUntil ? 1 : 0); } } int domain = domainListForStreaming[pipelineInfo[input->GetPipelineIndex()].current]; int sggDomain = avtStreamingGhostGenerator::LBGetNextDomain(); if (sggDomain >= 0) domain = sggDomain; vector<int> domainList(1, domain); new_data->GetRestriction() ->RestrictDomainsForLoadBalance(domainList); UpdateProgress(pipelineInfo[input->GetPipelineIndex()].current, domainListForStreaming.size()); pipelineInfo[input->GetPipelineIndex()].current++; if (pipelineInfo[input->GetPipelineIndex()].current == (int)domainListForStreaming.size()) { pipelineInfo[input->GetPipelineIndex()].complete = true; domainListForStreaming.clear(); } } // Can we do dynamic load balancing? else if (! CheckDynamicLoadBalancing(input)) { // // We probably want to do something more sophisticated in the future // (like walking through a SIL). For now, just use the "chunks" // mechanism set up with convenience methods. // vector<int> list; vector<int> mylist; trav.GetDomainList(list); if (dataReplicationRequested && list.size() == 1) { silr->RestrictDomainsForLoadBalance(list); pipelineInfo[input->GetPipelineIndex()].complete = true; // Communicate back to the pipeline that we are replicating. input->SetReplicateSingleDomainOnAllProcessors(true); return data; } // // For variables (including meshes) that require specific types of // load balancing, we override the scheme here // LoadBalanceScheme theScheme = DetermineAppropriateScheme(input); if (theScheme == LOAD_BALANCE_CONTIGUOUS_BLOCKS_TOGETHER) { int amountPer = list.size() / nProcs; int oneExtraUntil = list.size() % nProcs; int lastDomain = 0; for (int i = 0 ; i < nProcs ; i++) { if (i == rank) { int amount = amountPer + (i < oneExtraUntil ? 1 : 0); for (int j = 0 ; j < amount ; j++) { mylist.push_back(list[j+lastDomain]); } } lastDomain += amountPer + (i < oneExtraUntil ? 1 : 0); } } else if (theScheme == LOAD_BALANCE_STRIDE_ACROSS_BLOCKS) { for (size_t j = 0 ; j < list.size() ; j++) { if (j % nProcs == (size_t)rank) mylist.push_back(list[j]); } } else if (theScheme == LOAD_BALANCE_ABSOLUTE) { for (size_t j = 0 ; j < list.size() ; j++) { if (list[j] % nProcs == rank) mylist.push_back(list[j]); } } else if (theScheme == LOAD_BALANCE_RESTRICTED) { LBInfo &lbInfo(pipelineInfo[input->GetPipelineIndex()]); IOInfo &ioInfo(ioMap[lbInfo.db]); const HintList &hints(ioInfo.ioInfo.GetHints()); for (size_t j = 0 ; j < list.size() ; j++) { if (hints.size() >= (size_t)rank) { const vector<int> &doms = hints[rank]; int ndoms = doms.size(); for (int h=0; h<ndoms; h++) { if (doms[h] == list[j]) { mylist.push_back(list[j]); break; } } } } } else if (theScheme == LOAD_BALANCE_RANDOM_ASSIGNMENT) { // all procs randomly jumble the list of domain ids // all procs compute same jumbled list due to same seed // [ which won't be true on a heterogeneous platform ] size_t j; vector<int> jumbledList = list; srand(0xDeadBeef); for (j = 0 ; j < list.size() * 5; j++) { int i1 = rand() % list.size(); int i2 = rand() % list.size(); int tmp = jumbledList[i1]; jumbledList[i1] = jumbledList[i2]; jumbledList[i2] = tmp; } // now, do round-robin assignment from the jumbled list for (j = 0 ; j < list.size() ; j++) { if (j % nProcs == (size_t)rank) mylist.push_back(jumbledList[j]); } } else if (theScheme == LOAD_BALANCE_DBPLUGIN_DYNAMIC) { // Every processor gets the complete list mylist = list; } silr->RestrictDomainsForLoadBalance(mylist); pipelineInfo[input->GetPipelineIndex()].complete = true; } else { // disable progress updates from the filters this time around avtDataObjectSource::RegisterProgressCallback(NULL,NULL); LBInfo &lbInfo(pipelineInfo[input->GetPipelineIndex()]); IOInfo &ioInfo(ioMap[lbInfo.db]); if (rank == 0) { // ------------------------------------- // MASTER LOADBALANCER PROCESSES // ------------------------------------- // Allocate enough space to hold the completed domains ioInfo.domains.resize(nProcs); ioInfo.files.resize(nProcs); bool validFileMap = (ioInfo.fileMap.size() != 0); // Get the list of domains to process vector<int> domainList; trav.GetDomainList(domainList); // Make a work list and a completed list size_t totaldomains = domainList.size(); deque<int> incomplete(domainList.begin(), domainList.end()); vector<int> complete; debug5 << "LoadBalancer Master -- starting with " << incomplete.size() << " domains\n"; // pull from the incomplete list and push onto the complete list // until all domains are complete bool abort = false; int domain; UpdateProgress(0,0); while (complete.size() < totaldomains) { // check for an abort if (!abort && CheckAbort(false)) { abort = true; totaldomains -= incomplete.size(); incomplete.clear(); } // update the progress UpdateProgress(complete.size() + (domainList.size() - incomplete.size()), domainList.size()*2); // get the completed domain number MPI_Status stat; MPI_Recv(&domain, 1, MPI_INT, MPI_ANY_SOURCE, lastDomDoneMsg, VISIT_MPI_COMM, &stat); int processor = stat.MPI_SOURCE; // -1 means the first pass by the slave; nothing completed yet if (domain != -1) { // add it to the complete list complete.push_back(domain); } // figure out what to tell this processor to do if (incomplete.empty()) continue; // find a cached domain for next processor deque<int>::iterator i; for (i = incomplete.begin(); i != incomplete.end(); i++) { if (ioInfo.domains[processor].find(*i) != ioInfo.domains[processor].end()) break; } // if no match, try to find one that is in a file // already opened by this processor if (i == incomplete.end()) { for (i = incomplete.begin(); i != incomplete.end(); i++) { int fileno = 0; if (validFileMap) fileno = ioInfo.fileMap[*i]; if (ioInfo.files[processor].count(fileno) > 0) break; } } // if still no match, find one that is in a file // opened by the fewest number of processors if (i == incomplete.end()) { int mindomain = -1; int minopen = 999999999; for (i = incomplete.begin(); i != incomplete.end(); i++) { int fileno = 0; if (validFileMap) fileno = ioInfo.fileMap[*i]; // count the number of processors which have // this file opened int nopen = 0; for (size_t j=0; j<ioInfo.files.size(); j++) if (ioInfo.files[j].count(fileno) > 0) nopen++; if (nopen < minopen) { mindomain = *i; minopen = nopen; } } for (i = incomplete.begin(); i != incomplete.end(); i++) { if (*i == mindomain) break; } } // if no match, just take the next one in line if (i == incomplete.end()) i=incomplete.begin(); domain = *i; incomplete.erase(i); ioInfo.domains[processor].insert(domain); if (validFileMap) ioInfo.files[processor].insert(ioInfo.fileMap[domain]); else ioInfo.files[processor].insert(0); // send the new domain number to that processor debug5 << "LoadBalancer Master: sending domain " << domain << " to processor "<<processor<<"\n"; MPI_Send(&domain, 1, MPI_INT, processor, newDomToDoMsg, VISIT_MPI_COMM); } // we're all done -- -2 means to abort, -1 means to send results int status = abort ? -2 : -1; for (int i=1; i<nProcs; i++) MPI_Send(&status, 1, MPI_INT, i, newDomToDoMsg,VISIT_MPI_COMM); if (abort) EXCEPTION0(AbortException); // all work is done UpdateProgress(1,0); lbInfo.complete = true; new_data->GetRestriction()->TurnOffAll(); MPI_Barrier(VISIT_MPI_COMM); } else { // ------------------------------------- // SLAVE PROCESSES // ------------------------------------- // send our last completed domain to the master int domain = lbInfo.current; MPI_Send(&domain, 1, MPI_INT, 0, lastDomDoneMsg, VISIT_MPI_COMM); // get our new work unit MPI_Status stat; MPI_Recv(&domain, 1, MPI_INT, 0, newDomToDoMsg, VISIT_MPI_COMM, &stat); lbInfo.current = domain; if (domain == -2) { EXCEPTION0(AbortException); } else if (domain == -1) { // -1 is a tag for "no work" -- we are all done lbInfo.complete = true; new_data->GetRestriction()->TurnOffAll(); MPI_Barrier(VISIT_MPI_COMM); } else { vector<int> domainList(1, domain); new_data->GetRestriction() ->RestrictDomainsForLoadBalance(domainList); } } } // By intersecting with the original restriction, we will ensure that // we are catching restrictions beyond domains, like materials, etc. // See comments in SIL restriction code regarding 'FastIntersect'. new_data->GetRestriction()->FastIntersect(orig_silr); return new_data; #else EXCEPTION1(VisItException, "nprocs was > 1 in a non-parallel code"); #endif }
bool LoadBalancer::CheckDynamicLoadBalancing(avtContract_p input) { // // See if we have already have decided. If so, just return our cached // decision. // int index = input->GetPipelineIndex(); LBInfo &lbinfo = pipelineInfo[index]; if (lbinfo.haveInitializedDLB) return lbinfo.doDLB; // // If the user has not explicitly asked for DLB, then don't do it. // if (!allowDynamic) { // Almost always false. lbinfo.doDLB = false || (scheme == LOAD_BALANCE_STREAM); lbinfo.haveInitializedDLB = true; return lbinfo.doDLB; } // // Some hard and fast rules: // // Pipeline index 0 is reserved for meta-data and inlined pipelines. So // no DLB for those. // // Cannot dynamic load balance some pipelines because of the filters // in the pipeline. // // We cannot do dynamic load balancing if the database does not believe // we can do dynamic load balancing (for example because we need ghost // data communicated or materials reconstructed). // avtDataRequest_p data = input->GetDataRequest(); std::string dbname = lbinfo.db; avtDatabase *db = dbMap[dbname]; if (input->GetPipelineIndex() == 0 || input->ShouldUseStreaming() == false || db->CanDoStreaming(data) == false) { lbinfo.doDLB = false; lbinfo.haveInitializedDLB = true; return false; } // // Don't do DLB if we have 2 or 3 procs. It's not worth it. // if (nProcs == 2 || nProcs == 3) { lbinfo.doDLB = false; lbinfo.haveInitializedDLB = true; return false; } // // The user has asked for DLB. And nothing in the pipeline is prevent it. // Do it! // lbinfo.doDLB = true; lbinfo.haveInitializedDLB = true; return true; }
avtContract_p avtPseudocolorFilter::ModifyContract(avtContract_p contract) { avtContract_p rv = contract; avtDataAttributes &data = GetInput()->GetInfo().GetAttributes(); int topoDim = data.GetTopologicalDimension(); std::string pointVar = plotAtts.GetPointSizeVar(); std::string radiusVar = plotAtts.GetTubeRadiusVar(); std::string opacityVar = plotAtts.GetOpacityVariable(); avtDataRequest_p dataRequest = new avtDataRequest( contract->GetDataRequest()); primaryVar = dataRequest->GetVariable(); // ARS - FIX ME - Why AddSecondaryVariable here and not in // avtPseudocolorPlot::EnhanceSpecification // // Find out if we need to add a secondary variable. // if( (topoDim == 0 || (topoDim > 0 && plotAtts.GetRenderPoints())) && plotAtts.GetPointType() != PseudocolorAttributes::Point && plotAtts.GetPointType() != PseudocolorAttributes::Sphere && plotAtts.GetPointSizeVarEnabled() && pointVar != "default" && pointVar != "\0" && pointVar != primaryVar && !dataRequest->HasSecondaryVariable(pointVar.c_str())) { rv->GetDataRequest()->AddSecondaryVariable(pointVar.c_str()); rv->SetCalculateVariableExtents(pointVar, true); } if( (topoDim == 1 || (topoDim > 1 && plotAtts.GetRenderWireframe())) && plotAtts.GetLineType() == PseudocolorAttributes::Tube && plotAtts.GetTubeRadiusVarEnabled() && radiusVar != "default" && radiusVar != "\0" && radiusVar != primaryVar && !dataRequest->HasSecondaryVariable(radiusVar.c_str())) { rv->GetDataRequest()->AddSecondaryVariable(radiusVar.c_str()); rv->SetCalculateVariableExtents(radiusVar, true); } if (plotAtts.GetOpacityType() == PseudocolorAttributes::VariableRange && opacityVar != "default" && opacityVar != "\0" && opacityVar != primaryVar && !dataRequest->HasSecondaryVariable(opacityVar.c_str())) { rv->GetDataRequest()->AddSecondaryVariable(opacityVar.c_str()); rv->SetCalculateVariableExtents(opacityVar, true); } // Note the line type so that upstream operators can obtain the // needed data for displaying ribbons or tubes. std::string key = rv->SetAttribute( &plotAtts, PseudocolorAttributes::ID_lineType, PseudocolorAttributes::LineType_ToString(plotAtts.GetLineType()) ); if (contract->GetDataRequest()->MayRequireZones() || contract->GetDataRequest()->MayRequireNodes()) { keepNodeZone = true; if (data.ValidActiveVariable()) { if (data.GetCentering() == AVT_NODECENT) { rv->GetDataRequest()->TurnNodeNumbersOn(); } else if (data.GetCentering() == AVT_ZONECENT) { rv->GetDataRequest()->TurnZoneNumbersOn(); } } else { // canot determine variable centering, so turn on both // node numbers and zone numbers. rv->GetDataRequest()->TurnNodeNumbersOn(); rv->GetDataRequest()->TurnZoneNumbersOn(); } } else { keepNodeZone = false; } return rv; }
avtContract_p avtDataBinningFilter::ModifyContract(avtContract_p inContract) { bool defaultVarOK = true; if (strncmp(pipelineVariable, "operators/DataBinning", strlen("operators/DataBinning")) == 0) { defaultVarOK = false; varname = pipelineVariable; } const char *dim1Var = atts.GetDim1Var().c_str(); if (atts.GetDim1BinBasedOn() == DataBinningAttributes::Variable) { if (strcmp(dim1Var, "default") == 0) { if (defaultVarOK) dim1Var = pipelineVariable; else { EXCEPTION1(VisItException, "You specified the first dimension of the " "data binning as \"default\", but your plotting variable " "(which \"default\" resolves to) is of the output of the " "data binning. This is a recursion definition. Please " "change the first dimension of the data binning to be " "something besides \"default\"."); } } } const char *dim2Var = atts.GetDim2Var().c_str(); if (atts.GetDim2BinBasedOn() == DataBinningAttributes::Variable) { if (strcmp(dim2Var, "default") == 0 && (atts.GetNumDimensions() == DataBinningAttributes::Two || atts.GetNumDimensions() == DataBinningAttributes::Three)) { if (defaultVarOK) dim2Var = pipelineVariable; else { EXCEPTION1(VisItException, "You specified the second dimension of the " "data binning as \"default\", but your plotting variable " "(which \"default\" resolves to) is of the output of the " "data binning. This is a recursion definition. Please " "change the first dimension of the data binning to be " "something besides \"default\"."); } } } const char *dim3Var = atts.GetDim3Var().c_str(); if (atts.GetDim3BinBasedOn() == DataBinningAttributes::Variable) { if (strcmp(dim3Var, "default") == 0 && atts.GetNumDimensions() == DataBinningAttributes::Three) { if (defaultVarOK) dim3Var = pipelineVariable; else { EXCEPTION1(VisItException, "You specified the third dimension of the " "data binning as \"default\", but your plotting variable " "(which \"default\" resolves to) is of the output of the " "data binning. This is a recursion definition. Please " "change the first dimension of the data binning to be " "something besides \"default\"."); } } } avtDataRequest_p in_dr = inContract->GetDataRequest(); avtDataRequest_p out_dr; avtDataAttributes &inAtts = GetInput()->GetInfo().GetAttributes(); if (strncmp(in_dr->GetVariable(), "operators/DataBinning", strlen("operators/DataBinning")) == 0) out_dr = new avtDataRequest(in_dr, inAtts.GetMeshname().c_str()); else out_dr = new avtDataRequest(in_dr); std::vector<CharStrRef> vars2nd = in_dr->GetSecondaryVariablesWithoutDuplicates(); std::vector<std::string> removeMe; int i; for (i = 0 ; i < vars2nd.size() ; i++) if (strncmp(*(vars2nd[i]), "operators/DataBinning", strlen("operators/DataBinning")) == 0) { varname = *(vars2nd[i]); removeMe.push_back(*(vars2nd[i])); } for (i = 0 ; i < removeMe.size() ; i++) out_dr->RemoveSecondaryVariable(removeMe[i].c_str()); if (atts.GetDim1BinBasedOn() == DataBinningAttributes::Variable) out_dr->AddSecondaryVariable(dim1Var); if ((atts.GetNumDimensions() == DataBinningAttributes::Two || atts.GetNumDimensions() == DataBinningAttributes::Three) && (atts.GetDim2BinBasedOn() == DataBinningAttributes::Variable)) out_dr->AddSecondaryVariable(dim2Var); if ((atts.GetNumDimensions() == DataBinningAttributes::Three) && (atts.GetDim3BinBasedOn() == DataBinningAttributes::Variable)) out_dr->AddSecondaryVariable(dim3Var); if (atts.GetReductionOperator() != DataBinningAttributes::PDF && atts.GetReductionOperator() != DataBinningAttributes::Count) { if (atts.GetVarForReduction() == "default") { if (defaultVarOK) out_dr->AddSecondaryVariable(pipelineVariable); else { EXCEPTION1(VisItException, "You specified the variable for the reduction operator of your " "data binning as \"default\", but your plotting variable " "(which \"default\" resolves to) is of the output of the " "data binning. This is a recursion definition. Please " "change the first dimension of the data binning to be " "something besides \"default\"."); } } else out_dr->AddSecondaryVariable(atts.GetVarForReduction().c_str()); } // // Calculate the "original" extents. If we clip away part of the volume, we don't // want the extents bouncing all around because certain regions aren't contributing. // avtContract_p rv = new avtContract(inContract, out_dr); if (! atts.GetDim1SpecifyRange() && dim1Var != pipelineVariable && atts.GetDim1BinBasedOn() == DataBinningAttributes::Variable) rv->SetCalculateVariableExtents(dim1Var, true); if ((! atts.GetDim2SpecifyRange()) && (atts.GetNumDimensions() == DataBinningAttributes::Two || atts.GetNumDimensions() == DataBinningAttributes::Three) && (dim2Var != pipelineVariable) && (atts.GetDim2BinBasedOn() == DataBinningAttributes::Variable)) rv->SetCalculateVariableExtents(dim2Var, true); if ((! atts.GetDim3SpecifyRange()) && atts.GetNumDimensions() == DataBinningAttributes::Three && (dim2Var != pipelineVariable) && (atts.GetDim3BinBasedOn() == DataBinningAttributes::Variable)) rv->SetCalculateVariableExtents(dim3Var, true); int numSpatialDimensions = 0; if ((atts.GetDim1BinBasedOn() != DataBinningAttributes::Variable) && (! atts.GetDim1SpecifyRange())) numSpatialDimensions++; if ((atts.GetDim2BinBasedOn() != DataBinningAttributes::Variable) && (! atts.GetDim2SpecifyRange()) && (atts.GetNumDimensions() == DataBinningAttributes::Two || atts.GetNumDimensions() == DataBinningAttributes::Three)) numSpatialDimensions++; if ((atts.GetDim3BinBasedOn() != DataBinningAttributes::Variable) && (! atts.GetDim3SpecifyRange()) && (atts.GetNumDimensions() == DataBinningAttributes::Three)) numSpatialDimensions++; if (numSpatialDimensions > 0) rv->SetCalculateMeshExtents(true); lastContract = rv; return rv; }
avtContract_p avtVolumeFilter::ModifyContract(avtContract_p contract) { avtContract_p newcontract = NULL; if (primaryVariable != NULL) { delete [] primaryVariable; } avtDataRequest_p ds = new avtDataRequest(contract->GetDataRequest()); const char *var = ds->GetVariable(); bool setupExpr = false; char exprDef[128]; std::string exprName = (std::string)"_expr_" + (std::string)var; if (atts.GetScaling() == VolumeAttributes::Linear) { #ifdef HAVE_LIBSLIVR if ((atts.GetRendererType() == VolumeAttributes::RayCastingSLIVR) || ((atts.GetRendererType() == VolumeAttributes::RayCasting) && (atts.GetSampling() == VolumeAttributes::Trilinear))) ds->SetDesiredGhostDataType(GHOST_ZONE_DATA); #endif newcontract = new avtContract(contract, ds); primaryVariable = new char[strlen(var)+1]; strcpy(primaryVariable, var); } else if (atts.GetScaling() == VolumeAttributes::Log) { setupExpr = true; if (atts.GetUseColorVarMin()) { char m[16]; SNPRINTF(m, 16, "%f", atts.GetColorVarMin()); SNPRINTF(exprDef, 128, "log10withmin(<%s>, %s)", var, m); } else { SNPRINTF(exprDef, 128, "log10(<%s>)", var); } avtDataRequest_p nds = new avtDataRequest(exprName.c_str(), ds->GetTimestep(), ds->GetRestriction()); nds->AddSecondaryVariable(var); #ifdef HAVE_LIBSLIVR if ((atts.GetRendererType() == VolumeAttributes::RayCastingSLIVR) || ((atts.GetRendererType() == VolumeAttributes::RayCasting) && (atts.GetSampling() == VolumeAttributes::Trilinear))) nds->SetDesiredGhostDataType(GHOST_ZONE_DATA); #endif newcontract = new avtContract(contract, nds); primaryVariable = new char[exprName.size()+1]; strcpy(primaryVariable, exprName.c_str()); } else // VolumeAttributes::Skew) { setupExpr = true; SNPRINTF(exprDef, 128, "var_skew(<%s>, %f)", var, atts.GetSkewFactor()); avtDataRequest_p nds = new avtDataRequest(exprName.c_str(), ds->GetTimestep(), ds->GetRestriction()); nds->AddSecondaryVariable(var); #ifdef HAVE_LIBSLIVR if ((atts.GetRendererType() == VolumeAttributes::RayCastingSLIVR) || ((atts.GetRendererType() == VolumeAttributes::RayCasting) && (atts.GetSampling() == VolumeAttributes::Trilinear))) nds->SetDesiredGhostDataType(GHOST_ZONE_DATA); #endif newcontract = new avtContract(contract, nds); primaryVariable = new char[strlen(exprName.c_str())+1]; strcpy(primaryVariable, exprName.c_str()); } if (setupExpr) { ExpressionList *elist = ParsingExprList::Instance()->GetList(); Expression *e = NULL; for (int i = 0 ; i < elist->GetNumExpressions() ; i++) { if (elist->GetExpressions(i).GetName() == exprName) { e = &(elist->GetExpressions(i)); break; } } bool shouldDelete = false; if (e == NULL) { e = new Expression(); shouldDelete = true; } e->SetName(exprName.c_str()); e->SetDefinition(exprDef); e->SetType(Expression::ScalarMeshVar); elist->AddExpressions(*e); if (shouldDelete) delete e; } newcontract->NoStreaming(); newcontract->SetHaveRectilinearMeshOptimizations(true); return newcontract; }