<commit_before>// @(#)root/net:$Name:  $:$Id: TGrid.cxx,v 1.8 2005/05/13 08:49:54 rdm Exp $
// Author: Fons Rademakers   3/1/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGrid                                                                //
//                                                                      //
// Abstract base class defining interface to common GRID services.      //
//                                                                      //
// To open a connection to a GRID use the static method Connect().      //
// The argument of Connect() is of the form:                            //
//    <grid>[://<host>][:<port>], e.g.                                  //
// alien, alien://alice.cern.ch, globus://glsvr1.cern.ch, ...           //
// Depending on the <grid> specified an appropriate plugin library      //
// will be loaded which will provide the real interface.                //
//                                                                      //
// Related classes are TGridResult.                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGrid.h"
#include "TUrl.h"
#include "TROOT.h"
#include "TPluginManager.h"
#include "TFile.h"
#include "TList.h"
#include "TError.h"
#include "TUUID.h"
#include "TSystem.h"
#include "TH1.h"
#include "TChain.h"
#include "TKey.h"

TGrid *gGrid = 0;

ClassImp(TGrid)

//______________________________________________________________________________
TGrid::TGrid() : fPort(-1), fMergerOutputFile(0)
{
   // Create grid interface object.

   fMergerFileList = new TList;
   fMergerFileList->SetOwner(kTRUE);
}

//______________________________________________________________________________
TGrid *TGrid::Connect(const char *grid, const char *uid, const char *pw,
                      const char *options)
{
   // The grid should be of the form:  <grid>://<host>[:<port>],
   // e.g.:  alien://alice.cern.ch, globus://glsrv1.cern.ch, ...
   // The uid is the username and pw the password that should be used for
   // the connection. Depending on the <grid> the shared library (plugin)
   // for the selected system will be loaded. When the connection could not
   // be opened 0 is returned. For AliEn the supported options are:
   // -domain=<domain name>
   // -debug=<debug level from 1 to 10>
   // Example: "-domain=cern.ch -debug=5"

   TPluginHandler *h;
   TGrid *g = 0;

   if (!grid) {
      ::Error("TGrid::Connect", "no grid specified");
      return 0;
   }
   if (!uid)
      uid = "";
   if (!pw)
      pw = "";
   if (!options)
      options = "";

   if ((h = gROOT->GetPluginManager()->FindHandler("TGrid", grid))) {
      if (h->LoadPlugin() == -1)
         return 0;
      g = (TGrid *) h->ExecPlugin(4, grid, uid, pw, options);
   }

   return g;
}

//______________________________________________________________________________
TGrid::~TGrid()
{
   // Cleanup.

  if (fMergerFileList)
    delete fMergerFileList;

  if (fMergerOutputFile)
    delete fMergerOutputFile;
}

//______________________________________________________________________________
void TGrid::PrintProgress(Long64_t bytesread, Long64_t size)
{
   // Print file copy progress.

   fprintf(stderr, "[TGrid::Cp] Total %.02f MB\t|", (Double_t)size/1048576);
   for (int l = 0; l < 20; l++) {
      if (l < 20*bytesread/size)
         fprintf(stderr, "=");
      if (l == 20*bytesread/size)
         fprintf(stderr, ">");
      if (l > 20*bytesread/size)
         fprintf(stderr, ".");
   }

   fWatch.Stop();
   Double_t lCopy_time = fWatch.RealTime();
   fprintf(stderr, "| %.02f %% [%.01f MB/s]\r",
          100.0*bytesread/size, bytesread/lCopy_time/1048576.);
   fWatch.Continue();
}

//______________________________________________________________________________
Bool_t TGrid::Cp(const char *src, const char *dst, Bool_t progressbar,
                 UInt_t buffersize)
{
   // Allows to copy file from src to dst URL.

   Bool_t success = kFALSE;

   TUrl sURL(src, kTRUE);
   TUrl dURL(dst, kTRUE);

   char *copybuffer = 0;

   TFile *sfile = 0;
   TFile *dfile = 0;

   sfile = TFile::Open(src, "-READ");

   if (!sfile) {
      Error("Cp", "cannot open source file %s", src);
      goto copyout;
   }

   dfile = TFile::Open(dst, "-RECREATE");

   if (!dfile) {
      Error("Cp", "cannot open destination file %s", dst);
      goto copyout;
   }

   sfile->Seek(0);
   dfile->Seek(0);

   copybuffer = new char[buffersize];
   if (!copybuffer) {
      Error("Cp", "cannot allocate the copy buffer");
      goto copyout;
   }

   Bool_t   readop;
   Bool_t   writeop;
   Long64_t read;
   Long64_t written;
   Long64_t totalread;
   Long64_t filesize;
   filesize  = sfile->GetSize();
   totalread = 0;
   fWatch.Start();

   Long64_t b00 = sfile->GetBytesRead();

   do {
      if (progressbar) PrintProgress(totalread, filesize);

      Long64_t b1 = sfile->GetBytesRead() - b00;

      Long64_t readsize;
      if (filesize - b1 > (Long64_t)buffersize) {
         readsize = buffersize;
      } else {
         readsize = filesize - b1;
      }

      Long64_t b0 = sfile->GetBytesRead();
      readop = sfile->ReadBuffer(copybuffer, readsize);
      read   = sfile->GetBytesRead() - b0;
      if (read < 0) {
         Error("Cp", "cannot read from source file %s", src);
         goto copyout;
      }

      Long64_t w0 = dfile->GetBytesWritten();
      writeop = dfile->WriteBuffer(copybuffer, read);
      written = dfile->GetBytesWritten() - w0;
      if (written != read) {
         Error("Cp", "cannot write %d bytes to destination file %s", read, dst);
         goto copyout;
      }
      totalread += read;
   } while (read == (Long64_t)buffersize);

   if (progressbar) {
      PrintProgress(totalread, filesize);
      fprintf(stderr, "\n");
   }

   success = kTRUE;

copyout:
   if (sfile) sfile->Close();
   if (dfile) dfile->Close();

   if (sfile) delete sfile;
   if (dfile) delete dfile;
   if (copybuffer) delete copybuffer;

   fWatch.Stop();
   fWatch.Reset();

   return success;
}

//______________________________________________________________________________
void TGrid::MergerReset()
{
   // Reset merger file list.

   fMergerFileList->Clear();
}

//______________________________________________________________________________
Bool_t TGrid::MergerAddFile(const char *url)
{
   // Add file to file merger.

   TUUID uuid;
   TString localcopy = "file:/tmp/";
   localcopy += "ROOTMERGE-";
   localcopy += uuid.AsString();
   localcopy += ".root";

   if (!Cp(url, localcopy)) {
      Error("MergerAddFile", "cannot get a local copy of file %s", url);
      return kFALSE;
   }

   TFile *newfile = TFile::Open(localcopy, "READ");
   if (!newfile) {
      Error("MergerAddFile", "cannot open local copy %s of URL %s",
            localcopy.Data(), url);
      return kFALSE;
   } else {
      fMergerFileList->Add(newfile);
      return  kTRUE;
   }
}

//______________________________________________________________________________
Bool_t TGrid::MergerOutputFile(const char *outputfile)
{
   // Open merger output file.

   if (fMergerOutputFile)
      delete fMergerOutputFile;

   fMergerOutputFilename = outputfile;

   TUUID uuid;
   TString localcopy = "file:/tmp/";
   localcopy += "ROOTMERGED-";
   localcopy += uuid.AsString();
   localcopy += ".root";

   fMergerOutputFile = TFile::Open(localcopy, "RECREATE");
   fMergerOutputFilename1 = localcopy;

   if (!fMergerOutputFile) {
      Error("MergerOutputFile", "cannot open the MERGER outputfile %s", localcopy.Data());
      return kFALSE;
   }
   return kTRUE;
}

//______________________________________________________________________________
void TGrid::MergerPrintFiles(Option_t *options)
{
   // Print list of files being merged.

   fMergerFileList->Print(options);
}

//______________________________________________________________________________
Bool_t TGrid::MergerMerge()
{
   // Merge the files.

   if (!fMergerOutputFile) {
      Info("MergerMerge", "will merge the results to the file "
           "GridMergerMerged.root in your working directory, "
           "since you didn't specify a merge filename");
      if (!MergerOutputFile("GridMergerMerged.root")) {
         return kFALSE;
      }
   }

   Bool_t result = MergerMergeRecursive(fMergerOutputFile, fMergerFileList);
   if (!result) {
      Error("MergerMerge", "error during merge of your ROOT files");
   } else {
      fMergerOutputFile->Write();
      // copy the result file to the final destination
      Cp(fMergerOutputFilename1, fMergerOutputFilename);
   }

   // remove the temporary result file
   TString path(fMergerOutputFile->GetPath());
   path = path(0, path.Index(':',0));
   gSystem->Unlink(path);
   fMergerOutputFile = 0;

   TIter next(fMergerFileList);
   TFile *file;
   while ((file = (TFile*) next())) {
      // close the files
      file->Close();
      // remove the temporary files
      TString path(file->GetPath());
      path = path(0, path.Index(':',0));
      gSystem->Unlink(path);
   }
   return result;
}

//______________________________________________________________________________
Bool_t TGrid::MergerMergeRecursive(TDirectory *target, TList *sourcelist)
{
   // Recursively merge objects in the ROOT files.

   TString path(strstr(target->GetPath(), ":"));
   path.Remove(0, 2);

   TFile *first_source = (TFile*)sourcelist->First();
   first_source->cd(path);
   TDirectory *current_sourcedir = gDirectory;

   TChain *globChain = 0;
   TIter nextkey(current_sourcedir->GetListOfKeys());
   TKey *key;
   Bool_t success = kTRUE;

   // gain time, do not add the objects in the list in memory
   TH1::AddDirectory(kFALSE);

   while ((key = (TKey*) nextkey())) {
      first_source->cd(path);
      TObject *obj = key->ReadObj();

      if (obj->IsA()->InheritsFrom("TH1")) {
         Info("MergerMergeRecursive", "merging histogram %s", obj->GetName());
         TH1 *h1 = (TH1*)obj;

         TFile *nextsource = (TFile*)sourcelist->After(first_source);
         while (nextsource) {

            nextsource->cd(path);
            TH1 *h2 = (TH1*)gDirectory->Get(h1->GetName());
            if (h2) {
               h1->Add(h2);
               delete h2;
            }

            nextsource = (TFile*)sourcelist->After(nextsource);
         }
      } else if (obj->IsA()->InheritsFrom("TTree")) {
         Info("MergerMergeRecursive", "merging tree %s", obj->GetName());
         const char *obj_name= obj->GetName();

         globChain = new TChain(obj_name);
         globChain->Add(first_source->GetName());
         TFile *nextsource = (TFile*)sourcelist->After(first_source);
         while (nextsource) {
            globChain->Add(nextsource->GetName());
            nextsource = (TFile*)sourcelist->After(nextsource);
         }

      } else if (obj->IsA()->InheritsFrom("TDirectory")) {
         target->cd();
         TDirectory *newdir = target->mkdir(obj->GetName(), obj->GetTitle());
         if (!MergerMergeRecursive(newdir, sourcelist)) {
            Error("MergerMergeRecursive", "error during merge of directory %s",
                  newdir->GetPath());
            success = kFALSE;
         }
      } else {
         Error("MergerMergeRecursive", "unknown object type, name: %s title: %s",
               obj->GetName(), obj->GetTitle());
         success = kFALSE;
      }

      if (obj) {
         target->cd();

         if (obj->IsA()->InheritsFrom("TTree")) {
            globChain->Merge(target->GetFile() ,0, "keep");
            delete globChain;
         } else
            obj->Write(key->GetName());
      }

   }  // nextkey

   target->Write();

   TH1::AddDirectory(kTRUE);

   return success;
}
<commit_msg>Fix compile problem on MacOS X.<commit_after>// @(#)root/net:$Name:  $:$Id: TGrid.cxx,v 1.9 2005/05/20 09:59:35 rdm Exp $
// Author: Fons Rademakers   3/1/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGrid                                                                //
//                                                                      //
// Abstract base class defining interface to common GRID services.      //
//                                                                      //
// To open a connection to a GRID use the static method Connect().      //
// The argument of Connect() is of the form:                            //
//    <grid>[://<host>][:<port>], e.g.                                  //
// alien, alien://alice.cern.ch, globus://glsvr1.cern.ch, ...           //
// Depending on the <grid> specified an appropriate plugin library      //
// will be loaded which will provide the real interface.                //
//                                                                      //
// Related classes are TGridResult.                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGrid.h"
#include "TUrl.h"
#include "TROOT.h"
#include "TPluginManager.h"
#include "TFile.h"
#include "TList.h"
#include "TError.h"
#include "TUUID.h"
#include "TSystem.h"
#include "TH1.h"
#include "TChain.h"
#include "TKey.h"

TGrid *gGrid = 0;

ClassImp(TGrid)

//______________________________________________________________________________
TGrid::TGrid() : fPort(-1), fMergerOutputFile(0)
{
   // Create grid interface object.

   fMergerFileList = new TList;
   fMergerFileList->SetOwner(kTRUE);
}

//______________________________________________________________________________
TGrid *TGrid::Connect(const char *grid, const char *uid, const char *pw,
                      const char *options)
{
   // The grid should be of the form:  <grid>://<host>[:<port>],
   // e.g.:  alien://alice.cern.ch, globus://glsrv1.cern.ch, ...
   // The uid is the username and pw the password that should be used for
   // the connection. Depending on the <grid> the shared library (plugin)
   // for the selected system will be loaded. When the connection could not
   // be opened 0 is returned. For AliEn the supported options are:
   // -domain=<domain name>
   // -debug=<debug level from 1 to 10>
   // Example: "-domain=cern.ch -debug=5"

   TPluginHandler *h;
   TGrid *g = 0;

   if (!grid) {
      ::Error("TGrid::Connect", "no grid specified");
      return 0;
   }
   if (!uid)
      uid = "";
   if (!pw)
      pw = "";
   if (!options)
      options = "";

   if ((h = gROOT->GetPluginManager()->FindHandler("TGrid", grid))) {
      if (h->LoadPlugin() == -1)
         return 0;
      g = (TGrid *) h->ExecPlugin(4, grid, uid, pw, options);
   }

   return g;
}

//______________________________________________________________________________
TGrid::~TGrid()
{
   // Cleanup.

  if (fMergerFileList)
    delete fMergerFileList;

  if (fMergerOutputFile)
    delete fMergerOutputFile;
}

//______________________________________________________________________________
void TGrid::PrintProgress(Long64_t bytesread, Long64_t size)
{
   // Print file copy progress.

   fprintf(stderr, "[TGrid::Cp] Total %.02f MB\t|", (Double_t)size/1048576);
   for (int l = 0; l < 20; l++) {
      if (l < 20*bytesread/size)
         fprintf(stderr, "=");
      if (l == 20*bytesread/size)
         fprintf(stderr, ">");
      if (l > 20*bytesread/size)
         fprintf(stderr, ".");
   }

   fWatch.Stop();
   Double_t lCopy_time = fWatch.RealTime();
   fprintf(stderr, "| %.02f %% [%.01f MB/s]\r",
          100.0*bytesread/size, bytesread/lCopy_time/1048576.);
   fWatch.Continue();
}

//______________________________________________________________________________
Bool_t TGrid::Cp(const char *src, const char *dst, Bool_t progressbar,
                 UInt_t buffersize)
{
   // Allows to copy file from src to dst URL.

   Bool_t success = kFALSE;

   TUrl sURL(src, kTRUE);
   TUrl dURL(dst, kTRUE);

   char *copybuffer = 0;

   TFile *sfile = 0;
   TFile *dfile = 0;

   sfile = TFile::Open(src, "-READ");

   if (!sfile) {
      Error("Cp", "cannot open source file %s", src);
      goto copyout;
   }

   dfile = TFile::Open(dst, "-RECREATE");

   if (!dfile) {
      Error("Cp", "cannot open destination file %s", dst);
      goto copyout;
   }

   sfile->Seek(0);
   dfile->Seek(0);

   copybuffer = new char[buffersize];
   if (!copybuffer) {
      Error("Cp", "cannot allocate the copy buffer");
      goto copyout;
   }

   Bool_t   readop;
   Bool_t   writeop;
   Long64_t read;
   Long64_t written;
   Long64_t totalread;
   Long64_t filesize;
   Long64_t b00;
   filesize  = sfile->GetSize();
   totalread = 0;
   fWatch.Start();

   b00 = (Long64_t)sfile->GetBytesRead();

   do {
      if (progressbar) PrintProgress(totalread, filesize);

      Long64_t b1 = (Long64_t)sfile->GetBytesRead() - b00;

      Long64_t readsize;
      if (filesize - b1 > (Long64_t)buffersize) {
         readsize = buffersize;
      } else {
         readsize = filesize - b1;
      }

      Long64_t b0 = (Long64_t)sfile->GetBytesRead();
      readop = sfile->ReadBuffer(copybuffer, readsize);
      read   = (Long64_t)sfile->GetBytesRead() - b0;
      if (read < 0) {
         Error("Cp", "cannot read from source file %s", src);
         goto copyout;
      }

      Long64_t w0 = (Long64_t)dfile->GetBytesWritten();
      writeop = dfile->WriteBuffer(copybuffer, read);
      written = (Long64_t)dfile->GetBytesWritten() - w0;
      if (written != read) {
         Error("Cp", "cannot write %d bytes to destination file %s", read, dst);
         goto copyout;
      }
      totalread += read;
   } while (read == (Long64_t)buffersize);

   if (progressbar) {
      PrintProgress(totalread, filesize);
      fprintf(stderr, "\n");
   }

   success = kTRUE;

copyout:
   if (sfile) sfile->Close();
   if (dfile) dfile->Close();

   if (sfile) delete sfile;
   if (dfile) delete dfile;
   if (copybuffer) delete copybuffer;

   fWatch.Stop();
   fWatch.Reset();

   return success;
}

//______________________________________________________________________________
void TGrid::MergerReset()
{
   // Reset merger file list.

   fMergerFileList->Clear();
}

//______________________________________________________________________________
Bool_t TGrid::MergerAddFile(const char *url)
{
   // Add file to file merger.

   TUUID uuid;
   TString localcopy = "file:/tmp/";
   localcopy += "ROOTMERGE-";
   localcopy += uuid.AsString();
   localcopy += ".root";

   if (!Cp(url, localcopy)) {
      Error("MergerAddFile", "cannot get a local copy of file %s", url);
      return kFALSE;
   }

   TFile *newfile = TFile::Open(localcopy, "READ");
   if (!newfile) {
      Error("MergerAddFile", "cannot open local copy %s of URL %s",
            localcopy.Data(), url);
      return kFALSE;
   } else {
      fMergerFileList->Add(newfile);
      return  kTRUE;
   }
}

//______________________________________________________________________________
Bool_t TGrid::MergerOutputFile(const char *outputfile)
{
   // Open merger output file.

   if (fMergerOutputFile)
      delete fMergerOutputFile;

   fMergerOutputFilename = outputfile;

   TUUID uuid;
   TString localcopy = "file:/tmp/";
   localcopy += "ROOTMERGED-";
   localcopy += uuid.AsString();
   localcopy += ".root";

   fMergerOutputFile = TFile::Open(localcopy, "RECREATE");
   fMergerOutputFilename1 = localcopy;

   if (!fMergerOutputFile) {
      Error("MergerOutputFile", "cannot open the MERGER outputfile %s", localcopy.Data());
      return kFALSE;
   }
   return kTRUE;
}

//______________________________________________________________________________
void TGrid::MergerPrintFiles(Option_t *options)
{
   // Print list of files being merged.

   fMergerFileList->Print(options);
}

//______________________________________________________________________________
Bool_t TGrid::MergerMerge()
{
   // Merge the files.

   if (!fMergerOutputFile) {
      Info("MergerMerge", "will merge the results to the file "
           "GridMergerMerged.root in your working directory, "
           "since you didn't specify a merge filename");
      if (!MergerOutputFile("GridMergerMerged.root")) {
         return kFALSE;
      }
   }

   Bool_t result = MergerMergeRecursive(fMergerOutputFile, fMergerFileList);
   if (!result) {
      Error("MergerMerge", "error during merge of your ROOT files");
   } else {
      fMergerOutputFile->Write();
      // copy the result file to the final destination
      Cp(fMergerOutputFilename1, fMergerOutputFilename);
   }

   // remove the temporary result file
   TString path(fMergerOutputFile->GetPath());
   path = path(0, path.Index(':',0));
   gSystem->Unlink(path);
   fMergerOutputFile = 0;

   TIter next(fMergerFileList);
   TFile *file;
   while ((file = (TFile*) next())) {
      // close the files
      file->Close();
      // remove the temporary files
      TString path(file->GetPath());
      path = path(0, path.Index(':',0));
      gSystem->Unlink(path);
   }
   return result;
}

//______________________________________________________________________________
Bool_t TGrid::MergerMergeRecursive(TDirectory *target, TList *sourcelist)
{
   // Recursively merge objects in the ROOT files.

   TString path(strstr(target->GetPath(), ":"));
   path.Remove(0, 2);

   TFile *first_source = (TFile*)sourcelist->First();
   first_source->cd(path);
   TDirectory *current_sourcedir = gDirectory;

   TChain *globChain = 0;
   TIter nextkey(current_sourcedir->GetListOfKeys());
   TKey *key;
   Bool_t success = kTRUE;

   // gain time, do not add the objects in the list in memory
   TH1::AddDirectory(kFALSE);

   while ((key = (TKey*) nextkey())) {
      first_source->cd(path);
      TObject *obj = key->ReadObj();

      if (obj->IsA()->InheritsFrom("TH1")) {
         Info("MergerMergeRecursive", "merging histogram %s", obj->GetName());
         TH1 *h1 = (TH1*)obj;

         TFile *nextsource = (TFile*)sourcelist->After(first_source);
         while (nextsource) {

            nextsource->cd(path);
            TH1 *h2 = (TH1*)gDirectory->Get(h1->GetName());
            if (h2) {
               h1->Add(h2);
               delete h2;
            }

            nextsource = (TFile*)sourcelist->After(nextsource);
         }
      } else if (obj->IsA()->InheritsFrom("TTree")) {
         Info("MergerMergeRecursive", "merging tree %s", obj->GetName());
         const char *obj_name= obj->GetName();

         globChain = new TChain(obj_name);
         globChain->Add(first_source->GetName());
         TFile *nextsource = (TFile*)sourcelist->After(first_source);
         while (nextsource) {
            globChain->Add(nextsource->GetName());
            nextsource = (TFile*)sourcelist->After(nextsource);
         }

      } else if (obj->IsA()->InheritsFrom("TDirectory")) {
         target->cd();
         TDirectory *newdir = target->mkdir(obj->GetName(), obj->GetTitle());
         if (!MergerMergeRecursive(newdir, sourcelist)) {
            Error("MergerMergeRecursive", "error during merge of directory %s",
                  newdir->GetPath());
            success = kFALSE;
         }
      } else {
         Error("MergerMergeRecursive", "unknown object type, name: %s title: %s",
               obj->GetName(), obj->GetTitle());
         success = kFALSE;
      }

      if (obj) {
         target->cd();

         if (obj->IsA()->InheritsFrom("TTree")) {
            globChain->Merge(target->GetFile() ,0, "keep");
            delete globChain;
         } else
            obj->Write(key->GetName());
      }

   }  // nextkey

   target->Write();

   TH1::AddDirectory(kTRUE);

   return success;
}
<|endoftext|>


<commit_before><commit_msg>improved VCOM Toggle<commit_after><|endoftext|>


<commit_before><commit_msg>WaE: possible loss of data<commit_after><|endoftext|>


<commit_before>#ifndef __RANK_FILTER__
#define __RANK_FILTER__

#include <deque>
#include <cassert>
#include <functional>
#include <iostream>
#include <iterator>

#include <boost/array.hpp>
#include <boost/container/set.hpp>
#include <boost/container/node_allocator.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

namespace rank_filter
{

template<class I1,
         class I2>
inline void lineRankOrderFilter1D(const I1& src_begin, const I1& src_end,
        I2& dest_begin, I2& dest_end,
        size_t half_length, double rank)
{
    // Types in use.
    typedef typename std::iterator_traits<I1>::value_type T1;
    typedef typename std::iterator_traits<I2>::value_type T2;
    typedef typename std::iterator_traits<I1>::difference_type I1_diff_t;
    typedef typename std::iterator_traits<I2>::difference_type I2_diff_t;

    // Establish common types to work with source and destination values.
    BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
    typedef T1 T;
    typedef typename boost::common_type<I1_diff_t, I2_diff_t>::type I_diff_t;

    // Define container types that will be used.
    typedef boost::container::multiset< T,
            std::less<T>,
            boost::container::node_allocator<T>,
            boost::container::tree_assoc_options< boost::container::tree_type<boost::container::scapegoat_tree> >::type> multiset;
    typedef std::deque< typename multiset::iterator > deque;

    // Lengths.
    const I_diff_t src_size = std::distance(src_begin, src_end);
    const I_diff_t dest_size = std::distance(dest_begin, dest_end);

    // Ensure the result will fit.
    assert(src_size <= dest_size);

    // Window length cannot exceed input data with reflection.
    assert((half_length + 1) <= src_size);

    // Rank must be in the range 0 to 1.
    assert((0 <= rank) && (rank <= 1));

    // The position of the window.
    I_diff_t window_begin = 0;

    // Find window offset corresponding to this rank.
    const I_diff_t rank_pos = static_cast<I_diff_t>(boost::math::round(rank * (2 * half_length)));

    multiset sorted_window;
    deque window_iters(2 * half_length + 1);

    // Get the initial sorted window.
    // Include the reflection.
    for (I_diff_t j = 0; j < half_length; j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + half_length - j]);
    }
    for (I_diff_t j = half_length; j < (2 * half_length + 1); j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + j - half_length]);
    }

    typename multiset::iterator rank_point = sorted_window.begin();

    for (I_diff_t i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename multiset::iterator prev_iter;
    T prev_value;
    T next_value;
    while ( window_begin < src_size )
    {
        dest_begin[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin == src_size )
        {
            next_value = prev_value;
        }
        else if ( window_begin < (src_size - half_length) )
        {
            next_value = src_begin[window_begin + half_length];
        }
        else
        {
            next_value = *(window_iters[(2 * (src_size - (window_begin + 1)))]);
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

}

namespace std
{
    template <class T, size_t N>
    ostream& operator<<(ostream& out, const boost::array<T, N>& that)
    {
        out << "{ ";
        for (unsigned int i = 0; i < (N - 1); i++)
        {
            out << that[i] << ", ";
        }
        out << that[N - 1] << " }";

        return(out);
    }
}

#endif //__RANK_FILTER__
<commit_msg>Explain purpose of multiset and deque<commit_after>#ifndef __RANK_FILTER__
#define __RANK_FILTER__

#include <deque>
#include <cassert>
#include <functional>
#include <iostream>
#include <iterator>

#include <boost/array.hpp>
#include <boost/container/set.hpp>
#include <boost/container/node_allocator.hpp>
#include <boost/math/special_functions/round.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>

namespace rank_filter
{

template<class I1,
         class I2>
inline void lineRankOrderFilter1D(const I1& src_begin, const I1& src_end,
        I2& dest_begin, I2& dest_end,
        size_t half_length, double rank)
{
    // Types in use.
    typedef typename std::iterator_traits<I1>::value_type T1;
    typedef typename std::iterator_traits<I2>::value_type T2;
    typedef typename std::iterator_traits<I1>::difference_type I1_diff_t;
    typedef typename std::iterator_traits<I2>::difference_type I2_diff_t;

    // Establish common types to work with source and destination values.
    BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
    typedef T1 T;
    typedef typename boost::common_type<I1_diff_t, I2_diff_t>::type I_diff_t;

    // Define container types that will be used.
    typedef boost::container::multiset< T,
            std::less<T>,
            boost::container::node_allocator<T>,
            boost::container::tree_assoc_options< boost::container::tree_type<boost::container::scapegoat_tree> >::type> multiset;
    typedef std::deque< typename multiset::iterator > deque;

    // Lengths.
    const I_diff_t src_size = std::distance(src_begin, src_end);
    const I_diff_t dest_size = std::distance(dest_begin, dest_end);

    // Ensure the result will fit.
    assert(src_size <= dest_size);

    // Window length cannot exceed input data with reflection.
    assert((half_length + 1) <= src_size);

    // Rank must be in the range 0 to 1.
    assert((0 <= rank) && (rank <= 1));

    // The position of the window.
    I_diff_t window_begin = 0;

    // Find window offset corresponding to this rank.
    const I_diff_t rank_pos = static_cast<I_diff_t>(boost::math::round(rank * (2 * half_length)));

    // Track values in window both in sorted and sequential order.
    multiset sorted_window;
    deque window_iters(2 * half_length + 1);

    // Get the initial sorted window.
    // Include the reflection.
    for (I_diff_t j = 0; j < half_length; j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + half_length - j]);
    }
    for (I_diff_t j = half_length; j < (2 * half_length + 1); j++)
    {
        window_iters[j] = sorted_window.insert(src_begin[window_begin + j - half_length]);
    }

    typename multiset::iterator rank_point = sorted_window.begin();

    for (I_diff_t i = 0; i < rank_pos; i++)
    {
        rank_point++;
    }

    typename multiset::iterator prev_iter;
    T prev_value;
    T next_value;
    while ( window_begin < src_size )
    {
        dest_begin[window_begin] = *rank_point;

        prev_iter = window_iters.front();
        prev_value = *prev_iter;
        window_iters.pop_front();

        window_begin++;

        if ( window_begin == src_size )
        {
            next_value = prev_value;
        }
        else if ( window_begin < (src_size - half_length) )
        {
            next_value = src_begin[window_begin + half_length];
        }
        else
        {
            next_value = *(window_iters[(2 * (src_size - (window_begin + 1)))]);
        }

        if ( ( *rank_point < prev_value ) && ( *rank_point <= next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point > next_value ) )
        {
            if ( rank_point == prev_iter )
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point--;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));
            }
        }
        else if ( ( *rank_point < prev_value ) && ( *rank_point > next_value ) )
        {
            sorted_window.erase(prev_iter);
            window_iters.push_back(sorted_window.insert(next_value));

            rank_point--;
        }
        else if ( ( *rank_point >= prev_value ) && ( *rank_point <= next_value ) )
        {
            if (rank_point == prev_iter)
            {
                window_iters.push_back(sorted_window.insert(next_value));
                rank_point++;

                sorted_window.erase(prev_iter);
            }
            else
            {
                sorted_window.erase(prev_iter);
                window_iters.push_back(sorted_window.insert(next_value));

                rank_point++;
            }
        }
    }
}

}

namespace std
{
    template <class T, size_t N>
    ostream& operator<<(ostream& out, const boost::array<T, N>& that)
    {
        out << "{ ";
        for (unsigned int i = 0; i < (N - 1); i++)
        {
            out << that[i] << ", ";
        }
        out << that[N - 1] << " }";

        return(out);
    }
}

#endif //__RANK_FILTER__
<|endoftext|>


<commit_before>/*
 * Copyright 2016 C. Brett Witherspoon
 *
 * This file is part of the signum library
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef SIGNUM_PIPE_HPP_
#define SIGNUM_PIPE_HPP_

#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

namespace signum
{

class pipe
{
public:
    pipe(const std::string &name)
    {
        // Try to open pipe (blocks until other end appears) or create it
        m_fd = open(name.c_str(), O_WRONLY);
        if (m_fd == -1)
        {
            if (mkfifo(name.c_str(), 0666) == -1)
                throw std::runtime_error("Unable to create named pipe: " + name);

            m_fd = open(name.c_str(), O_WRONLY);
            if (m_fd == -1)
                throw std::runtime_error("Unable to open named pipe: " + name);
        }
    }

    pipe(const pipe&) = delete;

    ~pipe()
    {
        close(m_fd);
    }

    pipe &operator=(const pipe&) = delete;

    bool operator==(const pipe &rhs) const { return m_fd == rhs.m_fd; }

    bool operator!=(const pipe &rhs) const { return !operator==(rhs); }

    operator int() const { return m_fd; }

    template<typename T>
    size_t write(T *data, size_t size)
    {
        ssize_t n = ::write(m_fd, data, size * sizeof(T));
        if (n == -1)
            throw std::runtime_error("Unable to write to named pipe");
        return n;
    }

private:
    int m_fd;
};

} // end namespace signum

#endif /* SIGNUM_PIPE_HPP_ */
<commit_msg>pipe: add unlink method<commit_after>/*
 * Copyright 2016 C. Brett Witherspoon
 *
 * This file is part of the signum library
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef SIGNUM_PIPE_HPP_
#define SIGNUM_PIPE_HPP_

#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

namespace signum
{

class pipe
{
public:
    pipe(const std::string &name)
        : m_name(name)
    {
        // Try to open pipe (blocks until other end appears) or create it
        m_fd = open(name.c_str(), O_WRONLY);
        if (m_fd == -1)
        {
            if (mkfifo(name.c_str(), 0666) == -1)
                throw std::runtime_error("Unable to create named pipe: " + name);

            m_fd = open(name.c_str(), O_WRONLY);
            if (m_fd == -1)
                throw std::runtime_error("Unable to open named pipe: " + name);
        }
    }

    pipe(const pipe&) = delete;

    ~pipe()
    {
        unlink();
        close(m_fd);
    }

    pipe &operator=(const pipe&) = delete;

    bool operator==(const pipe &rhs) const { return m_fd == rhs.m_fd; }

    bool operator!=(const pipe &rhs) const { return !operator==(rhs); }

    operator int() const { return m_fd; }

    std::string name() const { return m_name; }

    void unlink() { ::unlink(m_name.c_str()); }

    template<typename T>
    size_t write(T *data, size_t size)
    {
        ssize_t n = ::write(m_fd, data, size * sizeof(T));
        if (n == -1)
            throw std::runtime_error("Unable to write to named pipe");
        return n;
    }

private:
    const std::string m_name;
    int m_fd;
};

} // end namespace signum

#endif /* SIGNUM_PIPE_HPP_ */
<|endoftext|>


<commit_before>/*
 * Copyright 2016 C. Brett Witherspoon
 *
 * This file is part of the signum library
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef SIGNUM_PIPE_HPP_
#define SIGNUM_PIPE_HPP_

#include <stdexcept>
#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

namespace signum
{

class pipe
{
public:
    pipe()
        : m_name(), m_fd(-1)
    {
    }

    explicit pipe(const std::string &name, mode_t mode = 0660)
        : m_name(name)
    {
        // Try to open pipe (blocks until other end appears) or create it
        m_fd = open(name.c_str(), O_WRONLY);
        if (m_fd == -1)
        {
            if (mkfifo(name.c_str(), mode) == -1)
                throw std::runtime_error("Unable to create named pipe: " + name);

            m_fd = open(name.c_str(), O_WRONLY);
            if (m_fd == -1)
                throw std::runtime_error("Unable to open named pipe: " + name);
        }
    }

    pipe(const pipe&) = delete;

    pipe(pipe &&other)
        : m_name(other.m_name),
          m_fd(other.m_fd)
    {
        other.m_fd = -1;
        other.m_name = "";
    }

    ~pipe()
    {
        unlink();
        close(m_fd);
    }

    pipe &operator=(const pipe&) = delete;

    pipe &operator=(pipe &&other)
    {
        m_name = other.m_name;
        other.m_name = "";

        m_fd = other.m_fd;
        other.m_fd = -1;

        return *this;
    }

    bool operator==(const pipe &rhs) const { return m_fd == rhs.m_fd; }

    bool operator!=(const pipe &rhs) const { return !operator==(rhs); }

    operator int() const { return m_fd; }

    std::string name() const { return m_name; }

    void unlink() { ::unlink(m_name.c_str()); }

    template<typename T>
    size_t write(T *data, size_t size)
    {
        ssize_t n = ::write(m_fd, data, size * sizeof(T));
        if (n == -1)
            throw std::runtime_error("Unable to write to named pipe");
        return n;
    }

private:
    std::string m_name;
    int m_fd;
};

} // end namespace signum

#endif /* SIGNUM_PIPE_HPP_ */
<commit_msg>pipe: use system error exception<commit_after>/*
 * Copyright 2016 C. Brett Witherspoon
 *
 * This file is part of the signum library
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef SIGNUM_PIPE_HPP_
#define SIGNUM_PIPE_HPP_

#include <system_error>
#include <string>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

namespace signum
{

class pipe
{
public:
    pipe()
        : m_name(), m_fd(-1)
    {
    }

    explicit pipe(const std::string &name, mode_t mode = 0660)
        : m_name(name)
    {
        // Try to open pipe (blocks until other end appears) or create it
        m_fd = open(name.c_str(), O_WRONLY);
        if (m_fd == -1)
        {
            if (errno == EACCES)
                throw std::system_error(EACCES, std::system_category());

            if (mkfifo(name.c_str(), mode) == -1)
                throw std::system_error(errno, std::system_category());

            m_fd = open(name.c_str(), O_WRONLY);
            if (m_fd == -1)
                throw std::system_error(errno, std::system_category());
        }
    }

    pipe(const pipe&) = delete;

    pipe(pipe &&other)
        : m_name(other.m_name),
          m_fd(other.m_fd)
    {
        other.m_fd = -1;
        other.m_name = "";
    }

    ~pipe()
    {
        unlink();
        close(m_fd);
    }

    pipe &operator=(const pipe&) = delete;

    pipe &operator=(pipe &&other)
    {
        m_name = other.m_name;
        other.m_name = "";

        m_fd = other.m_fd;
        other.m_fd = -1;

        return *this;
    }

    bool operator==(const pipe &rhs) const { return m_fd == rhs.m_fd; }

    bool operator!=(const pipe &rhs) const { return !operator==(rhs); }

    operator int() const { return m_fd; }

    std::string name() const { return m_name; }

    void unlink() { ::unlink(m_name.c_str()); }

    template<typename T>
    size_t write(T *data, size_t size)
    {
        ssize_t n = ::write(m_fd, data, size * sizeof(T));
        if (n == -1)
            throw std::system_error(errno, std::system_category());
        return n;
    }

private:
    std::string m_name;
    int m_fd;
};

} // end namespace signum

#endif /* SIGNUM_PIPE_HPP_ */
<|endoftext|>


<commit_before>//
//  linked_list.hpp
//  DS
//
//  Created by Rahul Goel on 7/26/17.
//  Copyright © 2017 Rahul Goel. All rights reserved.
//

#ifndef linked_list_hpp
#define linked_list_hpp

#include <stdio.h>
#include <stdlib.h>

//To create a test Single Linked List with four nodes in it
struct list_node* linkedlist_testcreate();

//To print all the elements in given single lineked list - O(n) Time
void linkedlist_print(struct list_node *base);

//To count the number of nodes in given single linked list - O(n) Time
int linkedlist_countnodes(struct list_node *base);

//To insert a node on given position pos
int linkedlist_insert(struct list_node *base,int pos,int data);

//To delete a node from given position pos
void linkedlist_delete(struct list_node *base, int pos);

//To check if given linked list has cycle or not
int linkedlist_checkIfCycle(struct list_node *base);

//Reverse of given linked list
struct list_node*  linkedlist_reverse(struct list_node *base);

#endif /* linked_list_hpp */
<commit_msg>linkedlist<commit_after>//
//  linked_list.hpp
//  DS
//
//  Created by Rahul Goel on 7/26/17.
//  Copyright © 2017 Rahul Goel. All rights reserved.
//

#ifndef linked_list_hpp
#define linked_list_hpp

#include <stdio.h>
#include <stdlib.h>

//1. To create a test Single Linked List with four nodes in it
struct list_node* linkedlist_testcreate();

//2. To print all the elements in given single lineked list - O(n) Time
void linkedlist_print(struct list_node *base);

//3. To count the number of nodes in given single linked list - O(n) Time
int linkedlist_countnodes(struct list_node *base);

//4. To insert a node on given position pos
int linkedlist_insert(struct list_node *base,int pos,int data);

//5. To delete a node from given position pos
void linkedlist_delete(struct list_node *base, int pos);

//6. To check if given linked list has cycle or not
int linkedlist_checkIfCycle(struct list_node *base);

//7. Reverse of given linked list
struct list_node*  linkedlist_reverse(struct list_node *base);

//8. Search given element in Linked List
bool linkedlist_searchElement(struct list_node *base, int number);

//9. Swap two nodes in linked list, without swapping data but with address as Swapping data of nodes may be expensive in many situations when data contains many fields
void linkedlist_swapTwoNodes(struct list_node *base, int val1, int val2);

//10. Get data in nth node from given linked list
int linkedlist_getNthNode(struct list_node *base,int n);

//11. Find middle of given linked list
int linkedlist_middleIs(struct list_node *base);

#endif /* linked_list_hpp */
<|endoftext|>


<commit_before>/* Copyright 2016 Hewlett Packard Enterprise Development LP

 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
 the specific language governing permissions and limitations under the License.*/

// #include <cxxabi.h>
#include "dynamiclibop.h"
#include <dlfcn.h>
#include <string>
#include <memory>
#include <typeinfo>
#include <vector>
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/device_base.h"
#include "threadpool.h"

#if GOOGLE_CUDA

// this must be defined for the include file below to actually include anything
#define EIGEN_USE_GPU
#include <cuda.h>
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#endif  // GOOGLE_CUDA

namespace tensorflow {

// Define the operator interface: inputs, outputs and parameters
// inputs and outputs are a list of tensors that can be either floats or doubles
// and all input tensors do not need to be the same type
REGISTER_OP("DynamicLib")
    .Attr("gpu_func_name: string")
    .Attr("gpu_lib_path: string")
    .Attr("cpu_func_name: string")
    .Attr("cpu_lib_path: string")
    .Attr("serialized_grad_dag: string")
    .Attr("cuda_threads_per_block: int")
    .Attr("out_shapes: list(shape)")
    .Attr("in_types: list({float, double}) >= 0")
    .Attr("out_types: list({float, double})")
    .Input("inputs: in_types")
    .Output("outputs: out_types")
    .Doc(R"doc(call a dynamically generated library operation)doc");

typedef Eigen::ThreadPoolDevice CPUDevice;
typedef Eigen::GpuDevice GPUDevice;

// static std::string getDebugString(
//        const std::vector<std::shared_ptr<const InputParameter>> parameters) {
//    std::string str;
//    int     status;
//    char   *paramType;
//    for (uint32_t i = 0; i < parameters.size(); i++) {
//        const std::type_info  &ti = typeid(*(parameters[i]));
//        paramType = abi::__cxa_demangle(ti.name(), 0, 0, &status);
//        str.append(paramType + std::string(": ") +
//                   std::to_string(parameters[i]->length()) + ", ");
//    }
//    return str;
// }

// Class which will dynamically load and launch the generated operators
// on either CPU or GPU
template <typename Device>
class DynamicLibLaunch;

// Partial specialization for CPU
template <>
class DynamicLibLaunch<CPUDevice>  {
 public:
    typedef uint16_t
        (*FUNPTR)(std::vector<std::shared_ptr<const InputParameter>> inputs,
                  std::vector<std::shared_ptr<OutputParameter>> outputs,
                  int num_threads, int thread_idx, uint16_t *err);
    DynamicLibLaunch(OpKernelConstruction* context,
                     const string& cpu_func_name, const string& cpu_lib_path,
                     const string&, const string&,
                     const int ) {
        LOG(INFO) << "*** Standalone DynamicLibLaunch on CPU *****";

        // load the compiled op shared library
        static_assert(sizeof(void *) == sizeof(void (*)(void)),
                      "object pointer and function pointer sizes must equal");
        void *handle = dlopen(cpu_lib_path.c_str(), RTLD_LAZY);
        OP_REQUIRES(context, handle != nullptr,
            errors::NotFound("Unable to find DynamicLib library "
                             + cpu_lib_path));

        // load the function and cast it from void* to a function pointer
        void *f = dlsym(handle, cpu_func_name.c_str());
        func_ = reinterpret_cast<FUNPTR>(f);
        OP_REQUIRES(context, func_ != nullptr,
            errors::NotFound("Unable to find DynamicLib function "
                             + cpu_func_name));
    }

    void Run(OpKernelContext* context, const CPUDevice&,
             std::vector<std::shared_ptr<const InputParameter>> inputs,
             std::vector<std::shared_ptr<OutputParameter>> outputs) {
        const int num_threads = context->device()->tensorflow_cpu_worker_threads()->workers->NumThreads();
        thread::ThreadPool thread_pool(Env::Default(), "dynamiclibop", num_threads);
        uint16_t err = 0;
        for (int thread = 0; thread < num_threads; thread++) {
            auto fn_work = std::bind(func_, inputs, outputs, num_threads, thread, &err);
            thread_pool.Schedule(fn_work);
        }
        OP_REQUIRES(context, err == 0,
            errors::InvalidArgument("External function execution error code: ",
                                    err));
    }

 private:
    FUNPTR func_;
};

#if GOOGLE_CUDA
// Partial specialization for GPU
template <>
class DynamicLibLaunch<GPUDevice>  {
 public:
    typedef uint16_t
        (*FUNPTR)(std::vector<std::shared_ptr<const InputParameter>> inputs,
                  std::vector<std::shared_ptr<OutputParameter>> outputs,
                  CUstream stream,
                  int cuda_threads_per_block);
    DynamicLibLaunch(OpKernelConstruction* context,
                     const string&, const string&,
                     const string& gpu_func_name, const string& gpu_lib_path,
                     const int cuda_threads_per_block) {
        LOG(INFO) << "*** Standalone DynamicLibLaunch on GPU *****";

        // load the compiled op shared library
        static_assert(sizeof(void *) == sizeof(void (*)(void)),
                  "object pointer and function pointer sizes must equal");
        void *handle = dlopen(gpu_lib_path.c_str(), RTLD_LAZY);
        OP_REQUIRES(context, handle != nullptr,
            errors::NotFound("Unable to find DynamicLib library "
                             + gpu_lib_path));

        // load the function and cast it from void* to a function pointer
        void *f = dlsym(handle, gpu_func_name.c_str());
        func_ = reinterpret_cast<FUNPTR>(f);
        OP_REQUIRES(context, func_ != nullptr,
            errors::NotFound("Unable to find DynamicLib function "
                             + gpu_func_name));

        cuda_threads_per_block_ = cuda_threads_per_block;
    }

    void Run(OpKernelContext* context, const GPUDevice& d,
             std::vector<std::shared_ptr<const InputParameter>> inputs,
             std::vector<std::shared_ptr<OutputParameter>> outputs) {
        // call the DynamicLib library functions
        uint16_t err = func_(inputs, outputs, d.stream(),
                             cuda_threads_per_block_);
        OP_REQUIRES(context, err == 0,
            errors::InvalidArgument("External function execution error code: ",
                                    err));
    }

 private:
    FUNPTR func_;
    int cuda_threads_per_block_;
};
#endif  // GOOGLE_CUDA

// General purpose tensorflow user operator class
// that allows us to run operators  generated and compiled independently
// by the Operator Vectorization Library.
// Parameters are a list of input tensors, list of output shapes, list of
// output types, the location of the DynamicLib shared libraries and the name
// of the DynamicLib operator.
// See tensorflow/python/kernel_tests/dynamic_lib_op_test.py for example usage
template <typename Device>
class DynamicLibOp : public OpKernel {
 public:
  explicit DynamicLibOp(OpKernelConstruction* context) : OpKernel(context) {
    // store the passed in parameters
    OP_REQUIRES_OK(context, context->GetAttr("cpu_func_name", &cpu_func_name_));
    OP_REQUIRES_OK(context, context->GetAttr("cpu_lib_path", &cpu_lib_path_));
    OP_REQUIRES_OK(context, context->GetAttr("gpu_func_name", &gpu_func_name_));
    OP_REQUIRES_OK(context, context->GetAttr("gpu_lib_path", &gpu_lib_path_));
    OP_REQUIRES_OK(context, context->GetAttr("cuda_threads_per_block",
                                             &cuda_threads_per_block_));
    OP_REQUIRES_OK(context, context->GetAttr("out_types", &out_types_));
    OP_REQUIRES_OK(context, context->GetAttr("out_shapes", &out_shapes_));

    launcher_ = std::unique_ptr<DynamicLibLaunch<Device>>(
                new DynamicLibLaunch<Device>(context, cpu_func_name_,
                                             cpu_lib_path_, gpu_func_name_,
                                             gpu_lib_path_,
                                             cuda_threads_per_block_));
  }

  // Function that is called when the output tensors of the operator
  // are evaluated
  void Compute(OpKernelContext* context) override {
//      LOG(INFO) << "*** computing DynamicLibOp ***";

      // Build the tensor input parameter list
      OpInputList input_list;
      context->input_list("inputs", &input_list);
      std::vector<std::shared_ptr<const InputParameter>> inputs;
      inputs.reserve(input_list.size());
      for (int32_t i = 0; i < input_list.size(); ++i) {
          const Tensor& cur_input = input_list[i];
          switch (cur_input.dtype()) {
            case (DT_FLOAT):
              inputs.emplace_back(
                     new TypedInput<float>(cur_input.flat<float>().data(),
                                           cur_input.NumElements()));
              break;
            case (DT_DOUBLE):
              inputs.emplace_back(
                     new TypedInput<double>(cur_input.flat<double>().data(),
                                            cur_input.NumElements()));
              break;
            default:
              OP_REQUIRES(context, false,
                          errors::InvalidArgument(
                          "Only float and double inputs are supported."));
              break;
            }
      }

      // Build the output tensor parameter list
      const uint32_t num_outputs = context->num_outputs();
      OP_REQUIRES(context, num_outputs == out_shapes_.size(),
                  errors::InvalidArgument(
                  "Output shapes inconsistent with output types"))
      OP_REQUIRES(context, num_outputs == out_types_.size(),
                  errors::InvalidArgument(
                  "Output types inconsistent num_outputs"))
      Tensor *output_tensor[num_outputs];
      std::vector<std::shared_ptr<OutputParameter>> outputs;
      outputs.reserve(num_outputs);
      for (uint32_t i = 0; i < num_outputs; ++i) {
          DataType cur_output_type = out_types_[i];
          TensorShape cur_shape = TensorShape(out_shapes_[i]);
          OP_REQUIRES_OK(context,
                         context->allocate_output(i,
                                              cur_shape, &output_tensor[i]));
          OP_REQUIRES(context, output_tensor[i]->dtype() == cur_output_type,
                       errors::InvalidArgument("Types inconsistent"))
          switch (cur_output_type) {
            case (DT_FLOAT):
                outputs.emplace_back(new TypedOutput<float>(
                               output_tensor[i]->template flat<float>().data(),
                               output_tensor[i]->NumElements()));
                break;
            case (DT_DOUBLE):
                outputs.emplace_back(new TypedOutput<double>(
                               output_tensor[i]->template flat<double>().data(),
                               output_tensor[i]->NumElements()));
                break;
            default:
                OP_REQUIRES(context, false,
                    errors::InvalidArgument(
                            "Only float and double outputs are supported."));
                break;
          }
      }

      // call the DynamicLib library function
      const Device& d = context->eigen_device<Device>();
      launcher_->Run(context, d, inputs, outputs);
  }

 private:
  string cpu_func_name_;
  string cpu_lib_path_;
  string gpu_func_name_;
  string gpu_lib_path_;
  int cuda_threads_per_block_;
  DataTypeVector out_types_;
  std::vector<TensorShapeProto> out_shapes_;
  std::unique_ptr<DynamicLibLaunch<Device>> launcher_;
};

// register the operator for each template type with tensorflow
// Note: this registration will cause the operator constructors to get called
// regardless of whether or not they are used in a tensorflow application
REGISTER_KERNEL_BUILDER(Name("DynamicLib")
    .Device(DEVICE_CPU),
    DynamicLibOp<CPUDevice>);

#if GOOGLE_CUDA
REGISTER_KERNEL_BUILDER(Name("DynamicLib")
    .Device(DEVICE_GPU),
    DynamicLibOp<GPUDevice>);
#endif  // GOOGLE_CUDA
}  // namespace tensorflow

<commit_msg>added scoping of threadpool in dynamiclibop.cc<commit_after>/* Copyright 2016 Hewlett Packard Enterprise Development LP

 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for
 the specific language governing permissions and limitations under the License.*/

// #include <cxxabi.h>
#include "dynamiclibop.h"
#include <dlfcn.h>
#include <string>
#include <memory>
#include <typeinfo>
#include <vector>
#include "tensorflow/core/platform/logging.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/device_base.h"
#include "threadpool.h"

#if GOOGLE_CUDA

// this must be defined for the include file below to actually include anything
#define EIGEN_USE_GPU
#include <cuda.h>
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
#endif  // GOOGLE_CUDA

namespace tensorflow {

// Define the operator interface: inputs, outputs and parameters
// inputs and outputs are a list of tensors that can be either floats or doubles
// and all input tensors do not need to be the same type
REGISTER_OP("DynamicLib")
    .Attr("gpu_func_name: string")
    .Attr("gpu_lib_path: string")
    .Attr("cpu_func_name: string")
    .Attr("cpu_lib_path: string")
    .Attr("serialized_grad_dag: string")
    .Attr("cuda_threads_per_block: int")
    .Attr("out_shapes: list(shape)")
    .Attr("in_types: list({float, double}) >= 0")
    .Attr("out_types: list({float, double})")
    .Input("inputs: in_types")
    .Output("outputs: out_types")
    .Doc(R"doc(call a dynamically generated library operation)doc");

typedef Eigen::ThreadPoolDevice CPUDevice;
typedef Eigen::GpuDevice GPUDevice;

// static std::string getDebugString(
//        const std::vector<std::shared_ptr<const InputParameter>> parameters) {
//    std::string str;
//    int     status;
//    char   *paramType;
//    for (uint32_t i = 0; i < parameters.size(); i++) {
//        const std::type_info  &ti = typeid(*(parameters[i]));
//        paramType = abi::__cxa_demangle(ti.name(), 0, 0, &status);
//        str.append(paramType + std::string(": ") +
//                   std::to_string(parameters[i]->length()) + ", ");
//    }
//    return str;
// }

// Class which will dynamically load and launch the generated operators
// on either CPU or GPU
template <typename Device>
class DynamicLibLaunch;

// Partial specialization for CPU
template <>
class DynamicLibLaunch<CPUDevice>  {
 public:
    typedef uint16_t
        (*FUNPTR)(std::vector<std::shared_ptr<const InputParameter>> inputs,
                  std::vector<std::shared_ptr<OutputParameter>> outputs,
                  int num_threads, int thread_idx, uint16_t *err);
    DynamicLibLaunch(OpKernelConstruction* context,
                     const string& cpu_func_name, const string& cpu_lib_path,
                     const string&, const string&,
                     const int ) {
        LOG(INFO) << "*** Standalone DynamicLibLaunch on CPU *****";

        // load the compiled op shared library
        static_assert(sizeof(void *) == sizeof(void (*)(void)),
                      "object pointer and function pointer sizes must equal");
        void *handle = dlopen(cpu_lib_path.c_str(), RTLD_LAZY);
        OP_REQUIRES(context, handle != nullptr,
            errors::NotFound("Unable to find DynamicLib library "
                             + cpu_lib_path));

        // load the function and cast it from void* to a function pointer
        void *f = dlsym(handle, cpu_func_name.c_str());
        func_ = reinterpret_cast<FUNPTR>(f);
        OP_REQUIRES(context, func_ != nullptr,
            errors::NotFound("Unable to find DynamicLib function "
                             + cpu_func_name));
    }

    void Run(OpKernelContext* context, const CPUDevice&,
             std::vector<std::shared_ptr<const InputParameter>> inputs,
             std::vector<std::shared_ptr<OutputParameter>> outputs) {
        const int num_threads = context->device()->tensorflow_cpu_worker_threads()->workers->NumThreads();
        uint16_t err = 0;
        // ThreadPool destructor is what joins all the threads and waits for completion, so we
        // scope it as a local variable and when it goes out of scope, all the work is done and result
        // can be used
        {
            thread::ThreadPool thread_pool(Env::Default(), "dynamiclibop", num_threads);
            for (int thread = 0; thread < num_threads; thread++) {
                auto fn_work = std::bind(func_, inputs, outputs, num_threads, thread, &err);
                thread_pool.Schedule(fn_work);
            }
        }
        OP_REQUIRES(context, err == 0,
            errors::InvalidArgument("External function execution error code: ",
                                    err));
    }

 private:
    FUNPTR func_;
};

#if GOOGLE_CUDA
// Partial specialization for GPU
template <>
class DynamicLibLaunch<GPUDevice>  {
 public:
    typedef uint16_t
        (*FUNPTR)(std::vector<std::shared_ptr<const InputParameter>> inputs,
                  std::vector<std::shared_ptr<OutputParameter>> outputs,
                  CUstream stream,
                  int cuda_threads_per_block);
    DynamicLibLaunch(OpKernelConstruction* context,
                     const string&, const string&,
                     const string& gpu_func_name, const string& gpu_lib_path,
                     const int cuda_threads_per_block) {
        LOG(INFO) << "*** Standalone DynamicLibLaunch on GPU *****";

        // load the compiled op shared library
        static_assert(sizeof(void *) == sizeof(void (*)(void)),
                  "object pointer and function pointer sizes must equal");
        void *handle = dlopen(gpu_lib_path.c_str(), RTLD_LAZY);
        OP_REQUIRES(context, handle != nullptr,
            errors::NotFound("Unable to find DynamicLib library "
                             + gpu_lib_path));

        // load the function and cast it from void* to a function pointer
        void *f = dlsym(handle, gpu_func_name.c_str());
        func_ = reinterpret_cast<FUNPTR>(f);
        OP_REQUIRES(context, func_ != nullptr,
            errors::NotFound("Unable to find DynamicLib function "
                             + gpu_func_name));

        cuda_threads_per_block_ = cuda_threads_per_block;
    }

    void Run(OpKernelContext* context, const GPUDevice& d,
             std::vector<std::shared_ptr<const InputParameter>> inputs,
             std::vector<std::shared_ptr<OutputParameter>> outputs) {
        // call the DynamicLib library functions
        uint16_t err = func_(inputs, outputs, d.stream(),
                             cuda_threads_per_block_);
        OP_REQUIRES(context, err == 0,
            errors::InvalidArgument("External function execution error code: ",
                                    err));
    }

 private:
    FUNPTR func_;
    int cuda_threads_per_block_;
};
#endif  // GOOGLE_CUDA

// General purpose tensorflow user operator class
// that allows us to run operators  generated and compiled independently
// by the Operator Vectorization Library.
// Parameters are a list of input tensors, list of output shapes, list of
// output types, the location of the DynamicLib shared libraries and the name
// of the DynamicLib operator.
// See tensorflow/python/kernel_tests/dynamic_lib_op_test.py for example usage
template <typename Device>
class DynamicLibOp : public OpKernel {
 public:
  explicit DynamicLibOp(OpKernelConstruction* context) : OpKernel(context) {
    // store the passed in parameters
    OP_REQUIRES_OK(context, context->GetAttr("cpu_func_name", &cpu_func_name_));
    OP_REQUIRES_OK(context, context->GetAttr("cpu_lib_path", &cpu_lib_path_));
    OP_REQUIRES_OK(context, context->GetAttr("gpu_func_name", &gpu_func_name_));
    OP_REQUIRES_OK(context, context->GetAttr("gpu_lib_path", &gpu_lib_path_));
    OP_REQUIRES_OK(context, context->GetAttr("cuda_threads_per_block",
                                             &cuda_threads_per_block_));
    OP_REQUIRES_OK(context, context->GetAttr("out_types", &out_types_));
    OP_REQUIRES_OK(context, context->GetAttr("out_shapes", &out_shapes_));

    launcher_ = std::unique_ptr<DynamicLibLaunch<Device>>(
                new DynamicLibLaunch<Device>(context, cpu_func_name_,
                                             cpu_lib_path_, gpu_func_name_,
                                             gpu_lib_path_,
                                             cuda_threads_per_block_));
  }

  // Function that is called when the output tensors of the operator
  // are evaluated
  void Compute(OpKernelContext* context) override {
//      LOG(INFO) << "*** computing DynamicLibOp ***";

      // Build the tensor input parameter list
      OpInputList input_list;
      context->input_list("inputs", &input_list);
      std::vector<std::shared_ptr<const InputParameter>> inputs;
      inputs.reserve(input_list.size());
      for (int32_t i = 0; i < input_list.size(); ++i) {
          const Tensor& cur_input = input_list[i];
          switch (cur_input.dtype()) {
            case (DT_FLOAT):
              inputs.emplace_back(
                     new TypedInput<float>(cur_input.flat<float>().data(),
                                           cur_input.NumElements()));
              break;
            case (DT_DOUBLE):
              inputs.emplace_back(
                     new TypedInput<double>(cur_input.flat<double>().data(),
                                            cur_input.NumElements()));
              break;
            default:
              OP_REQUIRES(context, false,
                          errors::InvalidArgument(
                          "Only float and double inputs are supported."));
              break;
            }
      }

      // Build the output tensor parameter list
      const uint32_t num_outputs = context->num_outputs();
      OP_REQUIRES(context, num_outputs == out_shapes_.size(),
                  errors::InvalidArgument(
                  "Output shapes inconsistent with output types"))
      OP_REQUIRES(context, num_outputs == out_types_.size(),
                  errors::InvalidArgument(
                  "Output types inconsistent num_outputs"))
      Tensor *output_tensor[num_outputs];
      std::vector<std::shared_ptr<OutputParameter>> outputs;
      outputs.reserve(num_outputs);
      for (uint32_t i = 0; i < num_outputs; ++i) {
          DataType cur_output_type = out_types_[i];
          TensorShape cur_shape = TensorShape(out_shapes_[i]);
          OP_REQUIRES_OK(context,
                         context->allocate_output(i,
                                              cur_shape, &output_tensor[i]));
          OP_REQUIRES(context, output_tensor[i]->dtype() == cur_output_type,
                       errors::InvalidArgument("Types inconsistent"))
          switch (cur_output_type) {
            case (DT_FLOAT):
                outputs.emplace_back(new TypedOutput<float>(
                               output_tensor[i]->template flat<float>().data(),
                               output_tensor[i]->NumElements()));
                break;
            case (DT_DOUBLE):
                outputs.emplace_back(new TypedOutput<double>(
                               output_tensor[i]->template flat<double>().data(),
                               output_tensor[i]->NumElements()));
                break;
            default:
                OP_REQUIRES(context, false,
                    errors::InvalidArgument(
                            "Only float and double outputs are supported."));
                break;
          }
      }

      // call the DynamicLib library function
      const Device& d = context->eigen_device<Device>();
      launcher_->Run(context, d, inputs, outputs);
  }

 private:
  string cpu_func_name_;
  string cpu_lib_path_;
  string gpu_func_name_;
  string gpu_lib_path_;
  int cuda_threads_per_block_;
  DataTypeVector out_types_;
  std::vector<TensorShapeProto> out_shapes_;
  std::unique_ptr<DynamicLibLaunch<Device>> launcher_;
};

// register the operator for each template type with tensorflow
// Note: this registration will cause the operator constructors to get called
// regardless of whether or not they are used in a tensorflow application
REGISTER_KERNEL_BUILDER(Name("DynamicLib")
    .Device(DEVICE_CPU),
    DynamicLibOp<CPUDevice>);

#if GOOGLE_CUDA
REGISTER_KERNEL_BUILDER(Name("DynamicLib")
    .Device(DEVICE_GPU),
    DynamicLibOp<GPUDevice>);
#endif  // GOOGLE_CUDA
}  // namespace tensorflow

<|endoftext|>


<commit_before>/*******************************************************************************
Program:   Wake Forest University - Virginia Tech CTC Software
Id:        $Id$
Language:  C++
*******************************************************************************/

// command line app to subtract tagged stool from images

#include <iostream>
#include <cstdlib>
using namespace std;

// ITK includes
#include <itkImageSeriesWriter.h>
#include <itkNumericSeriesFileNames.h>
#include <itksys/SystemTools.hxx>
#include <itkGDCMImageIO.h>
#include <itkImageRegionIterator.h>
#include <itkImageRegionConstIterator.h>

// CTC includes
#include "ctcConfigure.h"
#include "ctcCTCImage.h"
#include "ctcCTCImageReader.h"
#include "ctcSegmentColonWithContrastFilter.h"
#include "vul_arg.h"

int main(int argc, char ** argv)
{
  // parse args
  vul_arg<char const*> infile(0, "Input DICOM directory");
  vul_arg<char const*> outfile(0, "Output DICOM directory");
  vul_arg<int> replaceval("-r",
			  "Replacement HU value for tagged regions (default -900)",
			  -900);
  vul_arg_parse(argc, argv);

  // test if outfile exists, if so bail out
  if(itksys::SystemTools::FileExists(outfile()))
    {
      if(itksys::SystemTools::FileIsDirectory(outfile()))
	{
	  cerr << "Error: directory " << outfile() << " exists. Halting." << endl;
	}
      else
	{
	  cerr << "Error: file " << outfile() << " exists. Halting." << endl;
	}
      return EXIT_FAILURE;
    }

  // read in the DICOM series
  ctc::CTCImageReader::Pointer reader = ctc::CTCImageReader::New();
  reader->SetDirectory(string(infile()));
  try
    {
      reader->Update();
    }
  catch (itk::ExceptionObject &ex)
    {
      std::cout << ex << std::endl;
      return EXIT_FAILURE;
    }

  // segment air + constrast
  clog << "Starting Segment";
  ctc::SegmentColonWithContrastFilter::Pointer filter = ctc::SegmentColonWithContrastFilter::New();
  filter->SetInput( reader->GetOutput() );
  filter->Update();
  clog << " Done Segmenting." << endl;

  // loop through the voxels, testing for threshold and lumen test
  // replace image values with air
  clog << "Starting Mask";
  int replace = replaceval();
  typedef itk::ImageRegionIterator<ctc::CTCImageType> InputIteratorType;
  typedef itk::ImageRegionConstIterator<ctc::BinaryImageType> BinaryIteratorType;
  InputIteratorType it1(reader->GetOutput(), reader->GetOutput()->GetRequestedRegion());
  BinaryIteratorType it2(filter->GetOutput(), filter->GetOutput()->GetRequestedRegion());
  for( it1.GoToBegin(), it2.GoToBegin();
       !it1.IsAtEnd() || !it2.IsAtEnd();
       ++it1, ++it2)
    {
      if( (it2.Get() == 255) && (it1.Get() > -800) )
	{
	  it1.Set(replace);
	}
    }
  clog << " Done Masking" << endl;

  // write out modified image
  typedef itk::Image< short, 2 > Image2DType;
  typedef itk::ImageSeriesWriter< ctc::CTCImageType, Image2DType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( reader->GetOutput() );
  writer->SetMetaDataDictionaryArray( reader->GetMetaDataDictionaryArray() );

  itk::GDCMImageIO::Pointer dicomIO = itk::GDCMImageIO::New();
  writer->SetImageIO( dicomIO );

  typedef itk::NumericSeriesFileNames NameGeneratorType;
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
  if( !itksys::SystemTools::MakeDirectory(outfile()) )
    {
      cerr << "Error: could not create output directory" << endl;
      return EXIT_FAILURE;
    }

  std::string format = outfile();
  format += "/%03d.dcm";
  nameGenerator->SetSeriesFormat( format.c_str() );

  ctc::CTCImageType::ConstPointer inputImage = reader->GetOutput();
  ctc::CTCImageType::RegionType region = inputImage->GetLargestPossibleRegion();
  ctc::CTCImageType::IndexType start = region.GetIndex();
  ctc::CTCImageType::SizeType size = region.GetSize();

  const unsigned int firstSlice = start[2];
  const unsigned int lastSlice = start[2] + size[2] - 1;
  nameGenerator->SetStartIndex( firstSlice );
  nameGenerator->SetEndIndex( lastSlice );
  nameGenerator->SetIncrementIndex( 1 );
  writer->SetFileNames( nameGenerator->GetFileNames() );

  try
    {
      writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
      cerr << "ExceptionObject caught !" << endl;
      cerr << err << endl;
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>CLW: added modifier for DICOM tags to facilitate placement in PACS<commit_after>/*******************************************************************************
Program:   Wake Forest University - Virginia Tech CTC Software
Id:        $Id$
Language:  C++
*******************************************************************************/

// command line app to subtract tagged stool from images

#include <iostream>
#include <cstdlib>
using namespace std;

// ITK includes
#include <itkImageSeriesWriter.h>
#include <itkNumericSeriesFileNames.h>
#include <itksys/SystemTools.hxx>
#include <itkGDCMImageIO.h>
#include <itkImageRegionIterator.h>
#include <itkImageRegionConstIterator.h>
#include <itkMetaDataObject.h>
#include <itkMetaDataDictionary.h>

// CTC includes
#include "ctcConfigure.h"
#include "ctcCTCImage.h"
#include "ctcCTCImageReader.h"
#include "ctcSegmentColonWithContrastFilter.h"
#include "vul_arg.h"

int main(int argc, char ** argv)
{
  // parse args
  vul_arg<char const*> infile(0, "Input DICOM directory");
  vul_arg<char const*> outfile(0, "Output DICOM directory");
  vul_arg<int> replaceval("-r",
			  "Replacement HU value for tagged regions (default -900)",
			  -900);
  vul_arg_parse(argc, argv);

  // test if outfile exists, if so bail out
  if(itksys::SystemTools::FileExists(outfile()))
    {
      if(itksys::SystemTools::FileIsDirectory(outfile()))
	{
	  cerr << "Error: directory " << outfile() << " exists. Halting." << endl;
	}
      else
	{
	  cerr << "Error: file " << outfile() << " exists. Halting." << endl;
	}
      return EXIT_FAILURE;
    }

  // read in the DICOM series
  ctc::CTCImageReader::Pointer reader = ctc::CTCImageReader::New();
  reader->SetDirectory(string(infile()));
  try
    {
      reader->Update();
    }
  catch (itk::ExceptionObject &ex)
    {
      std::cout << ex << std::endl;
      return EXIT_FAILURE;
    }

  // segment air + constrast
  clog << "Starting Segment";
  ctc::SegmentColonWithContrastFilter::Pointer filter =
    ctc::SegmentColonWithContrastFilter::New();
  filter->SetInput( reader->GetOutput() );
  filter->Update();
  clog << " Done Segmenting." << endl;

  // loop through the voxels, testing for threshold and lumen test
  // replace image values with air
  clog << "Starting Mask";
  int replace = replaceval();
  typedef itk::ImageRegionIterator<ctc::CTCImageType> InputIteratorType;
  typedef itk::ImageRegionConstIterator<ctc::BinaryImageType> BinaryIteratorType;
  InputIteratorType it1(reader->GetOutput(),
			reader->GetOutput()->GetRequestedRegion());
  BinaryIteratorType it2(filter->GetOutput(),
			 filter->GetOutput()->GetRequestedRegion());

  for( it1.GoToBegin(), it2.GoToBegin();
       !it1.IsAtEnd() || !it2.IsAtEnd();
       ++it1, ++it2)
    {
      if( (it2.Get() == 255) && (it1.Get() > -800) )
	{
	  it1.Set(replace);
	}
    }
  clog << " Done Masking" << endl;

  // write out modified image
  typedef itk::Image< short, 2 > Image2DType;
  typedef itk::ImageSeriesWriter< ctc::CTCImageType, Image2DType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( reader->GetOutput() );

  // modify series number
  ctc::CTCImageReader::DictionaryArrayRawPointer dictarray =
    reader->GetMetaDataDictionaryArray();

  std::string SeriesNumberTag = "0020|0011";
  std::string SeriesNumberValue;
  for(int slice = 0;
      slice < dictarray->size();
      slice++)
    {
      ctc::CTCImageReader::DictionaryRawPointer dict =
	(*(reader->GetMetaDataDictionaryArray()))[slice];

      itk::ExposeMetaData<std::string>(*dict,
					SeriesNumberTag,
					SeriesNumberValue);
      SeriesNumberValue = "90";
      itk::EncapsulateMetaData<std::string>(*dict,
					    SeriesNumberTag,
					    SeriesNumberValue);
    }

  writer->SetMetaDataDictionaryArray( dictarray );

  itk::GDCMImageIO::Pointer dicomIO = itk::GDCMImageIO::New();

  writer->SetImageIO( dicomIO );

  typedef itk::NumericSeriesFileNames NameGeneratorType;
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
  if( !itksys::SystemTools::MakeDirectory(outfile()) )
    {
      cerr << "Error: could not create output directory" << endl;
      return EXIT_FAILURE;
    }

  std::string format = outfile();
  format += "/%03d.dcm";
  nameGenerator->SetSeriesFormat( format.c_str() );

  ctc::CTCImageType::ConstPointer inputImage = reader->GetOutput();
  ctc::CTCImageType::RegionType region = inputImage->GetLargestPossibleRegion();
  ctc::CTCImageType::IndexType start = region.GetIndex();
  ctc::CTCImageType::SizeType size = region.GetSize();

  const unsigned int firstSlice = start[2];
  const unsigned int lastSlice = start[2] + size[2] - 1;
  nameGenerator->SetStartIndex( firstSlice );
  nameGenerator->SetEndIndex( lastSlice );
  nameGenerator->SetIncrementIndex( 1 );
  writer->SetFileNames( nameGenerator->GetFileNames() );

  try
    {
      writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
      cerr << "ExceptionObject caught !" << endl;
      cerr << err << endl;
      return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * File:   Sfuck.cpp
 * Author: Michael Hrcek <hrcekmj@clarkson.edu>
 *
 * Created on September 14, 2015, 6:25 PM
 */

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <time.h>

using namespace std;

struct store {
    int intBank[128][128];
    int index, vindex;
    bool printAsChar;
    bool notFlaged;

    store() {
        index = 0;
        vindex = 0;
        printAsChar = true;
    }

    void getCommand(char c);
};

void store::getCommand(char c) {
    switch (c) {
        case '+':
            intBank[vindex][index]++;
            break;
        case '-':
            intBank[vindex][index]--;
            break;
        case '>':
            if (index == 127) {
                index = 0;
            } else {
                index++;
            }
            break;
        case '<':
            if (index == 0) {
                index = 127;
            } else {
                index--;
            }
            break;
        case '^':
            if (vindex == 127) {
                vindex = 0;
            } else {
                vindex++;
            }
            break;
        case '\\':
            if (vindex == 0) {
                vindex = 127;
            } else {
                vindex--;
            }
            break;
        case '#':
            index = vindex = 0;
            break;
        case ',':
            intBank[vindex][index] = (int) cin.get();
            break;
        case '.':
            if (printAsChar) {
                cout << (char) intBank[vindex][index];
            } else {
                cout << intBank[vindex][index];
            }
            break;
        case '=':
            if (intBank[vindex][index] == (int) 'x') {
                intBank[vindex][index] = 1;
            } else {
                intBank[vindex][index] = 0;
            }
            break;
        case '?':
            intBank[vindex][index] = rand();
            break;
        case '@':
            printAsChar = !printAsChar;
            break;
        case '~':
            notFlaged = false;
            break;
        case '|':
            if (vindex > 0) {
                intBank[vindex][index] = intBank[vindex - 1][index];
            } else {
                intBank[vindex][index] = intBank[127][index];
            }
            break;
        case '}':
            if (index > 0) {
                intBank[vindex][index] = intBank[vindex][index - 1];
            } else {
                intBank[vindex][index] = intBank[vindex][127];
            }
            break;

    }
}

/*
 *
 */
int main(int argc, char** argv) {

    srand(time(NULL));

    store s;
    string choice;

    while (true) {
        cout << "SGFY interpreter v0.1.1\n\n------------------------------------------\n"
                << "Enter filename (cin if live interpret): ";
        cin >> choice;
        cin.clear();

        s.notFlaged = true;

        if (choice == "cin") {
            while (s.notFlaged) {
                s.getCommand(cin.get());
            }
        } else {
            ifstream stream(choice.c_str());
            while (!stream.eof()) {
                s.getCommand(stream.get());
            }
        }

        cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
    }

    //    if (argc <= 1) {
    //        while (true) {
    //            s.getCommand(cin.get());
    //        }
    //    } else{
    //        //Get args
    //    }

    return 0;
}

<commit_msg>Updated | logic<commit_after>/*
 * File:   Sfuck.cpp
 * Author: Michael Hrcek <hrcekmj@clarkson.edu>
 *
 * Created on September 14, 2015, 6:25 PM
 */

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <time.h>

using namespace std;

struct store {
    int intBank[128][128];
    int index, vindex;
    bool printAsChar;
    bool notFlaged;

    store() {
        index = 0;
        vindex = 0;
        printAsChar = true;
    }

    void getCommand(char c);
};

void store::getCommand(char c) {
    switch (c) {
        case '+':
            intBank[vindex][index]++;
            break;
        case '-':
            intBank[vindex][index]--;
            break;
        case '>':
            if (index == 127) {
                index = 0;
            } else {
                index++;
            }
            break;
        case '<':
            if (index == 0) {
                index = 127;
            } else {
                index--;
            }
            break;
        case '^':
            if (vindex == 127) {
                vindex = 0;
            } else {
                vindex++;
            }
            break;
        case '\\':
            if (vindex == 0) {
                vindex = 127;
            } else {
                vindex--;
            }
            break;
        case '#':
            index = vindex = 0;
            break;
        case ',':
            intBank[vindex][index] = (int) cin.get();
            break;
        case '.':
            if (printAsChar) {
                cout << (char) intBank[vindex][index];
            } else {
                cout << intBank[vindex][index];
            }
            break;
        case '=':
            if (intBank[vindex][index] == (int) 'x') {
                intBank[vindex][index] = 1;
            } else {
                intBank[vindex][index] = 0;
            }
            break;
        case '?':
            intBank[vindex][index] = rand();
            break;
        case '@':
            printAsChar = !printAsChar;
            break;
        case '~':
            notFlaged = false;
            break;
        case '|':
            if (vindex < 127) {
                intBank[vindex][index] = intBank[vindex + 1][index];
            } else {
                intBank[vindex][index] = intBank[0][index];
            }
            break;
        case '}':
            if (index > 0) {
                intBank[vindex][index] = intBank[vindex][index - 1];
            } else {
                intBank[vindex][index] = intBank[vindex][127];
            }
            break;

    }
}

/*
 *
 */
int main(int argc, char** argv) {

    srand(time(NULL));

    store s;
    string choice;

    while (true) {
        cout << "SGFY interpreter v0.1.1\n\n------------------------------------------\n"
                << "Enter filename (cin if live interpret): ";
        cin >> choice;
        cin.clear();

        s.notFlaged = true;

        if (choice == "cin") {
            while (s.notFlaged) {
                s.getCommand(cin.get());
            }
        } else {
            ifstream stream(choice.c_str());
            while (!stream.eof()) {
                s.getCommand(stream.get());
            }
        }

        cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
    }

    //    if (argc <= 1) {
    //        while (true) {
    //            s.getCommand(cin.get());
    //        }
    //    } else{
    //        //Get args
    //    }

    return 0;
}

<|endoftext|>


<commit_before>// vimshell.cpp : Defines the entry point for the application.
//

#include "vimshell.h"
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <shellapi.h>

bool cvtLPW2stdstring(std::string& s, const LPWSTR pw,
                      UINT codepage = CP_ACP)
{
    bool res = false;
    char* p = 0;
    int bsz;

    bsz = WideCharToMultiByte(codepage,
        0,
        pw,-1,
        0,0,
        0,0);
    if (bsz > 0) {
        p = new char[bsz];
        int rc = WideCharToMultiByte(codepage,
            0,
            pw,-1,
            p,bsz,
            0,0);
        if (rc != 0) {
            p[bsz-1] = 0;
            s = p;
            res = true;
        }
    }
    delete [] p;
    return res;
}

std::string FindAndReplace(std::string tInput, std::string tFind, std::string tReplace )
{
	size_t uPos = 0;
	size_t uFindLen = tFind.length();
	size_t uReplaceLen = tReplace.length();

	if( uFindLen == 0 )
	{
		return tInput;
	}

	while((uPos = tInput.find( tFind, uPos )) != std::string::npos)
	{
		tInput.replace( uPos, uFindLen, tReplace );
		uPos += uReplaceLen;
	}

	return tInput;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	int count;
	//MessageBox(0, lpCmdLine, 0, 0);
	LPWSTR* strings = CommandLineToArgvW(GetCommandLineW(), &count);
	std::string currentDir;

	cvtLPW2stdstring(currentDir, strings[0]);

	// Cut off the filename
	while((currentDir.length() > 0) &&
		(currentDir[currentDir.length()-1] != '/') &&
		(currentDir[currentDir.length()-1] != '\\'))
	{
		currentDir = currentDir.substr(0, currentDir.length()-1);
	}
	if(currentDir.length() > 0 && currentDir[0] == '"')
		currentDir = currentDir.substr(1);

	std::string filename = currentDir + std::string("shell.txt");

	std::ifstream fileIn(filename.c_str());
	if(!fileIn)
	{
		MessageBox(0, "Please create a file called shell.txt in the same folder you put this new vimrun.exe", 0,0);
		return 1;
	}

	std::string argumentshellcommand;
	std::string silentshellcommand;
	std::string interactiveshellcommand;

	std::getline(fileIn, argumentshellcommand);
	std::getline(fileIn, silentshellcommand);
	std::getline(fileIn, interactiveshellcommand);

	std::string args = lpCmdLine;

	while(args.length() > 0 && args[0] == ' ')
		args = args.substr(1);

	bool execSilently = false;

	if(args.length() > 3 &&
			args[0] == '-' &&
			args[1] == 's' &&
			args[2] == ' ')
	{
		args = args.substr(3);
		execSilently = true;
	}

	size_t spacepos = args.find_first_of(" ");
	args = args.substr(spacepos+1);
	spacepos = args.find_first_of(" ");
	args = args.substr(spacepos+1);

	std::string cmd;

	if(spacepos == std::string::npos)
		args = "";

	std::string argcmd = execSilently ? silentshellcommand : argumentshellcommand;

	if(args.length() == 0)
	{
		cmd = interactiveshellcommand;
	}
	else
	{
		std::string quotedPH = "#QQQQ#";
		if(argcmd.find(quotedPH) != std::string::npos)
		{
			bool indoubles = false;
			bool insingles = false;
			for(size_t i = 0; i < args.length(); i++)
			{
				if(args[i] == '"')
					indoubles = !indoubles;
				if(args[i] == '\'')
					insingles = !insingles;

				if(!indoubles && !insingles && args[i] == '\\')
				{
					args.insert(i, "\\");
					i++;
					continue;
				}

				if(!indoubles && args[i] == '\'')
				{
					args.insert(i, "\\");
					i++;
					continue;
				}

			}
			//args = FindAndReplace(args,"'", "\\'");

		//	args = FindAndReplace(args, "\\", "\\\\");
			cmd = FindAndReplace(argcmd, quotedPH, args);
		}
		else
		{
			cmd = argcmd + " " + args;
		}
	}
	/*MessageBox(0,cmd.c_str(), 0,0);
	std::ofstream f("C:/output.txt");
	f << cmd.c_str();
	f.close();*/

	STARTUPINFO si = { sizeof(STARTUPINFO) };
	si.dwFlags = STARTF_USESHOWWINDOW;
	if(execSilently)
		si.wShowWindow = SW_HIDE;
	else
		si.wShowWindow = SW_SHOW;
	PROCESS_INFORMATION pi;
	char arr[1024];
	strcpy_s(arr, 1024, cmd.c_str());
	CreateProcess(NULL, arr, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	WaitForSingleObject(pi.hProcess, INFINITE);
	DWORD exit_code;
	GetExitCodeProcess(pi.hProcess, &exit_code);

	return exit_code;
}
<commit_msg>Vimshell now works with files instead of inline strings. This assures everything works 100% of the time. Instead of the old #QQQQ# you now enter #F# in your shell.txt to reference the file your shell should read from. If you wish to append (prepending isn't possible at the moment (and would be impossible with this syntax)) something at the end of this file, do so like this: #Fxxx# to append xxx. For example, something useful to append would be #F;read;# on the first line of your shell.txt, so your shell will pauze after running<commit_after>// vimshell.cpp : Defines the entry point for the application.
//

#include "vimshell.h"
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <shellapi.h>

bool cvtLPW2stdstring(std::string& s, const LPWSTR pw,
                      UINT codepage = CP_ACP)
{
    bool res = false;
    char* p = 0;
    int bsz;

    bsz = WideCharToMultiByte(codepage,
        0,
        pw,-1,
        0,0,
        0,0);
    if (bsz > 0) {
        p = new char[bsz];
        int rc = WideCharToMultiByte(codepage,
            0,
            pw,-1,
            p,bsz,
            0,0);
        if (rc != 0) {
            p[bsz-1] = 0;
            s = p;
            res = true;
        }
    }
    delete [] p;
    return res;
}

std::string FindAndReplace(std::string tInput, std::string tFind, std::string tReplace )
{
	size_t uPos = 0;
	size_t uFindLen = tFind.length();
	size_t uReplaceLen = tReplace.length();

	if( uFindLen == 0 )
	{
		return tInput;
	}

	while((uPos = tInput.find( tFind, uPos )) != std::string::npos)
	{
		tInput.replace( uPos, uFindLen, tReplace );
		uPos += uReplaceLen;
	}

	return tInput;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	int count;
	//MessageBox(0, lpCmdLine, 0, 0);
	LPWSTR* strings = CommandLineToArgvW(GetCommandLineW(), &count);
	std::string currentDir;

	cvtLPW2stdstring(currentDir, strings[0]);

	// Cut off the filename
	while((currentDir.length() > 0) &&
		(currentDir[currentDir.length()-1] != '/') &&
		(currentDir[currentDir.length()-1] != '\\'))
	{
		currentDir = currentDir.substr(0, currentDir.length()-1);
	}
	if(currentDir.length() > 0 && currentDir[0] == '"')
		currentDir = currentDir.substr(1);

	std::string filename = currentDir + std::string("shell.txt");

	std::ifstream fileIn(filename.c_str());
	if(!fileIn)
	{
		MessageBox(0, "Please create a file called shell.txt in the same folder you put this new vimrun.exe", 0,0);
		return 1;
	}

	std::string argumentshellcommand;
	std::string silentshellcommand;
	std::string interactiveshellcommand;

	std::getline(fileIn, argumentshellcommand);
	std::getline(fileIn, silentshellcommand);
	std::getline(fileIn, interactiveshellcommand);

	std::string args = lpCmdLine;

	while(args.length() > 0 && args[0] == ' ')
		args = args.substr(1);

	bool execSilently = false;

	if(args.length() > 3 &&
			args[0] == '-' &&
			args[1] == 's' &&
			args[2] == ' ')
	{
		args = args.substr(3);
		execSilently = true;
	}

	size_t spacepos = args.find_first_of(" ");
	args = args.substr(spacepos+1);
	spacepos = args.find_first_of(" ");
	args = args.substr(spacepos+1);

	std::string cmd;

	if(spacepos == std::string::npos)
		args = "";

	std::string argcmd = execSilently ? silentshellcommand : argumentshellcommand;

	if(args.length() == 0)
	{
		cmd = interactiveshellcommand;
	}
	else
	{
		int start = argcmd.find('#F');
		int end = argcmd.find('#', start+1);

		//MessageBox(0, argcmd.c_str(), 0,0);
		if(start == std::string::npos || end == std::string::npos)
			MessageBox(0, "Check your shell.txt", 0,0);

		std::string appendage = argcmd.substr(start+1, end-start-1);

		std::string filename = "C:/vimshelltmp.txt";

		cmd = argcmd.replace(start-1, end-start+2, filename);
		std::ofstream f(filename.c_str());
		f << args.c_str() << appendage;
		f.close();
	}

	//MessageBox(0,cmd.c_str(), 0,0);
	std::ofstream f("C:/output.txt");
	f << cmd.c_str();
	f.close();

	STARTUPINFO si = { sizeof(STARTUPINFO) };
	si.dwFlags = STARTF_USESHOWWINDOW;
	if(execSilently)
		si.wShowWindow = SW_HIDE;
	else
		si.wShowWindow = SW_SHOW;
	PROCESS_INFORMATION pi;
	char arr[1024];
	strcpy_s(arr, 1024, cmd.c_str());
	CreateProcess(NULL, arr, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	WaitForSingleObject(pi.hProcess, INFINITE);
	DWORD exit_code;
	GetExitCodeProcess(pi.hProcess, &exit_code);

	return exit_code;
}
<|endoftext|>