/[escript]/trunk/escript/src/Data.cpp
ViewVC logotype

Diff of /trunk/escript/src/Data.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3030 by jfenwick, Thu Jan 28 02:03:15 2010 UTC revision 3031 by jfenwick, Thu May 27 04:04:33 2010 UTC
# Line 3814  escript::applyBinaryCFunction(boost::pyt Line 3814  escript::applyBinaryCFunction(boost::pyt
3814  }  }
3815    
3816  #endif // IKNOWWHATIMDOING  #endif // IKNOWWHATIMDOING
3817    
3818    Data
3819    escript::condEval(escript::Data& mask, escript::Data& trueval, escript::Data& falseval)
3820    {
3821        // First, we need to make sure that trueval and falseval are compatible types.
3822        // also need to ensure that mask is a proper type for a mask
3823        // Need to choose a functionspace and shape for result
3824        // need to catch DataEmpty as well ?
3825    
3826        // only allowing scalar masks
3827    
3828        if (mask.getDataPointRank()!=0)
3829        {
3830        throw DataException("Only supporting scalar masks");
3831        // Allowing people to slice two different objects together within a single datapoint - not allowing that
3832    
3833        }
3834    
3835    
3836    
3837    //     if (trueval.isLazy() || falseval.isLazy() || mask.isLazy())
3838    //     {
3839    //  throw DataException("Not supporting laziness yet");
3840    //
3841    //     }
3842    
3843        if (trueval.getDataPointShape()!=falseval.getDataPointShape())
3844        {
3845        throw DataException("condEval: shapes of true and false values must match.");
3846        }
3847        
3848    
3849        FunctionSpace fs=trueval.getFunctionSpace();    // should check this for compatibility as well
3850        if (trueval.getFunctionSpace()!=falseval.getFunctionSpace())
3851        {
3852        throw DataException("FunctionSpaces must match atm");
3853        }
3854    
3855        if (mask.isLazy() && !mask.actsExpanded())
3856        {
3857        mask.resolve();
3858        }
3859        if (trueval.isLazy() && !trueval.actsExpanded())
3860        {
3861        trueval.resolve();
3862        }
3863        if (falseval.isLazy() && !falseval.actsExpanded())
3864        {
3865        falseval.resolve();
3866        }
3867    
3868        if (mask.isConstant() && trueval.isConstant() && falseval.isConstant())
3869        {
3870        Data result(0,trueval.getDataPointShape(), fs , false);
3871        if (mask.getSampleDataRO(0)[0]>0)
3872        {
3873            result.copy(trueval);
3874        }
3875        else
3876        {
3877            result.copy(falseval);
3878        }
3879        return result;
3880        }
3881        // Now we need to promote to correct ReadyData types
3882        // If they are lazy, they must be expanded
3883        if (mask.actsExpanded() || trueval.actsExpanded() || falseval.actsExpanded())
3884        {
3885        if (!mask.isLazy()) {mask.expand();}
3886        if (!trueval.isLazy()) {trueval.expand();}
3887        if (!falseval.isLazy()) {falseval.expand();}
3888        }
3889        else if (mask.isTagged() || trueval.isTagged() || falseval.isTagged())
3890        {
3891        mask.tag();
3892        trueval.tag();
3893        falseval.tag();
3894        }
3895        // by this point all data will be of the same ready type.
3896        if (mask.isTagged())
3897        {
3898        Data result(0,trueval.getDataPointShape(), fs , false);
3899        result.tag();
3900        DataTagged* rdat=dynamic_cast<DataTagged*>(result.getReady());
3901        DataTagged* tdat=dynamic_cast<DataTagged*>(trueval.getReady());
3902        DataTagged* fdat=dynamic_cast<DataTagged*>(falseval.getReady());
3903        const DataTagged* mdat=dynamic_cast<DataTagged*>(mask.getReady());
3904        DataTypes::ValueType::ValueType srcptr;
3905    
3906        // default value first
3907        if (mdat->getDefaultValueRO(0)>0)
3908        {
3909            srcptr=&(tdat->getDefaultValueRW(0));
3910        } else {
3911            srcptr=&(fdat->getDefaultValueRW(0));
3912        }
3913        for (int i=0;i<trueval.getDataPointSize();++i)
3914        {
3915            *(&(rdat->getDefaultValueRW(0))+i)=*(srcptr+i);
3916        }
3917    
3918        // now we copy the tags from the mask - if the mask does not have it then it doesn't appear
3919        const DataTagged::DataMapType& maskLookup=mdat->getTagLookup();
3920        DataTagged::DataMapType::const_iterator i;
3921        DataTagged::DataMapType::const_iterator thisLookupEnd=maskLookup.end();
3922        for (i=maskLookup.begin();i!=thisLookupEnd;i++)
3923        {
3924            if (mdat->getDataByTagRO(i->first,0)>0)
3925            {
3926            rdat->addTaggedValue(i->first,trueval.getDataPointShape(), tdat->getVectorRO(), tdat->getOffsetForTag(i->first));
3927            }
3928            else
3929            {
3930            rdat->addTaggedValue(i->first,falseval.getDataPointShape(), fdat->getVectorRO(), fdat->getOffsetForTag(i->first));
3931            }
3932        }
3933    
3934        return result;
3935        }
3936        if (!trueval.actsExpanded() || !falseval.actsExpanded() || !mask.actsExpanded())
3937        {
3938        throw DataException("Only supporting all expanded args to condEval atm");
3939        }
3940        else if (mask.actsExpanded() && trueval.actsExpanded() && falseval.actsExpanded())
3941        {
3942        // Here is the code for all expanded objects
3943        
3944        Data result(0,trueval.getDataPointShape(), fs , true);  // Need to support non-expanded as well
3945        // OPENMP 3.0 allows unsigned loop vars.
3946        #if defined(_OPENMP) && (_OPENMP < 200805)
3947        long i;
3948        #else
3949        size_t i;
3950        #endif
3951        DataVector& rvec=result.getReady()->getVectorRW();      // don't need to get aquireWrite since we made it
3952        unsigned int psize=result.getDataPointSize();
3953        
3954        size_t numsamples=result.getNumSamples();
3955        size_t dppsample=result.getNumDataPointsPerSample();
3956        #pragma omp parallel for private(i) schedule(static)
3957        for (i=0;i<numsamples;++i)
3958        {
3959                // We are assuming that the first datapoint in the sample determines which side to use
3960                // for the whole sample.
3961            const DataAbstract::ValueType::value_type* src=0;
3962            const DataAbstract::ValueType::value_type* masksample=mask.getSampleDataRO(i);
3963            if (masksample[0]>0)    // first scalar determines whole sample
3964            {
3965                src=trueval.getSampleDataRO(i);
3966            }
3967            else
3968            {
3969                src=falseval.getSampleDataRO(i);
3970            }
3971    /*      const DataAbstract::ValueType::value_type* truesample=0;
3972            const DataAbstract::ValueType::value_type* falsesample=0;*/
3973            for (int j=0;j<dppsample;++j)
3974            {
3975                size_t offset=j*psize;
3976    //          const DataAbstract::ValueType::value_type* src=0;
3977    //          if (masksample[j] <= 0) // scalar mask remember
3978    //          {
3979    //          if (falsesample==0)
3980    //          {
3981    //              falsesample=falseval.getSampleDataRO(i);
3982    //          }
3983    //          src=falsesample;
3984    //          }
3985    //          else
3986    //          {
3987    //          if (truesample==0)
3988    //          {
3989    //              truesample=trueval.getSampleDataRO(i);
3990    //          }
3991    //          src=truesample;
3992    //          }
3993                for (long k=0;k<psize;++k)
3994                {
3995                rvec[i*dppsample*psize+offset+k]=(src)[offset+k];
3996                }
3997            }
3998        
3999        }
4000        return result;
4001        } else {
4002        throw DataException("Unsupported combination of DataAbstracts");
4003    
4004        }
4005    
4006    }

Legend:
Removed from v.3030  
changed lines
  Added in v.3031

  ViewVC Help
Powered by ViewVC 1.1.26