// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void ErodeDilateBadData::dataCheck() { setErrorCondition(0); getDataContainerArray()->getPrereqGeometryFromDataContainer<ImageGeom, AbstractFilter>(this, getFeatureIdsArrayPath().getDataContainerName()); if (getNumIterations() <= 0) { QString ss = QObject::tr("The number of iterations (%1) must be positive").arg(getNumIterations()); setErrorCondition(-5555); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); } QVector<size_t> cDims(1, 1); m_FeatureIdsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getFeatureIdsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ if( NULL != m_FeatureIdsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */ { m_FeatureIds = m_FeatureIdsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */ }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void ErodeDilateBadData::readFilterParameters(AbstractFilterParametersReader* reader, int index) { reader->openFilterGroup(this, index); setFeatureIdsArrayPath(reader->readDataArrayPath("FeatureIdsArrayPath", getFeatureIdsArrayPath() ) ); setDirection( reader->readValue("Direction", getDirection()) ); setNumIterations( reader->readValue("NumIterations", getNumIterations()) ); setXDirOn(reader->readValue("XDirOn", getXDirOn()) ); setYDirOn(reader->readValue("YDirOn", getYDirOn()) ); setZDirOn(reader->readValue("ZDirOn", getZDirOn()) ); reader->closeFilterGroup(); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void ErodeDilateBadData::setupFilterParameters() { FilterParameterVector parameters; { ChoiceFilterParameter::Pointer parameter = ChoiceFilterParameter::New(); parameter->setHumanLabel("Operation"); parameter->setPropertyName("Direction"); QVector<QString> choices; choices.push_back("Dilate"); choices.push_back("Erode"); parameter->setChoices(choices); parameter->setCategory(FilterParameter::Parameter); parameters.push_back(parameter); } parameters.push_back(IntFilterParameter::New("Number of Iterations", "NumIterations", getNumIterations(), FilterParameter::Parameter)); parameters.push_back(BooleanFilterParameter::New("X Direction", "XDirOn", getXDirOn(), FilterParameter::Parameter)); parameters.push_back(BooleanFilterParameter::New("Y Direction", "YDirOn", getYDirOn(), FilterParameter::Parameter)); parameters.push_back(BooleanFilterParameter::New("Z Direction", "ZDirOn", getZDirOn(), FilterParameter::Parameter)); parameters.push_back(SeparatorFilterParameter::New("Cell Data", FilterParameter::RequiredArray)); { DataArraySelectionFilterParameter::RequirementType req = DataArraySelectionFilterParameter::CreateRequirement(DREAM3D::TypeNames::Int32, 1, DREAM3D::AttributeMatrixType::Cell, DREAM3D::GeometryType::ImageGeometry); parameters.push_back(DataArraySelectionFilterParameter::New("Feature Ids", "FeatureIdsArrayPath", getFeatureIdsArrayPath(), FilterParameter::RequiredArray, req)); } setFilterParameters(parameters); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void OpenCloseBadData::writeFilterParameters(AbstractFilterParametersWriter* writer) { writer->writeValue("Direction", getDirection() ); writer->writeValue("NumIterations", getNumIterations() ); }
//Worker function. Start and end represent the #pragma line and the closing brace //Drives all the work for a parallel for void parallelForHelper(int start, int end) { //grab the necessary values from the #pragma line std::string pragmaString = input.at(start); strvec privVars = getConstructVars(pragmaString, "private"); strvec sharedVars = getConstructVars(pragmaString, "shared"); int numThreads = getNumThreads(pragmaString); //create a vector for the new pthreads void* function std::vector<std::string> newFunction; std::string newFuncName; std::string smallNewFuncName = std::string("func").append(std::to_string(currentFunction)); newFuncName.append("void* func").append(std::to_string(currentFunction)).append("(void* paramStruct)"); newFunction.push_back(newFuncName); currentFunction++; newFunction.push_back("{"); //now handle the case when a parallel for is inside a parallel. in that case, the parfor will not have priv/shared declared //it will instead use the priv/shared declared above //those are backed up in global vars. if (privVars.size() == 0 && sharedVars.size() == 0) //if we determine nothing is private, copy the global backup to the local strvecs { for (int i = 0; i < privVarBackup.size(); i++) { privVars.push_back(privVarBackup.at(i)); } for (int i = 0; i < sharedVarBackup.size(); i++) { sharedVars.push_back(sharedVarBackup.at(i)); } } //redeclare privates in the new function redeclareVars(privVars, newFunction); strvec privVarDeclarations; redeclareVars(privVars, privVarDeclarations); add(privVarDeclarations, totalPrivBackup); //globals will appear later redeclareVars(sharedVars, globalVars); //move the code to the new function //first modify the for loop to use the start and end from the new struct int numIterations = getNumIterations(input.at(start + 1)); input.at(start + 1) = fixForLine(input.at(start + 1)); //then copy the rest of the stuff for (int i = start + 1; i < end; i++) { newFunction.push_back(input.at(i)); } newFunction.push_back("}"); newFunction.push_back("}"); //delete the #pragma section input.erase(input.begin() + start, input.begin() + end + 1); //record the offset as start since we're going to be changing the size of the vector int newOffset = start; //set up the pthreads code //first we need an array of pthread_t threadids with size = numthreads std::string tempString = std::string("pthread_t threads[").append(std::to_string(numThreads)).append("];"); input.insert(input.begin() + newOffset++, tempString); //populate the threads[] array std::string loopVar = std::string("uniqueVar").append(std::to_string(uniqueVarNum)); uniqueVarNum++; tempString = std::string("for (int ").append(loopVar).append(" = 0; ").append(loopVar).append(" < ").append(std::to_string(numThreads)).append("; ").append(loopVar).append("++)"); input.insert(input.begin() + newOffset++, tempString); input.insert(input.begin() + newOffset++, "{"); tempString = std::string("threads[").append(loopVar).append("] = ").append(loopVar).append(";"); input.insert(input.begin() + newOffset++, tempString); input.insert(input.begin() + newOffset++, "}"); //create the pthreads code int uneven = numIterations - ((numIterations / numThreads) * numThreads); //figure out how many don't go in evenly int basicNum = numIterations / numThreads; //now distribute the iterations among the pthreads //example: 18 iterations among 4 threads //break it down as follows: //0-3 thread 1 //4-7 thread 2 //8-11 thread 3 //12-17 thread 4 //or 12-14 thread 4 int startIteration = 0; int endIteration = basicNum - 1; for (int i = 0; i < numThreads; i++) { tempString = std::string("StartEnd paramStruct").append(std::to_string(i)).append(";"); input.insert(input.begin() + newOffset++, tempString); tempString = std::string("paramStruct").append(std::to_string(i)).append(".start = ").append(std::to_string(startIteration)).append(";"); input.insert(input.begin() + newOffset++, tempString); startIteration += basicNum; if (i == numThreads - 1) //if we're on the last loop, give all remaining iterations to this thread. { endIteration = numIterations - 1; //-1 to fix off by one error } tempString = std::string("paramStruct").append(std::to_string(i)).append(".end = ").append(std::to_string(endIteration + 1)).append(";"); //plus 1 since for loop is < input.insert(input.begin() + newOffset++, tempString); endIteration += basicNum; tempString = std::string("paramStruct").append(std::to_string(i)).append(".threadNum = ").append(std::to_string(i)).append(";"); input.insert(input.begin() + newOffset++, tempString); tempString = std::string("pthread_create(&threads[").append(std::to_string(i)).append("], NULL, ").append(smallNewFuncName).append(", (void*) ¶mStruct").append(std::to_string(i)).append(");"); input.insert(input.begin() + newOffset++, tempString); } //now join the threads for (int i = 0; i < numThreads; i++) { tempString = std::string("pthread_join(threads[").append(std::to_string(i)).append("], NULL);"); input.insert(input.begin() + newOffset++, tempString); } //insert the new stuff, in reverse order!! insertAfterIncludes(newFunction); //first, new function }