Changeset 515 for trunk


Ignore:
Timestamp:
Aug 24, 2006, 10:04:28 AM (18 years ago)
Author:
dkearney
Message:

added units of days (d), hours (h), minutes (min), /m2.
minutes units was not added to tcl because tcl thinks it milli-in's
added a few simple tests to test day/hour/minute/second conversions
adjusted python's queue module to get condor working mostly.
adjustments to a few make files

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Makefile.in

    r512 r515  
    5555        set -x;
    5656        cp -r examples @prefix@
     57        rm -f @prefix@/examples/demo.bash.in
    5758
    5859
     
    105106build_pkgs:
    106107        set -x;
    107         make distclean
    108108        if ! test -d "bin"; then \
    109109                mkdir bin;\
     
    129129        cd examples/c-example; make distclean; cd -;
    130130        cd gui; make distclean; cd -;
    131         cd perl; make clean; cd -;
     131        cd perl; make clean; rm Makefile.PL; cd -;
    132132        cd python; rm -rf build; rm setup.py; cd -;
    133133        cd src; make distclean; cd -;
  • trunk/examples/c-example/Makefile.in

    r489 r515  
    4646        rm -f $(PROGS) run*.xml
    4747
    48 distclean:
     48distclean: clean
    4949        - rm Makefile
  • trunk/gui/scripts/units.tcl

    r488 r515  
    484484
    485485Rappture::Units::define s -type seconds -metric yes
     486# can't use min becase tcl thinks its milli-in's
     487# Rappture::Units::define min->s {min*60.00} {s/60.00}
     488Rappture::Units::define h->s {h*3600.00} {s/3600.00}
     489Rappture::Units::define d->s {d*86400.00} {s/86400.00}
    486490
    487491# can't put mol's in because tcl thinks its milli-ol's
  • trunk/python/Rappture/queue.py

    r497 r515  
    1010import time
    1111import shutil
     12import datetime
    1213
    1314# import Rappture Related libs
     
    152153
    153154    def __convertWalltime__(self):
    154         minutesu
     155        pass
    155156
    156157    def submit(self):
    157158        pass
    158159
     160    def __checkFiles__(self,chkFileName):
     161        retVal = False
     162        if not os.path.isfile(chkFileName):
     163            retVal = True
     164        return retVal
     165
    159166    def status(self):
    160         pass
     167        min = 0
     168        tCount = 0
     169        sleepTime = 10
     170
     171        while self.__checkFiles__(self.errFile()):
     172            if tCount == 60 :
     173                min += 1
     174                tCount = 0
     175
     176            self._currStatus = self.getCurrentStatus()
     177            if (self._currStatus != self._prevStatus):
     178                sys.stdout.write("%s: %s\n" % ( self._currStatus, time.ctime() ) )
     179                sys.stdout.flush()
     180                self._prevStatus = self._currStatus
     181
     182            time.sleep(sleepTime)
     183            tCount += sleepTime
    161184
    162185class pbs(queue):
     
    284307        self.errFile()   )
    285308
    286     def __checkErrFiles__(self,chkFileName):
    287         retVal = False
    288         if not os.path.isfile(chkFileName):
    289             retVal = True
    290         return retVal
    291 
    292309    def cmd(self,cmd=''):
    293310        cmd = str(cmd)
     
    333350            raise RpQueueError, error
    334351
    335     def status(self):
    336         min = 0
    337         tCount = 0
    338         sleepTime = 10
    339 
    340         while self.__checkErrFiles__(self.errFile()):
    341             if tCount == 60 :
    342                 min += 1
    343                 tCount = 0
    344 
    345             self._currStatus = self.getCurrentStatus()
    346             if (self._currStatus != self._prevStatus):
    347                 sys.stdout.write("%s: %s\n" % ( self._currStatus, time.ctime() ) )
    348                 sys.stdout.flush()
    349                 self._prevStatus = self._currStatus
    350 
    351             time.sleep(sleepTime)
    352             tCount += sleepTime
     352#    def status(self):
     353#        min = 0
     354#        tCount = 0
     355#        sleepTime = 10
     356#
     357#        while self.__checkFiles__(self.errFile()):
     358#            if tCount == 60 :
     359#                min += 1
     360#                tCount = 0
     361#
     362#            self._currStatus = self.getCurrentStatus()
     363#            if (self._currStatus != self._prevStatus):
     364#                sys.stdout.write("%s: %s\n" % ( self._currStatus, time.ctime() ) )
     365#                sys.stdout.flush()
     366#                self._prevStatus = self._currStatus
     367#
     368#            time.sleep(sleepTime)
     369#            tCount += sleepTime
    353370
    354371
     
    359376    USE_MPI = 1
    360377
    361     def __init__(self,walltime='00:01:00',flags=0):
     378    def __init__(   self,
     379                    jobName,
     380                    resultsDir,
     381                    nodes,
     382                    executable,
     383                    execArgs='',
     384                    walltime='00:01:00',
     385                    flags=0             ):
     386
    362387        # call the base class's init
    363388        for base in self.__class__.__bases__:
     
    365390
    366391        self._condor_msgs = {}
     392        self.__fillStatusDict__()
    367393
    368394        self._flags = flags
    369395        self.__setWorkingDir__()
     396
     397        # setup the empty process lists
     398        self._processList = []
    370399
    371400        # set vars based on user input
     
    394423        self._workingdir = str(epoch) + "_" + session
    395424
    396     def __makeCondorTemplate__(self):
     425    def __makeCondorScript__(self):
    397426#        return """universe=grid
    398427#    gridresource = gt2 tg-gatekeeper.purdue.teragrid.org:2120/jobmanager-pbs
     
    409438#    """
    410439
    411         self._mpirsl = ''
    412         if (self.flags & self.USE_MPI):
     440        self._resultDirPath = os.path.join(os.getcwd(),self.resultsDir())
     441
     442        self._mpirsl = ""
     443        if (self._flags & self.USE_MPI):
    413444            self._mpirsl = "(jobType=mpi)(count=%d)(hostcount=%d)" % \
    414445                            (self.nodes(), self.nodes())
     446
     447        (wall_hr,wall_min,wall_sec) = self.walltime().split(":")
     448        walltime =  int(wall_hr)*60 + int(wall_min) + int(wall_sec)/60.00
    415449
    416450        return """universe=grid
     
    424458    log = %s
    425459    #globusrsl = (project=TG-ECD060000N)(jobType=mpi)(count=2)(hostcount=2)(maxWallTime=WALLTIME)
    426     globusrsl = (project=TG-ECD060000N)(maxWallTime=%s)%s(queue=%s)
     460    globusrsl = (project=TG-ECD060000N)(maxWallTime=%g)%s(queue=%s)
    427461    notification = never
    428462    """ % ( self.executable(),
     
    431465            self.resultsDir(),
    432466            self.logFile(),
    433             self.resultsDir(),
    434             self.walltime(),
     467            walltime,
    435468            self._mpirsl,
    436469            self.queue()    )
    437470
    438     def addProcess(self,argsList,inputFiles=[],):
    439 #        return """arguments = ARGUMENT resultsID.tar.gz WORKINGDIR_ID
    440 #    transfer_input_files = INFILE,\\
    441 #                           APPROOT/data/circle-1.e,\\
    442 #                           APPROOT/data/circle-1.n,\\
    443 #                           APPROOT/data/circle-1.d,\\
    444 #                           APPROOT/data/circle-1.s,\\
    445 #                           APPROOT/data/circle-1_ni,\\
    446 #                           APPROOT/data/circle-1.edge,\\
    447 #                           APPROOT/data/circle-1.ele,\\
    448 #                           APPROOT/data/circle-1.node
    449 #    transfer_output_files = resultsID.tar.gz
    450 #    Queue
    451 #    """
     471    def addProcess(self,argsList=[],inputFiles=[]):
     472#    return """arguments = ARGUMENT resultsID.tar.gz WORKINGDIR_ID
     473# transfer_input_files = INFILE,\\
     474#                        APPROOT/grid.1.poly,\\
     475#                        APPROOT/grid.1.node,\\
     476#                        APPROOT/grid.1.ele,\\
     477#                        APPROOT/grid.1.edge
     478# transfer_output_files = resultsID.tar.gz
     479# Queue
     480# """
     481        args = " ".join(argsList)
    452482        transInFiles = ",\\\\\n\t\t".join(inputFiles)
    453483        nextProcId = len(self._processList)
    454         newProcess = """arguments = %s results%d.tar.gz %s_%d
     484        resultsTarName = "%s%d.tar.gz" % (self.jobName(),nextProcId)
     485        newProcess = """arguments = %s %s %s_%d
    455486    transfer_input_files = %s
    456     transfer_output_files = resultsID.tar.gz
     487    transfer_output_files = %s
    457488    Queue
    458489
    459     """ % (argList,nextProcId,self._workingdir,nextProcId,transInFiles)
     490    """ % ( args,
     491            resultsTarName,
     492            self._workingdir,
     493            nextProcId,
     494            transInFiles,
     495            resultsTarName  )
    460496        self._processList.append(newProcess)
    461497
    462498
    463 #    def chkCondorStatus(chkID):
    464499    def getCurrentStatus(self):
    465         global condor_msgs
    466         if chkID:
    467             chkCmd = 'condor_q'
    468             cmdOutput = getCommandOutput("%s | grep \'^ *%s\'" % (chkCmd,chkID))
     500        if self._jobId:
     501            chkCmd = "condor_q | grep \'^ *%s\'" % (self._jobId)
     502            cmdOutput = getCommandOutput(chkCmd)
    469503
    470504            # parse a string that should look like this:
     
    480514            if len(parseResults) > 6:
    481515                qstat = parseResults[5]
    482                 retVal = condor_msgs[qstat]
     516                retVal = self._condor_msgs[qstat]
    483517
    484518            if retVal == '':
    485                 retVal = condor_msgs['DEFAULT']
     519                retVal = self._condor_msgs['DEFAULT']
    486520
    487521        return retVal
    488522
    489     def chkCondorLoop(resultTarPathPrefix,numJobs):
    490 
     523    def __checkFiles__(self):
     524        numJobs = len(self._processList)
    491525        retVal = numJobs
    492526        for i in xrange(numJobs):
    493             resultTarPath = resultTarPathPrefix + str(i) + ".tar.gz"
     527            resultTarPath = self.resultsDir() + "/" + self.jobName() + str(i) + ".tar.gz"
    494528
    495529            # this might be the point of a race condition,
     
    508542        return retVal
    509543
    510     def runCondor ( inputs,
    511                     condorScriptPath,
    512                     resultDirName ):
    513 
    514         # prepare the user output for printing our job submission info to screen
    515 
    516         jobNodeCnt = int(inputs['Nvg'])
    517 
    518         sys.stdout.write ("Your job is set to use %d node(s)\n" % (jobNodeCnt) )
    519         # sys.stdout.write ("with %d processor(s) per node\n" % int(ppn))
    520         sys.stdout.write ("Submitting job to queue\n")
    521         sys.stdout.flush()
    522 
    523         # submit the condor job
    524         condorCmd = 'condor_submit'
    525         cmdOutData = getCommandOutput('%s %s' % (condorCmd,condorScriptPath))
    526 
    527         # grab the qID from the return data of the command
    528         global qID
    529         qID.append(re.search('cluster [0-9]+', cmdOutData).group().split()[1])
    530 
    531         # track condor's progress
     544    def status(self):
    532545        min = 0
    533546        tCount = 0
    534547        sleepTime = 10
    535         prevStatus = '?'
    536         currStatus = '?'
    537         resultTarNamePrefix = 'results'
    538         resultTarPathPrefix = resultDirName+'/'+resultTarNamePrefix
    539 
    540         while chkCondorLoop(resultTarPathPrefix,int(inputs['Nvg'])):
    541             currStatus = chkCondorStatus(qID[0])
     548
     549        while self.__checkFiles__():
    542550            if tCount == 60 :
    543551                min += 1
    544552                tCount = 0
    545             if (currStatus != prevStatus) :
    546                 sys.stdout.write("%s: %s\n" % ( currStatus, time.ctime() ) )
    547                 prevStatus = currStatus
    548 
    549             sys.stdout.flush()
     553
     554            self._currStatus = self.getCurrentStatus()
     555            if (self._currStatus != self._prevStatus):
     556                sys.stdout.write("%s: %s\n" % ( self._currStatus, time.ctime() ) )
     557                sys.stdout.flush()
     558                self._prevStatus = self._currStatus
     559
    550560            time.sleep(sleepTime)
    551561            tCount += sleepTime
    552562
    553 
    554         outFiles = {}
    555         errFiles = {}
    556         outfileNamePrefix = "out."
    557         errfileNamePrefix = "err."
    558         logfileNamePrefix = "log."
    559         logfileName = resultDirName + logfileNamePrefix + qID[0]
    560 
    561         for i in xrange(int(inputs['Nvg'])):
    562             resultTarName = resultTarNamePrefix + str(i) + ".tar.gz"
    563             resultTarPath = resultDirName+'/'+resultTarName
    564 
    565             # check to see that the result file exists, if not raise error
    566             if (not os.path.exists(resultTarPath)):
    567                 error = 'Returned data not found at %s' % (resultTarPath)
    568                 raise RuntimeError, error
    569                 sys.exit(-1)
    570 
    571             # prepare to return error files and outfiles
    572             outFiles[i] = resultDirName+'/'+outfileNamePrefix+qID[0]+'.'+str(i)
    573             errFiles[i] = resultDirName+'/'+errfileNamePrefix+qID[0]+'.'+str(i)
    574 
    575             # check to see that the result tar size is greater than 0
    576             resultTarSize = os.path.getsize(resultTarPath)
    577             if (resultTarSize):
    578                 # untar the output and return out and err file texts
    579     #           print 'tar --directory %s -xzf %s' % (resultDirName,resultTarPath)
    580                 untarRslt = getCommandOutput('tar --directory %s -xzf %s' % (resultDirName,resultTarPath))
    581     #           print 'untarRslt = %s' % (untarRslt)
    582 
    583             else:
    584                 # tar file is of zero size, simulation did not have ended properly
    585                 error = 'Returned file does not contain any data\n Unsuccessful Run'
    586                 raise RuntimeError, error
    587                 sys.exit(-1)
    588 
    589         return (logfileName, outFiles, errFiles)
     563    def submit(self):
     564
     565        if len(self._processList) == 0:
     566            self.addProcess()
     567
     568        submitFileData = self.__makeCondorScript__() + "\n".join(self._processList)
     569        submitFileName = self._resultDirPath+'/'+self.jobName()+'.condor'
     570        writeFile(submitFileName,submitFileData)
     571
     572        # submit the condor job
     573        myCWD = os.getcwd()
     574        os.chdir(self._resultDirPath)
     575        condorCmd = 'condor_submit %s 2> condor_submit.error' % (submitFileName)
     576        cmdOutData = getCommandOutput(condorCmd)
     577        os.chdir(myCWD)
     578
     579        self._prevStatus = ''
     580        self._currStatus = ''
     581
     582        # a successful submission (on hamlet/lear) follows this regexp
     583        if re.search(r'cluster ([0-9]+)',cmdOutData):
     584            self._jobId = re.search(r'cluster ([0-9]+)',cmdOutData).group(1)
     585        else:
     586            print "cmdOutData returned :%s:" % cmdOutData
     587            error = 'Submission to Condor Queue Failed'
     588            # raise RpQueueError, error
    590589
    591590#######################################################################
     
    613612    else :
    614613        mpiCommand = mpiCommand.strip()
     614
     615    sys.stdout.write("testing hello with condor\n")
     616    jobName = 'helloMPITest'
     617    resultsDir = createDir('4321')
     618    executable = 'hello.sh'
     619    shutil.copy('hello/hello.sh',resultsDir)
     620    shutil.copy('hello/hello',resultsDir)
     621    myCondorObj = condor(jobName,resultsDir,2,executable,walltime=walltime,flags=condor.USE_MPI)
     622    myCondorObj.submit()
     623    myCondorObj.status()
     624    sys.stdout.flush()
     625
     626    sys.stdout.write("testing hello\n")
     627    jobName = 'helloRP_MPITest'
     628    resultsDir = createDir('abab')
     629    executable = 'helloRP'
     630    driver = "driver7878.xml"
     631    shutil.copy('hello/helloRP',resultsDir)
     632    shutil.copy(driver,resultsDir)
     633    myPBSObj =  pbs(jobName,resultsDir,nodes,executable,driver)
     634    myPBSObj.submit()
     635    myPBSObj.status()
     636    sys.stdout.flush()
     637
    615638
    616639    sys.stdout.write("testing hello\n")
  • trunk/src/core/RpUnits.cc

    r487 r515  
    17231723 * Defines the following units:
    17241724 *   seconds  (s)
     1725 *   minutes  (min)
     1726 *   hours    (h)
     1727 *   days     (d)
    17251728 *
     1729 *   month and year are not included because simple
     1730 *   day->month conversions may be misleading
     1731 *   month->year conversions may be included in the future
     1732 *
    17261733 * Return codes: 0 success, anything else is error
    17271734 */
     
    17301737RpUnitsPreset::addPresetTime () {
    17311738
    1732     RpUnits* seconds    = RpUnits::define("s", NULL, RP_TYPE_TIME);
    1733 
    1734     RpUnits::makeMetric(seconds);
     1739    RpUnits* second    = RpUnits::define("s", NULL, RP_TYPE_TIME);
     1740    RpUnits* minute    = RpUnits::define("min", second, RP_TYPE_TIME);
     1741    RpUnits* hour      = RpUnits::define("h", second, RP_TYPE_TIME);
     1742    RpUnits* day       = RpUnits::define("d", second, RP_TYPE_TIME);
     1743
     1744    RpUnits::makeMetric(second);
    17351745
    17361746    // add time definitions
     1747
     1748    RpUnits::define(second, minute, sec2min, min2sec);
     1749    RpUnits::define(second, hour, sec2hour, hour2sec);
     1750    RpUnits::define(second, day, sec2day, day2sec);
    17371751
    17381752    return 0;
  • trunk/src/core/RpUnitsStd.cc

    r382 r515  
    302302}
    303303
     304/****************************************
     305 * TIME CONVERSIONS
     306 ****************************************/
     307
     308double sec2min (double sec)
     309{
     310    return (sec/60.00);
     311}
     312
     313double min2sec (double min)
     314{
     315    return (min*60.00);
     316}
     317
     318double sec2hour (double sec)
     319{
     320    return (sec/3600.00);
     321}
     322
     323double hour2sec (double hour)
     324{
     325    return (hour*3600.00);
     326}
     327
     328double sec2day (double sec)
     329{
     330    return (sec/86400.00);
     331}
     332
     333double day2sec (double day)
     334{
     335    return (day*86400.00);
     336}
     337
     338
     339
    304340#ifdef __cplusplus
    305341}
  • trunk/src/core/RpUnitsStd.h

    r511 r515  
    8585
    8686
     87
     88double sec2min    (double sec);
     89double min2sec    (double min);
     90double sec2hour   (double sec);
     91double hour2sec   (double hour);
     92double sec2day (double sec);
     93double day2sec (double day);
     94
    8795#ifdef __cplusplus
    8896}
  • trunk/test/Makefile.in

    r495 r515  
    3838# define our directories
    3939#
    40 INCLUDES_DIR    = $(RP_BASE)/include
     40INCLUDES_DIR    = $(RP_BASE)/src
    4141BIN_DIR         = $(RP_BASE)/bin
    4242LIB_DIR         = $(RP_INSTALL_BASE)/lib # $(RP_BASE)/src
     
    5252INCL_CEE        = -I $(INCLUDES_DIR)/cee
    5353INCL_FORTRAN    = -I $(INCLUDES_DIR)/fortran
    54 INCL_PY         = -I $(INCLUDES_DIR)/python
    5554
    5655
  • trunk/test/src/RpUnits_test.cc

    r394 r515  
    327327    std::cout << "convert(\"5.00mm\",\"\",0) = " << RpUnits::convert("5.00mm","",0) << std::endl;
    328328
     329    // day hour min sec test
     330    std::cout << "convert(\"5.00s\",\"s\",1) = " << RpUnits::convert("5.00s","s",1) << " = 5s" << std::endl;
     331    std::cout << "convert(\"5.00s\",\"s\",0) = " << RpUnits::convert("5.00s","s",0) << " = 5" << std::endl;
     332    std::cout << "convert(\"5.00min\",\"s\",1) = " << RpUnits::convert("5.00min","s",1) << " = 300s" << std::endl;
     333    std::cout << "convert(\"5.00min\",\"s\",0) = " << RpUnits::convert("5.00min","s",0) << " = 300" << std::endl;
     334    std::cout << "convert(\"5.00h\",\"s\",1) = " << RpUnits::convert("5.00h","s",1) << " = 18000s" << std::endl;
     335    std::cout << "convert(\"5.00h\",\"s\",0) = " << RpUnits::convert("5.00h","s",0) << " = 18000" << std::endl;
     336    std::cout << "convert(\"5.00d\",\"s\",1) = " << RpUnits::convert("5.00d","s",1) << " = 432000s" << std::endl;
     337    std::cout << "convert(\"5.00d\",\"s\",0) = " << RpUnits::convert("5.00d","s",0) << " = 432000" << std::endl;
     338
     339    std::cout << "convert(\"5.00s\",\"min\",1) = " << RpUnits::convert("5.00s","min",1) << " = 300min" << std::endl;
     340    std::cout << "convert(\"5.00s\",\"min\",0) = " << RpUnits::convert("5.00s","min",0) << " = 300" << std::endl;
     341    std::cout << "convert(\"5.00min\",\"min\",1) = " << RpUnits::convert("5.00min","min",1) << " = 5min" << std::endl;
     342    std::cout << "convert(\"5.00min\",\"min\",0) = " << RpUnits::convert("5.00min","min",0) << " = 5" << std::endl;
     343    std::cout << "convert(\"5.00h\",\"min\",1) = " << RpUnits::convert("5.00h","min",1) << " = 300min" << std::endl;
     344    std::cout << "convert(\"5.00h\",\"min\",0) = " << RpUnits::convert("5.00h","min",0) << " = 300" << std::endl;
     345    std::cout << "convert(\"5.00d\",\"min\",1) = " << RpUnits::convert("5.00d","min",1) << " = 7200min" << std::endl;
     346    std::cout << "convert(\"5.00d\",\"min\",0) = " << RpUnits::convert("5.00d","min",0) << " = 7200" << std::endl;
     347
     348    std::cout << "convert(\"5.00s\",\"h\",1) = " << RpUnits::convert("5.00s","h",1) << " = 0.001388h" << std::endl;
     349    std::cout << "convert(\"5.00s\",\"h\",0) = " << RpUnits::convert("5.00s","h",0) << " = 0.001388" << std::endl;
     350    std::cout << "convert(\"5.00min\",\"h\",1) = " << RpUnits::convert("5.00min","h",1) << " = 0.0833h" << std::endl;
     351    std::cout << "convert(\"5.00min\",\"h\",0) = " << RpUnits::convert("5.00min","h",0) << " = 0.0833" << std::endl;
     352    std::cout << "convert(\"5.00h\",\"h\",1) = " << RpUnits::convert("5.00h","h",1) << " = 5h" << std::endl;
     353    std::cout << "convert(\"5.00h\",\"h\",0) = " << RpUnits::convert("5.00h","h",0) << " = 5" << std::endl;
     354    std::cout << "convert(\"5.00d\",\"h\",1) = " << RpUnits::convert("5.00d","h",1) << " = 120h" << std::endl;
     355    std::cout << "convert(\"5.00d\",\"h\",0) = " << RpUnits::convert("5.00d","h",0) << " = 120" << std::endl;
     356
     357    std::cout << "convert(\"5.00s\",\"d\",1) = " << RpUnits::convert("5.00s","d",1) << " = 5.7870e-05d" << std::endl;
     358    std::cout << "convert(\"5.00s\",\"d\",0) = " << RpUnits::convert("5.00s","d",0) << " = 5.7870e-05" << std::endl;
     359    std::cout << "convert(\"5.00min\",\"d\",1) = " << RpUnits::convert("5.00min","d",1) << " = 0.00347222d" << std::endl;
     360    std::cout << "convert(\"5.00min\",\"d\",0) = " << RpUnits::convert("5.00min","d",0) << " = 0.00347222" << std::endl;
     361    std::cout << "convert(\"5.00h\",\"d\",1) = " << RpUnits::convert("5.00h","d",1) << " = 0.208333d" << std::endl;
     362    std::cout << "convert(\"5.00h\",\"d\",0) = " << RpUnits::convert("5.00h","d",0) << " = 0.208333" << std::endl;
     363    std::cout << "convert(\"5.00d\",\"d\",1) = " << RpUnits::convert("5.00d","d",1) << " = 5d" << std::endl;
     364    std::cout << "convert(\"5.00d\",\"d\",0) = " << RpUnits::convert("5.00d","d",0) << " = 5" << std::endl;
     365
    329366    return 0;
    330367
Note: See TracChangeset for help on using the changeset viewer.