<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013-2015, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#include <algorithm> // std::generate
#include <iostream>
#include <vector>

#include "nupic/algorithms/Anomaly.hpp"

#include "nupic/algorithms/Cells4.hpp"
#include "nupic/algorithms/BacktrackingTMCpp.hpp"
#include "nupic/algorithms/TemporalMemory.hpp"

#include "nupic/algorithms/SpatialPooler.hpp"

#include "nupic/encoders/ScalarEncoder.hpp"

#include "nupic/os/Timer.hpp"
#include "nupic/utils/VectorHelpers.hpp"
#include "nupic/utils/Random.hpp"

namespace examples {

using namespace std;
using namespace nupic;
using namespace nupic::utils;

using nupic::ScalarEncoder;

using nupic::algorithms::spatial_pooler::SpatialPooler;

using TP =     nupic::algorithms::Cells4::Cells4;
using BackTM = nupic::algorithms::backtracking_tm::BacktrackingTMCpp;
using TM =     nupic::algorithms::temporal_memory::TemporalMemory;

using nupic::algorithms::anomaly::Anomaly;
using nupic::algorithms::anomaly::AnomalyMode;

// work-load
void run(UInt EPOCHS = 5000,
	 bool useSPlocal=true, //can toggle which (long running) components are tested, default all
	 bool useSPglobal=true,
	 bool useTP=true,
	 bool useBackTM=true,
	 bool useTM=true,
	 const UInt COLS = 2048, // number of columns in SP, TP
         const UInt DIM_INPUT = 10000,
         const UInt CELLS = 10 // cells per column in TP
	 ) {
#ifndef NDEBUG
  EPOCHS = 2; // make test faster in Debug
#endif

  if(useTP or useTM or useBackTM) {
	  NTA_CHECK(useSPlocal or useSPglobal) << "using TM requires a SP too";
  }

  std::cout << "starting test. DIM_INPUT=" << DIM_INPUT
  		<< ", DIM=" << COLS << ", CELLS=" << CELLS << std::endl;
  std::cout << "EPOCHS = " << EPOCHS << std::endl;

  // initialize SP, TP, Anomaly, AnomalyLikelihood
  Timer tInit(true);
  ScalarEncoder enc(133, -100.0, 100.0, DIM_INPUT, 0.0, 0.0, false);
  NTA_INFO << "SP (l) local inhibition is slow, so we reduce its data 10x smaller"; //to make it reasonably fast for test, for comparison x10
  SpatialPooler spGlobal(vector<UInt>{DIM_INPUT}, vector<UInt>{COLS}); // Spatial pooler with globalInh
  SpatialPooler spLocal(vector<UInt>{DIM_INPUT}, vector<UInt>{COLS/10u}); // Spatial pooler with local inh
  spGlobal.setGlobalInhibition(true);
  spLocal.setGlobalInhibition(false);

  TP tp(COLS, CELLS, 12, 8, 15, 5, .5f, .8f, 1.0f, .1f, .1f, 0.0f,
            false, 42, true, false);
  BackTM backTM(COLS, CELLS); //TODO get all, described parameters
  TM tm(vector<UInt>{COLS}, CELLS);

  Anomaly an(5, AnomalyMode::PURE);
  Anomaly anLikelihood(5, AnomalyMode::LIKELIHOOD);
  tInit.stop();

  // data for processing input
  vector<UInt> input(DIM_INPUT);
  vector<UInt> outSP(COLS); // active array, output of SP/TP
  vector<UInt> outSPsparse;
  vector<UInt> outTP(tp.nCells());
  vector<Real> rIn(COLS); // input for TP (must be Reals)
  vector<Real> rOut(tp.nCells());
  Real res = 0.0; //for anomaly:
  vector<UInt> prevPred_(outSP.size());
  Random rnd;

  // Start a stopwatch timer
  printf("starting:  %d iterations.", EPOCHS);
  Timer tAll(true);
  Timer tRng, tEnc, tSPloc, tSPglob, tTP, tBackTM, tTM,
	tAn, tAnLikelihood;

  //run
  for (UInt e = 0; e < EPOCHS; e++) {
    //Input
//    generate(input.begin(), input.end(), [&] () { return rnd.getUInt32(2); });
    tRng.start();
    const Real r = (Real)(rnd.getUInt32(100) - rnd.getUInt32(100)*rnd.getReal64()); //rnd from range -100..100
    tRng.stop();

    //Encode
    tEnc.start();
    enc.encodeIntoArray(r, input.data());
    tEnc.stop();

    //SP (global x local)
    if(useSPlocal) {
    tSPloc.start();
    fill(outSP.begin(), outSP.end(), 0);
    spLocal.compute(input.data(), true, outSP.data());
    spLocal.stripUnlearnedColumns(outSP.data());
    tSPloc.stop();
    NTA_CHECK(outSP.size() == COLS);
    }

    if(useSPglobal) {
    tSPglob.start();
    fill(outSP.begin(), outSP.end(), 0);
    spGlobal.compute(input.data(), true, outSP.data());
    spGlobal.stripUnlearnedColumns(outSP.data());
    tSPglob.stop();
    NTA_CHECK(outSP.size() == COLS);
    }
    outSPsparse = VectorHelpers::binaryToSparse(outSP);
    NTA_CHECK(outSPsparse.size() < COLS);

    //TP (TP x BackTM x TM)
    if(useTP) {
    tTP.start();
    rIn = VectorHelpers::castVectorType<UInt, Real>(outSP);
    tp.compute(rIn.data(), rOut.data(), true, true);
    outTP = VectorHelpers::castVectorType<Real, UInt>(rOut);
    tTP.stop();
    }

    if(useBackTM) {
    tBackTM.start();
    backTM.compute(rIn.data(), true /*learn*/, true /*infer*/);
    const auto backAct = backTM.getActiveState();
    const auto backPred = backTM.getPredictedState();
    const vector<char> vAct(backAct, backAct + backTM.getNumCells());
    const vector<char> vPred(backPred, backPred + backTM.getNumCells());
    tBackTM.stop();
    }

    if(useTM) {
    tTM.start();
    tm.compute(outSPsparse.size(), outSPsparse.data(), true /*learn*/);
    const auto tmAct = tm.getActiveCells();
    tm.activateDendrites(); //must be called before getPredictiveCells
    const auto tmPred = tm.getPredictiveCells();
    //TODO assert tmAct == spOut
    //TODO merge Act + Pred and use for anomaly from TM
    tTM.stop();
    }

    //Anomaly (pure x likelihood)
    tAn.start();
    res = an.compute(outSP /*active*/, prevPred_ /*prev predicted*/);
    tAn.stop();

    tAnLikelihood.start();
    anLikelihood.compute(outSP /*active*/, prevPred_ /*prev predicted*/);
    tAnLikelihood.stop();

    prevPred_ = outTP; //to be used as predicted T-1

    // print
    if (e == EPOCHS - 1) {
      tAll.stop();

      cout << "Epoch = " << e << endl;
      cout << "Anomaly = " << res << endl;
      VectorHelpers::print_vector(VectorHelpers::binaryToSparse<UInt>(outSP), ",", "SP= ");
      VectorHelpers::print_vector(VectorHelpers::binaryToSparse<UInt>(VectorHelpers::cellsToColumns(outTP, CELLS)), ",", "TP= ");
      NTA_CHECK(outSP[69] == 0) << "A value in SP computed incorrectly";
      NTA_CHECK(outTP[42] == 0) << "Incorrect value in TP";
      cout << "==============TIMERS============" << endl;
      cout << "Init:\t" << tInit.getElapsed() << endl;
      cout << "Random:\t" << tRng.getElapsed() << endl;
      cout << "Encode:\t" << tEnc.getElapsed() << endl;
      if(useSPlocal)  cout << "SP (l):\t" << tSPloc.getElapsed() << "(x10)" << endl;
      if(useSPglobal) cout << "SP (g):\t" << tSPglob.getElapsed() << endl;
      if(useTP) cout << "TP:\t" << tTP.getElapsed() << endl;
      if(useTM) cout << "TM:\t" << tTM.getElapsed() << endl;
      if(useBackTM) cout << "BackTM:\t" << tBackTM.getElapsed() << endl;
      cout << "AN:\t" << tAn.getElapsed() << endl;
      cout << "AN:\t" << tAnLikelihood.getElapsed() << endl;

      const size_t timeTotal = (size_t)floor(tAll.getElapsed());
      cout << "Total elapsed time = " << timeTotal << " seconds" << endl;
      if(EPOCHS >= 100) { //show only relevant values, ie don't run in valgrind (ndebug, epochs=5) run
#ifdef _MSC_VER
          const size_t CI_avg_time = (size_t)floor(30*Timer::getSpeed()); //sec
#else
          const size_t CI_avg_time = (size_t)floor(7*Timer::getSpeed()); //sec
#endif
        NTA_CHECK(timeTotal <= CI_avg_time) << //we'll see how stable the time result in CI is, if usable
          "HelloSPTP test slower than expected! (" << timeTotal << ",should be "<< CI_avg_time;
      }
    }
  } //end for

} //end run()
} //-ns
<commit_msg>Hotgym: test returns total elapsed time<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013-2015, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#include <algorithm> // std::generate
#include <iostream>
#include <vector>

#include "nupic/algorithms/Anomaly.hpp"

#include "nupic/algorithms/Cells4.hpp"
#include "nupic/algorithms/BacktrackingTMCpp.hpp"
#include "nupic/algorithms/TemporalMemory.hpp"

#include "nupic/algorithms/SpatialPooler.hpp"

#include "nupic/encoders/ScalarEncoder.hpp"

#include "nupic/os/Timer.hpp"
#include "nupic/utils/VectorHelpers.hpp"
#include "nupic/utils/Random.hpp"

namespace examples {

using namespace std;
using namespace nupic;
using namespace nupic::utils;

using nupic::ScalarEncoder;

using nupic::algorithms::spatial_pooler::SpatialPooler;

using TP =     nupic::algorithms::Cells4::Cells4;
using BackTM = nupic::algorithms::backtracking_tm::BacktrackingTMCpp;
using TM =     nupic::algorithms::temporal_memory::TemporalMemory;

using nupic::algorithms::anomaly::Anomaly;
using nupic::algorithms::anomaly::AnomalyMode;

// work-load
Real64 run(UInt EPOCHS = 5000,
	 bool useSPlocal=true, //can toggle which (long running) components are tested, default all
	 bool useSPglobal=true,
	 bool useTP=true,
	 bool useBackTM=true,
	 bool useTM=true,
	 const UInt COLS = 2048, // number of columns in SP, TP
         const UInt DIM_INPUT = 10000,
         const UInt CELLS = 10 // cells per column in TP
	 ) {
#ifndef NDEBUG
  EPOCHS = 2; // make test faster in Debug
#endif

  if(useTP or useTM or useBackTM) {
	  NTA_CHECK(useSPlocal or useSPglobal) << "using TM requires a SP too";
  }

  std::cout << "starting test. DIM_INPUT=" << DIM_INPUT
  		<< ", DIM=" << COLS << ", CELLS=" << CELLS << std::endl;
  std::cout << "EPOCHS = " << EPOCHS << std::endl;

  // initialize SP, TP, Anomaly, AnomalyLikelihood
  Timer tInit(true);
  ScalarEncoder enc(133, -100.0, 100.0, DIM_INPUT, 0.0, 0.0, false);
  NTA_INFO << "SP (l) local inhibition is slow, so we reduce its data 10x smaller"; //to make it reasonably fast for test, for comparison x10
  SpatialPooler spGlobal(vector<UInt>{DIM_INPUT}, vector<UInt>{COLS}); // Spatial pooler with globalInh
  SpatialPooler spLocal(vector<UInt>{DIM_INPUT}, vector<UInt>{COLS/10u}); // Spatial pooler with local inh
  spGlobal.setGlobalInhibition(true);
  spLocal.setGlobalInhibition(false);

  TP tp(COLS, CELLS, 12, 8, 15, 5, .5f, .8f, 1.0f, .1f, .1f, 0.0f,
            false, 42, true, false);
  BackTM backTM(COLS, CELLS); //TODO get all, described parameters
  TM tm(vector<UInt>{COLS}, CELLS);

  Anomaly an(5, AnomalyMode::PURE);
  Anomaly anLikelihood(5, AnomalyMode::LIKELIHOOD);
  tInit.stop();

  // data for processing input
  vector<UInt> input(DIM_INPUT);
  vector<UInt> outSP(COLS); // active array, output of SP/TP
  vector<UInt> outSPsparse;
  vector<UInt> outTP(tp.nCells());
  vector<Real> rIn(COLS); // input for TP (must be Reals)
  vector<Real> rOut(tp.nCells());
  Real res = 0.0; //for anomaly:
  vector<UInt> prevPred_(outSP.size());
  Random rnd;

  // Start a stopwatch timer
  printf("starting:  %d iterations.", EPOCHS);
  Timer tAll(true);
  Timer tRng, tEnc, tSPloc, tSPglob, tTP, tBackTM, tTM,
	tAn, tAnLikelihood;

  //run
  for (UInt e = 0; e < EPOCHS; e++) {
    //Input
//    generate(input.begin(), input.end(), [&] () { return rnd.getUInt32(2); });
    tRng.start();
    const Real r = (Real)(rnd.getUInt32(100) - rnd.getUInt32(100)*rnd.getReal64()); //rnd from range -100..100
    tRng.stop();

    //Encode
    tEnc.start();
    enc.encodeIntoArray(r, input.data());
    tEnc.stop();

    //SP (global x local)
    if(useSPlocal) {
    tSPloc.start();
    fill(outSP.begin(), outSP.end(), 0);
    spLocal.compute(input.data(), true, outSP.data());
    spLocal.stripUnlearnedColumns(outSP.data());
    tSPloc.stop();
    NTA_CHECK(outSP.size() == COLS);
    }

    if(useSPglobal) {
    tSPglob.start();
    fill(outSP.begin(), outSP.end(), 0);
    spGlobal.compute(input.data(), true, outSP.data());
    spGlobal.stripUnlearnedColumns(outSP.data());
    tSPglob.stop();
    NTA_CHECK(outSP.size() == COLS);
    }
    outSPsparse = VectorHelpers::binaryToSparse(outSP);
    NTA_CHECK(outSPsparse.size() < COLS);

    //TP (TP x BackTM x TM)
    if(useTP) {
    tTP.start();
    rIn = VectorHelpers::castVectorType<UInt, Real>(outSP);
    tp.compute(rIn.data(), rOut.data(), true, true);
    outTP = VectorHelpers::castVectorType<Real, UInt>(rOut);
    tTP.stop();
    }

    if(useBackTM) {
    tBackTM.start();
    backTM.compute(rIn.data(), true /*learn*/, true /*infer*/);
    const auto backAct = backTM.getActiveState();
    const auto backPred = backTM.getPredictedState();
    const vector<char> vAct(backAct, backAct + backTM.getNumCells());
    const vector<char> vPred(backPred, backPred + backTM.getNumCells());
    tBackTM.stop();
    }

    if(useTM) {
    tTM.start();
    tm.compute(outSPsparse.size(), outSPsparse.data(), true /*learn*/);
    const auto tmAct = tm.getActiveCells();
    tm.activateDendrites(); //must be called before getPredictiveCells
    const auto tmPred = tm.getPredictiveCells();
    //TODO assert tmAct == spOut
    //TODO merge Act + Pred and use for anomaly from TM
    tTM.stop();
    }

    //Anomaly (pure x likelihood)
    tAn.start();
    res = an.compute(outSP /*active*/, prevPred_ /*prev predicted*/);
    tAn.stop();

    tAnLikelihood.start();
    anLikelihood.compute(outSP /*active*/, prevPred_ /*prev predicted*/);
    tAnLikelihood.stop();

    prevPred_ = outTP; //to be used as predicted T-1

    // print
    if (e == EPOCHS - 1) {
      tAll.stop();

      cout << "Epoch = " << e << endl;
      cout << "Anomaly = " << res << endl;
      VectorHelpers::print_vector(VectorHelpers::binaryToSparse<UInt>(outSP), ",", "SP= ");
      VectorHelpers::print_vector(VectorHelpers::binaryToSparse<UInt>(VectorHelpers::cellsToColumns(outTP, CELLS)), ",", "TP= ");
      NTA_CHECK(outSP[69] == 0) << "A value in SP computed incorrectly";
      NTA_CHECK(outTP[42] == 0) << "Incorrect value in TP";
      cout << "==============TIMERS============" << endl;
      cout << "Init:\t" << tInit.getElapsed() << endl;
      cout << "Random:\t" << tRng.getElapsed() << endl;
      cout << "Encode:\t" << tEnc.getElapsed() << endl;
      if(useSPlocal)  cout << "SP (l):\t" << tSPloc.getElapsed() << "(x10)" << endl;
      if(useSPglobal) cout << "SP (g):\t" << tSPglob.getElapsed() << endl;
      if(useTP) cout << "TP:\t" << tTP.getElapsed() << endl;
      if(useTM) cout << "TM:\t" << tTM.getElapsed() << endl;
      if(useBackTM) cout << "BackTM:\t" << tBackTM.getElapsed() << endl;
      cout << "AN:\t" << tAn.getElapsed() << endl;
      cout << "AN:\t" << tAnLikelihood.getElapsed() << endl;

      const size_t timeTotal = (size_t)floor(tAll.getElapsed());
      cout << "Total elapsed time = " << timeTotal << " seconds" << endl;
      if(EPOCHS >= 100) { //show only relevant values, ie don't run in valgrind (ndebug, epochs=5) run
#ifdef _MSC_VER
          const size_t CI_avg_time = (size_t)floor(30*Timer::getSpeed()); //sec
#else
          const size_t CI_avg_time = (size_t)floor(7*Timer::getSpeed()); //sec
#endif
        NTA_CHECK(timeTotal <= CI_avg_time) << //we'll see how stable the time result in CI is, if usable
          "HelloSPTP test slower than expected! (" << timeTotal << ",should be "<< CI_avg_time;
      }
    }
  } //end for
  return tAll.getElapsed();
} //end run()
} //-ns
<|endoftext|>


<commit_before>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	bufferedReaderClass = env->FindClass("java/io/BufferedReader");
	 	inputStreamReaderClass = env->FindClass("java/io/InputStreamReader");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

		//getInputStreamMethod = env->GetMethodID(env->FindClass("java/net/URLConnection"), "getInputStream", "()Ljava/io/InputStream;");
	 	readerCloseMethod = env->GetMethodID(bufferedReaderClass, "close", "()V");
	 	readLineMethod = env->GetMethodID(bufferedReaderClass, "readLine", "()Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "()I");
	 	inputStreamReaderConstructor = env->GetMethodID(inputStreamReaderClass, "<init>", "(Ljava/io/InputStream;)V");
	 	bufferedReaderConstructor = env->GetMethodID(bufferedReaderClass, "<init>", "(Ljava/io/Reader;)V");
		urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");
		inputStreamCloseMethod = env->GetMethodID(inputStreamClass, "close", "()V");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	//jobject url = env->NewObject(urlClass, urlConstructor, "sometrik.com");
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		//Set Follow enabled
		switch (req.getType()) {
		case HTTPRequest::POST:
		  	env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
				 env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));;
			break;
		}

		//Brings out exception, if URL is bad --- needs exception (IOExcpetion) handling or something
			int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

			if (env->ExceptionCheck()) {
			   env->ExceptionClear();
				__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCPETION http request responsecode = %i", responseCode);
			  return HTTPResponse(0, "exception");
			}
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

			const char *errorMessage = "";

		if (responseCode >= 400 && responseCode <= 599){
			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

		}

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "going to else");
		// stream
		if (callback) {
			while ( 1 ) {
				  // lue streamia
					callback->handleChunk(0, 0);
			}
  		return HTTPResponse(responseCode, errorMessage);
		} else {
			// lue koko stream

			jobject input = env->CallObjectMethod(connection, getInputStreamMethod);
			env->ExceptionClear();

			jmethodID blaah = env->GetMethodID(inputStreamClass, "read", "([B)I");
			jbyteArray array = env->NewByteArray(4096);
			int g = 0;
			std::string content;
			__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "going in while");

			while ((g = env->CallIntMethod(input, blaah, array)) != -1) {
				__android_log_print(ANDROID_LOG_INFO, "AndroidClient", " stream =  %i", g);

				jbyte* content_array = env->GetByteArrayElements(array, NULL);
				content += std::string((char*)content_array, g);

				env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);

			}

			__android_log_print(ANDROID_LOG_INFO, "content", "contentti = %s", content.c_str());

			//env->CallVoidMethod(input, inputStreamCloseMethod);

			return HTTPResponse(responseCode, errorMessage, "", content);
		}
  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}

<commit_msg>Remove unnecessary debug code<commit_after>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	bufferedReaderClass = env->FindClass("java/io/BufferedReader");
	 	inputStreamReaderClass = env->FindClass("java/io/InputStreamReader");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

	 	readerCloseMethod = env->GetMethodID(bufferedReaderClass, "close", "()V");
	 	readLineMethod = env->GetMethodID(bufferedReaderClass, "readLine", "()Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "()I");
	 	inputStreamReaderConstructor = env->GetMethodID(inputStreamReaderClass, "<init>", "(Ljava/io/InputStream;)V");
	 	bufferedReaderConstructor = env->GetMethodID(bufferedReaderClass, "<init>", "(Ljava/io/Reader;)V");
		urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");
		inputStreamCloseMethod = env->GetMethodID(inputStreamClass, "close", "()V");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	//jobject url = env->NewObject(urlClass, urlConstructor, "sometrik.com");
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		//Set Follow enabled
		switch (req.getType()) {
		case HTTPRequest::POST:
		  	env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
				 env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));;
			break;
		}

			int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

			if (env->ExceptionCheck()) {
			   env->ExceptionClear();
				__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCPETION http request responsecode = %i", responseCode);
			  return HTTPResponse(0, "exception");
			}
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

			const char *errorMessage = "";

		if (responseCode >= 400 && responseCode <= 599){
			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

		}

		jobject input = env->CallObjectMethod(connection, getInputStreamMethod);
		env->ExceptionClear();

		jmethodID blaah = env->GetMethodID(inputStreamClass, "read", "([B)I");
		jbyteArray array = env->NewByteArray(4096);
		int g = 0;
		std::string content;

		while ((g = env->CallIntMethod(input, blaah, array)) != -1) {

			jbyte* content_array = env->GetByteArrayElements(array, NULL);
			if (callback) {
				callback->handleChunk(g, (char*) content_array);
			} else {
				content += std::string((char*) content_array, g);
			}

			env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);

		}

		__android_log_print(ANDROID_LOG_INFO, "content", "contentti = %Ld", content.size());

		return HTTPResponse(responseCode, errorMessage, "", content);

  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}

<|endoftext|>


<commit_before>// FitsRequestHandler.cc

// This file is part of fits_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2004,2005 University Corporation for Atmospheric Research
// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact University Corporation for Atmospheric Research at
// 3080 Center Green Drive, Boulder, CO 80301

// (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005
// Please read the full copyright statement in the file COPYRIGHT_UCAR.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>
//      jgarcia     Jose Garcia <jgarcia@ucar.edu>

#include "config.h"

#include <DAS.h>
#include <DDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <InternalErr.h>
#include <mime_util.h>

#include <BESResponseHandler.h>
#include <BESDapError.h>

#include <BESDapNames.h>
#include <BESResponseNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>

#include <BESVersionInfo.h>
#include <BESConstraintFuncs.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>

#include <fitsio.h>

#include "FitsRequestHandler.h"
#include "fits_read_attributes.h"
#include "fits_read_descriptors.h"

#define FITS_NAME "fits"

FitsRequestHandler::FitsRequestHandler(const string &name) :
		BESRequestHandler(name)
{
	add_handler(DAS_RESPONSE, FitsRequestHandler::fits_build_das);
	add_handler(DDS_RESPONSE, FitsRequestHandler::fits_build_dds);
	add_handler(DATA_RESPONSE, FitsRequestHandler::fits_build_data);

	add_handler(DMR_RESPONSE, FitsRequestHandler::fits_build_dmr);
	add_handler(DAP4DATA_RESPONSE, FitsRequestHandler::fits_build_dmr);

	add_handler(VERS_RESPONSE, FitsRequestHandler::fits_build_vers);
	add_handler(HELP_RESPONSE, FitsRequestHandler::fits_build_help);
}

FitsRequestHandler::~FitsRequestHandler()
{
}

bool FitsRequestHandler::fits_build_das(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
	if (!bdas) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdas->set_container(dhi.container->get_symbolic_name());
		DAS *das = bdas->get_das();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);
		bdas->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS das response", true, unknown_error, __FILE__, __LINE__);
	}
	return true;
}

bool FitsRequestHandler::fits_build_dds(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;

		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}

		Ancillary::read_ancillary_dds(*dds, accessed);
		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS dds response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

bool FitsRequestHandler::fits_build_data(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DataDDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_dds(*dds, accessed);

		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS data response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

/**
 * Build a DMR object. This method builds a DMR by first building a DDS
 * that is loaded with attributes and then using that to make a DMR. This
 * method can be used by both the DAP4 metadata and data responses - because
 * the DMR is the C++ object used for both by libdap.
 *
 * @note The CSV handler has a version of this method that contains some
 * more commentary.
 *
 * @param dhi
 * @return true or throws an exception on error
 */
bool FitsRequestHandler::fits_build_dmr(BESDataHandlerInterface &dhi)
{
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		string fits_error;

		if (!fits_handler::fits_read_descriptors(dds, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);

		DAS das;
		if (!fits_handler::fits_read_attributes(das, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		Ancillary::read_ancillary_das(das, data_path);

		dds.transfer_attributes(&das);
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Remove the existing DMR and set the newly made one
	DMR *dmr = bdmr.get_dmr();
	dmr->set_factory(new D4BaseTypeFactory);
	dmr->build_using_dds(dds);

	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	return true;
}

bool FitsRequestHandler::fits_build_vers(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	info->add_module(PACKAGE_NAME, PACKAGE_VERSION);

	return true;
}

bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESInfo *info = dynamic_cast<BESInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	map<string, string> attrs;
	attrs["name"] = PACKAGE_NAME;
	attrs["version"] = PACKAGE_VERSION;
	list<string> services;
	BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
	if (services.size() > 0) {
		string handles = BESUtil::implode(services, ',');
		attrs["handles"] = handles;
	}
	info->begin_tag("module", &attrs);
	info->end_tag("module");

	return true;
}

/** @brief dumps information about this object
 *
 * Displays the pointer value of this instance, the name of the request
 * handler, and the names of all registered handler functions
 *
 * @param strm C++ i/o stream to dump the information to
 */
void FitsRequestHandler::dump(ostream &strm) const
{
	strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
	BESIndent::Indent();
	BESRequestHandler::dump(strm);
	BESIndent::UnIndent();
}

<commit_msg>commets<commit_after>// FitsRequestHandler.cc

// This file is part of fits_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2004,2005 University Corporation for Atmospheric Research
// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact University Corporation for Atmospheric Research at
// 3080 Center Green Drive, Boulder, CO 80301

// (c) COPYRIGHT University Corporation for Atmostpheric Research 2004-2005
// Please read the full copyright statement in the file COPYRIGHT_UCAR.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>
//      jgarcia     Jose Garcia <jgarcia@ucar.edu>

#include "config.h"

#include <DAS.h>
#include <DDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <InternalErr.h>
#include <mime_util.h>

#include <BESResponseHandler.h>
#include <BESDapError.h>

#include <BESDapNames.h>
#include <BESResponseNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>

#include <BESVersionInfo.h>
#include <BESConstraintFuncs.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>

#include <fitsio.h>

#include "FitsRequestHandler.h"
#include "fits_read_attributes.h"
#include "fits_read_descriptors.h"

#define FITS_NAME "fits"

FitsRequestHandler::FitsRequestHandler(const string &name) :
		BESRequestHandler(name)
{
	add_handler(DAS_RESPONSE, FitsRequestHandler::fits_build_das);
	add_handler(DDS_RESPONSE, FitsRequestHandler::fits_build_dds);
	add_handler(DATA_RESPONSE, FitsRequestHandler::fits_build_data);

	add_handler(DMR_RESPONSE, FitsRequestHandler::fits_build_dmr);
	add_handler(DAP4DATA_RESPONSE, FitsRequestHandler::fits_build_dmr);

	add_handler(VERS_RESPONSE, FitsRequestHandler::fits_build_vers);
	add_handler(HELP_RESPONSE, FitsRequestHandler::fits_build_help);
}

FitsRequestHandler::~FitsRequestHandler()
{
}

bool FitsRequestHandler::fits_build_das(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
	if (!bdas) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdas->set_container(dhi.container->get_symbolic_name());
		DAS *das = bdas->get_das();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);
		bdas->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS das response", true, unknown_error, __FILE__, __LINE__);
	}
	return true;
}

bool FitsRequestHandler::fits_build_dds(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;

		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}

		Ancillary::read_ancillary_dds(*dds, accessed);
		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS dds response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

bool FitsRequestHandler::fits_build_data(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
	if (!bdds) throw BESInternalError("cast error", __FILE__, __LINE__);

	try {
		bdds->set_container(dhi.container->get_symbolic_name());
		DataDDS *dds = bdds->get_dds();
		string accessed = dhi.container->access();
		string fits_error;
		if (!fits_handler::fits_read_descriptors(*dds, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_dds(*dds, accessed);

		DAS *das = new DAS;
		BESDASResponse bdas(das);
		bdas.set_container(dhi.container->get_symbolic_name());
		if (!fits_handler::fits_read_attributes(*das, accessed, fits_error)) {
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		}
		Ancillary::read_ancillary_das(*das, accessed);

		dds->transfer_attributes(das);

		bdds->set_constraint(dhi);

		bdds->clear_container();
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		string err = "Unknown exception caught building FITS data response";
		throw BESDapError(err, true, unknown_error, __FILE__, __LINE__);
	}

	return true;
}

/**
 * Build a DMR object. This method builds a DMR by first building a DDS
 * that is loaded with attributes and then using that to make a DMR. This
 * method can be used by both the DAP4 metadata and data responses - because
 * the DMR is the C++ object used for both by libdap.
 *
 * @note The CSV handler has a version of this method that contains some
 * more commentary.
 *
 * @param dhi
 * @return true or throws an exception on error
 */
bool FitsRequestHandler::fits_build_dmr(BESDataHandlerInterface &dhi)
{
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		string fits_error;

		if (!fits_handler::fits_read_descriptors(dds, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);

		DAS das;
		if (!fits_handler::fits_read_attributes(das, data_path, fits_error))
			throw BESDapError(fits_error, false, unknown_error, __FILE__, __LINE__);
		Ancillary::read_ancillary_das(das, data_path);

		dds.transfer_attributes(&das);
	}
	catch( InternalErr &e ) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( Error &e ) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch( ... ) {
		throw BESDapError("Unknown exception caught building FITS DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	DMR *dmr = bdmr.get_dmr();
	dmr->set_factory(new D4BaseTypeFactory);
	dmr->build_using_dds(dds);

	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	return true;
}

bool FitsRequestHandler::fits_build_vers(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	info->add_module(PACKAGE_NAME, PACKAGE_VERSION);

	return true;
}

bool FitsRequestHandler::fits_build_help(BESDataHandlerInterface &dhi)
{
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESInfo *info = dynamic_cast<BESInfo *>(response);
	if (!info) throw BESInternalError("cast error", __FILE__, __LINE__);

	map<string, string> attrs;
	attrs["name"] = PACKAGE_NAME;
	attrs["version"] = PACKAGE_VERSION;
	list<string> services;
	BESServiceRegistry::TheRegistry()->services_handled(FITS_NAME, services);
	if (services.size() > 0) {
		string handles = BESUtil::implode(services, ',');
		attrs["handles"] = handles;
	}
	info->begin_tag("module", &attrs);
	info->end_tag("module");

	return true;
}

/** @brief dumps information about this object
 *
 * Displays the pointer value of this instance, the name of the request
 * handler, and the names of all registered handler functions
 *
 * @param strm C++ i/o stream to dump the information to
 */
void FitsRequestHandler::dump(ostream &strm) const
{
	strm << BESIndent::LMarg << "FitsRequestHandler::dump - (" << (void *) this << ")" << endl;
	BESIndent::Indent();
	BESRequestHandler::dump(strm);
	BESIndent::UnIndent();
}

<|endoftext|>


<commit_before>/// @brief provides CORDIC for cos function
/// @ref see H. Dawid, H. Meyr, "CORDIC Algorithms and Architectures"

namespace std {
    template<typename T, size_t n, size_t f, class op, class up>
    utils::number<T, n, f, op, up> cos(utils::number<T, n, f, op, up> const& x)
    {
        #define iterations 20

        static double lut[64] = {

        }
    }
}
<commit_msg>works fine<commit_after>/// @brief provides CORDIC for cos function
/// @ref see H. Dawid, H. Meyr, "CORDIC Algorithms and Architectures"

#include "./../../fixed_point_lib/src/CORDIC/lut/arctan_lut.hpp"

namespace std {
    template<typename T, size_t n, size_t f, class op, class up>
    utils::number<T, n, f, op, up> cos(utils::number<T, n, f, op, up> const& val)
    {
        typedef utils::number<T, n, f, op, up> fixed_point;
        BOOST_STATIC_ASSERT(std::numeric_limits<fixed_point>::is_signed);
        BOOST_STATIC_ASSERT(64u > f);

        static utils::cordic::arctan_lut<64u, fixed_point> const lut;

        // normalization factor: see page 10, table 24.1 and pages 4-5, equations
        // (5)-(6)
        // factor converges to the limit 1.64676 very fast: it tooks 8 iterations
        // only. 8 iterations correpsonds to precision of size 0.007812 for
        // angle approximation
        static fixed_point norm_factor(1.0 / 1.64676);

        assert(("illegal argument", std::fabs(val) <= fixed_point(1.0)));

        // rotation mode: see page 6
        // shift sequence is just 0, 1, ... (circular coordinate system)
        fixed_point x(norm_factor), y(0.0), z(val);
        fixed_point x1, y1, z1;
        BOOST_FOREACH(size_t i, boost::irange<size_t>(0, std::min(64u, f), 1))
        {
            int const sign = (z > fixed_point(0)) ? 1 : -1;
            fixed_point const x_scaled = fixed_point::wrap(sign * (x.value() >> i));
            fixed_point const y_scaled = fixed_point::wrap(sign * (y.value() >> i));

            x1 = fixed_point(x - y_scaled);
            y1 = fixed_point(y + x_scaled);
            z1 = fixed_point(z - fixed_point((sign > 0) ? lut[i] : -lut[i]));

            x = x1; y = y1; z = z1;
        }

        return x;
    }
}
<|endoftext|>


<commit_before>#include "LLVM_Headers.h"
#include "CodeGen_X86.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Debug.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "integer_division_table.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::stack;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix() :
    CodeGen(),

    // Vector types. These need an LLVMContext before they can be initialized.
    i8x8(NULL),
    i8x16(NULL),
    i8x32(NULL),
    i16x4(NULL),
    i16x8(NULL),
    i16x16(NULL),
    i32x2(NULL),
    i32x4(NULL),
    i32x8(NULL),
    i64x2(NULL),
    i64x4(NULL),
    f32x2(NULL),
    f32x4(NULL),
    f32x8(NULL),
    f64x2(NULL),
    f64x4(NULL),

    // Wildcards for pattern matching
    wild_i8x8(Variable::make(Int(8, 8), "*")),
    wild_i16x4(Variable::make(Int(16, 4), "*")),
    wild_i32x2(Variable::make(Int(32, 2), "*")),

    wild_u8x8(Variable::make(UInt(8, 8), "*")),
    wild_u16x4(Variable::make(UInt(16, 4), "*")),
    wild_u32x2(Variable::make(UInt(32, 2), "*")),

    wild_i8x16(Variable::make(Int(8, 16), "*")),
    wild_i16x8(Variable::make(Int(16, 8), "*")),
    wild_i32x4(Variable::make(Int(32, 4), "*")),
    wild_i64x2(Variable::make(Int(64, 2), "*")),

    wild_u8x16(Variable::make(UInt(8, 16), "*")),
    wild_u16x8(Variable::make(UInt(16, 8), "*")),
    wild_u32x4(Variable::make(UInt(32, 4), "*")),
    wild_u64x2(Variable::make(UInt(64, 2), "*")),

    wild_i8x32(Variable::make(Int(8, 32), "*")),
    wild_i16x16(Variable::make(Int(16, 16), "*")),
    wild_i32x8(Variable::make(Int(32, 8), "*")),
    wild_i64x4(Variable::make(Int(64, 4), "*")),

    wild_u8x32(Variable::make(UInt(8, 32), "*")),
    wild_u16x16(Variable::make(UInt(16, 16), "*")),
    wild_u32x8(Variable::make(UInt(32, 8), "*")),
    wild_u64x4(Variable::make(UInt(64, 4), "*")),

    wild_f32x2(Variable::make(Float(32, 2), "*")),

    wild_f32x4(Variable::make(Float(32, 4), "*")),
    wild_f64x2(Variable::make(Float(64, 2), "*")),

    wild_f32x8(Variable::make(Float(32, 8), "*")),
    wild_f64x4(Variable::make(Float(64, 4), "*")),

    // Bounds of types
    min_i8(Int(8).min()),
    max_i8(Int(8).max()),
    max_u8(UInt(8).max()),

    min_i16(Int(16).min()),
    max_i16(Int(16).max()),
    max_u16(UInt(16).max()),

    min_i32(Int(32).min()),
    max_i32(Int(32).max()),
    max_u32(UInt(32).max()),

    min_i64(Int(64).min()),
    max_i64(Int(64).max()),
    max_u64(UInt(64).max()),

    min_f32(Float(32).min()),
    max_f32(Float(32).max()),

    min_f64(Float(64).min()),
    max_f64(Float(64).max()) {

}

void CodeGen_Posix::init_module() {
    CodeGen::init_module();

    i8x8 = VectorType::get(i8, 8);
    i8x16 = VectorType::get(i8, 16);
    i8x32 = VectorType::get(i8, 32);
    i16x4 = VectorType::get(i16, 4);
    i16x8 = VectorType::get(i16, 8);
    i16x16 = VectorType::get(i16, 16);
    i32x2 = VectorType::get(i32, 2);
    i32x4 = VectorType::get(i32, 4);
    i32x8 = VectorType::get(i32, 8);
    i64x2 = VectorType::get(i64, 2);
    i64x4 = VectorType::get(i64, 4);
    f32x2 = VectorType::get(f32, 2);
    f32x4 = VectorType::get(f32, 4);
    f32x8 = VectorType::get(f32, 8);
    f64x2 = VectorType::get(f64, 2);
    f64x4 = VectorType::get(f64, 4);
}

Value *CodeGen_Posix::save_stack() {
    llvm::Function *stacksave =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stacksave);
    return builder->CreateCall(stacksave);
}

void CodeGen_Posix::restore_stack(llvm::Value *saved_stack) {
    llvm::Function *stackrestore =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stackrestore);
    builder->CreateCall(stackrestore, saved_stack);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type, Expr size) {

    Allocation allocation;

    int bytes_per_element = type.bits / 8;
    if (const IntImm *int_size = size.as<IntImm>()) {
        allocation.stack_size = int_size->value * bytes_per_element;

        // Round up to nearest multiple of 32.
        allocation.stack_size = ((allocation.stack_size + 31)/32)*32;

        // If it's more than 8k, put it on the heap.
        if (allocation.stack_size > 8*1024) {
            allocation.stack_size = 0;
        }
    } else {
        allocation.stack_size = 0;
    }

    llvm::Type *llvm_type = llvm_type_of(type);

    if (allocation.stack_size) {
        // Do a new 32-byte aligned alloca
        allocation.saved_stack = save_stack();
        Value *size = ConstantInt::get(i32, allocation.stack_size/32);
        Value *ptr = builder->CreateAlloca(i32x8, size, name);
        allocation.ptr = builder->CreatePointerCast(ptr, llvm_type->getPointerTo());
    } else {
        allocation.saved_stack = NULL;
        Value *llvm_size = codegen(size * bytes_per_element);

        // call malloc
        llvm::Function *malloc_fn = module->getFunction("halide_malloc");
        malloc_fn->setDoesNotAlias(0);
        assert(malloc_fn && "Could not find halide_malloc in module");

        llvm_size = builder->CreateIntCast(llvm_size, malloc_fn->arg_begin()->getType(), false);

        debug(4) << "Creating call to halide_malloc\n";
        CallInst *call = builder->CreateCall(malloc_fn, llvm_size);
        allocation.ptr = call;
    }

    // Push the allocation base pointer onto the symbol table
    debug(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);
    sym_push(name + ".host", allocation.ptr);

    return allocation;
}

void CodeGen_Posix::free_allocation(const std::string &name) {
    Allocation alloc = allocations.get(name);

    if (alloc.stack_size) {
        // Free is a no-op for stack allocations
    } else {
        // Call free
        llvm::Function *free_fn = module->getFunction("halide_free");
        assert(free_fn && "Could not find halide_free in module");
        debug(4) << "Creating call to halide_free\n";
        builder->CreateCall(free_fn, alloc.ptr);
    }

    sym_pop(name + ".host");
    allocations.pop(name);
}

void CodeGen_Posix::destroy_allocation(Allocation alloc) {

    if (alloc.saved_stack) {
        restore_stack(alloc.saved_stack);
    }

    // Heap allocations have already been freed.
}

void CodeGen_Posix::visit(const Allocate *alloc) {

    Allocation allocation = create_allocation(alloc->name, alloc->type, alloc->size);

    codegen(alloc->body);

    // Should have been freed
    assert(!sym_exists(alloc->name + ".host"));
    assert(!allocations.contains(alloc->name));

    debug(2) << "Destroying allocation " << alloc->name << "\n";
    destroy_allocation(allocation);
}

void CodeGen_Posix::visit(const Free *stmt) {
    free_allocation(stmt->name);
}

void CodeGen_Posix::prepare_for_early_exit() {
    // We've jumped to a code path that will be called just before
    // bailing out. Free everything outstanding.
    for (Scope<Allocation>::iterator iter = allocations.begin();
         iter != allocations.end(); ++iter) {
        const string &name = (*iter);
        std::vector<Allocation> stash;
        while (allocations.contains(name)) {
            stash.push_back(allocations.get(name));
            free_allocation(name);
        }

        // Restore all the allocations before we jump back to the main
        // code path.
        for (size_t i = stash.size(); i > 0; i--) {
            allocations.push(name, stash[i-1]);
            sym_push(name + ".host", stash[i-1].ptr);
        }
    }
}

}}
<commit_msg>Fixed corruption of the allocations scope when bailing out early<commit_after>#include "LLVM_Headers.h"
#include "CodeGen_X86.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Debug.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "integer_division_table.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::stack;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix() :
    CodeGen(),

    // Vector types. These need an LLVMContext before they can be initialized.
    i8x8(NULL),
    i8x16(NULL),
    i8x32(NULL),
    i16x4(NULL),
    i16x8(NULL),
    i16x16(NULL),
    i32x2(NULL),
    i32x4(NULL),
    i32x8(NULL),
    i64x2(NULL),
    i64x4(NULL),
    f32x2(NULL),
    f32x4(NULL),
    f32x8(NULL),
    f64x2(NULL),
    f64x4(NULL),

    // Wildcards for pattern matching
    wild_i8x8(Variable::make(Int(8, 8), "*")),
    wild_i16x4(Variable::make(Int(16, 4), "*")),
    wild_i32x2(Variable::make(Int(32, 2), "*")),

    wild_u8x8(Variable::make(UInt(8, 8), "*")),
    wild_u16x4(Variable::make(UInt(16, 4), "*")),
    wild_u32x2(Variable::make(UInt(32, 2), "*")),

    wild_i8x16(Variable::make(Int(8, 16), "*")),
    wild_i16x8(Variable::make(Int(16, 8), "*")),
    wild_i32x4(Variable::make(Int(32, 4), "*")),
    wild_i64x2(Variable::make(Int(64, 2), "*")),

    wild_u8x16(Variable::make(UInt(8, 16), "*")),
    wild_u16x8(Variable::make(UInt(16, 8), "*")),
    wild_u32x4(Variable::make(UInt(32, 4), "*")),
    wild_u64x2(Variable::make(UInt(64, 2), "*")),

    wild_i8x32(Variable::make(Int(8, 32), "*")),
    wild_i16x16(Variable::make(Int(16, 16), "*")),
    wild_i32x8(Variable::make(Int(32, 8), "*")),
    wild_i64x4(Variable::make(Int(64, 4), "*")),

    wild_u8x32(Variable::make(UInt(8, 32), "*")),
    wild_u16x16(Variable::make(UInt(16, 16), "*")),
    wild_u32x8(Variable::make(UInt(32, 8), "*")),
    wild_u64x4(Variable::make(UInt(64, 4), "*")),

    wild_f32x2(Variable::make(Float(32, 2), "*")),

    wild_f32x4(Variable::make(Float(32, 4), "*")),
    wild_f64x2(Variable::make(Float(64, 2), "*")),

    wild_f32x8(Variable::make(Float(32, 8), "*")),
    wild_f64x4(Variable::make(Float(64, 4), "*")),

    // Bounds of types
    min_i8(Int(8).min()),
    max_i8(Int(8).max()),
    max_u8(UInt(8).max()),

    min_i16(Int(16).min()),
    max_i16(Int(16).max()),
    max_u16(UInt(16).max()),

    min_i32(Int(32).min()),
    max_i32(Int(32).max()),
    max_u32(UInt(32).max()),

    min_i64(Int(64).min()),
    max_i64(Int(64).max()),
    max_u64(UInt(64).max()),

    min_f32(Float(32).min()),
    max_f32(Float(32).max()),

    min_f64(Float(64).min()),
    max_f64(Float(64).max()) {

}

void CodeGen_Posix::init_module() {
    CodeGen::init_module();

    i8x8 = VectorType::get(i8, 8);
    i8x16 = VectorType::get(i8, 16);
    i8x32 = VectorType::get(i8, 32);
    i16x4 = VectorType::get(i16, 4);
    i16x8 = VectorType::get(i16, 8);
    i16x16 = VectorType::get(i16, 16);
    i32x2 = VectorType::get(i32, 2);
    i32x4 = VectorType::get(i32, 4);
    i32x8 = VectorType::get(i32, 8);
    i64x2 = VectorType::get(i64, 2);
    i64x4 = VectorType::get(i64, 4);
    f32x2 = VectorType::get(f32, 2);
    f32x4 = VectorType::get(f32, 4);
    f32x8 = VectorType::get(f32, 8);
    f64x2 = VectorType::get(f64, 2);
    f64x4 = VectorType::get(f64, 4);
}

Value *CodeGen_Posix::save_stack() {
    llvm::Function *stacksave =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stacksave);
    return builder->CreateCall(stacksave);
}

void CodeGen_Posix::restore_stack(llvm::Value *saved_stack) {
    llvm::Function *stackrestore =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stackrestore);
    builder->CreateCall(stackrestore, saved_stack);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type, Expr size) {

    Allocation allocation;

    int bytes_per_element = type.bits / 8;
    if (const IntImm *int_size = size.as<IntImm>()) {
        allocation.stack_size = int_size->value * bytes_per_element;

        // Round up to nearest multiple of 32.
        allocation.stack_size = ((allocation.stack_size + 31)/32)*32;

        // If it's more than 8k, put it on the heap.
        if (allocation.stack_size > 8*1024) {
            allocation.stack_size = 0;
        }
    } else {
        allocation.stack_size = 0;
    }

    llvm::Type *llvm_type = llvm_type_of(type);

    if (allocation.stack_size) {
        // Do a new 32-byte aligned alloca
        allocation.saved_stack = save_stack();
        Value *size = ConstantInt::get(i32, allocation.stack_size/32);
        Value *ptr = builder->CreateAlloca(i32x8, size, name);
        allocation.ptr = builder->CreatePointerCast(ptr, llvm_type->getPointerTo());
    } else {
        allocation.saved_stack = NULL;
        Value *llvm_size = codegen(size * bytes_per_element);

        // call malloc
        llvm::Function *malloc_fn = module->getFunction("halide_malloc");
        malloc_fn->setDoesNotAlias(0);
        assert(malloc_fn && "Could not find halide_malloc in module");

        llvm_size = builder->CreateIntCast(llvm_size, malloc_fn->arg_begin()->getType(), false);

        debug(4) << "Creating call to halide_malloc\n";
        CallInst *call = builder->CreateCall(malloc_fn, llvm_size);
        allocation.ptr = call;
    }

    // Push the allocation base pointer onto the symbol table
    debug(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);
    sym_push(name + ".host", allocation.ptr);

    return allocation;
}

void CodeGen_Posix::free_allocation(const std::string &name) {
    Allocation alloc = allocations.get(name);

    if (alloc.stack_size) {
        // Free is a no-op for stack allocations
    } else {
        // Call free
        llvm::Function *free_fn = module->getFunction("halide_free");
        assert(free_fn && "Could not find halide_free in module");
        debug(4) << "Creating call to halide_free\n";
        builder->CreateCall(free_fn, alloc.ptr);
    }

    sym_pop(name + ".host");
    allocations.pop(name);
}

void CodeGen_Posix::destroy_allocation(Allocation alloc) {

    if (alloc.saved_stack) {
        restore_stack(alloc.saved_stack);
    }

    // Heap allocations have already been freed.
}

void CodeGen_Posix::visit(const Allocate *alloc) {

    Allocation allocation = create_allocation(alloc->name, alloc->type, alloc->size);

    codegen(alloc->body);

    // Should have been freed
    assert(!sym_exists(alloc->name + ".host"));
    assert(!allocations.contains(alloc->name));

    debug(2) << "Destroying allocation " << alloc->name << "\n";
    destroy_allocation(allocation);
}

void CodeGen_Posix::visit(const Free *stmt) {
    free_allocation(stmt->name);
}

void CodeGen_Posix::prepare_for_early_exit() {
    // We've jumped to a code path that will be called just before
    // bailing out. Free everything outstanding.
    vector<string> names;
    for (Scope<Allocation>::iterator iter = allocations.begin();
         iter != allocations.end(); ++iter) {
        names.push_back(*iter);
    }

    for (size_t i = 0; i < names.size(); i++) {
        std::vector<Allocation> stash;
        while (allocations.contains(names[i])) {
            stash.push_back(allocations.get(names[i]));
            free_allocation(names[i]);
        }

        // Restore all the allocations before we jump back to the main
        // code path.
        for (size_t j = stash.size(); j > 0; j--) {
            allocations.push(names[i], stash[j-1]);
            sym_push(names[i] + ".host", stash[j-1].ptr);
        }
    }
}

}}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <osg/GL>
#include <osgGLUT/glut>
#include <osgGLUT/Viewer>

#include <osg/Node>
#include <osg/Notify>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/AnimationPathManipulator>

#include <osgUtil/Optimizer>

struct SortByAverageDistanceFunctor
{
    bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
    {
        return lhs->getAverageDistance()<rhs->getAverageDistance();
    }
};

struct SortByMinimumDistanceFunctor
{
    bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
    {
        return lhs->getMinimumDistance()<rhs->getMinimumDistance();
    }
};

struct MySortCallback : public osgUtil::RenderBin::SortCallback
{
    virtual void sortImplementation(osgUtil::RenderBin* renderbin)
    {

        osgUtil::RenderBin::RenderGraphList& renderGraphList = renderbin->_renderGraphList;
        for(osgUtil::RenderBin::RenderGraphList::iterator itr=renderGraphList.begin();
            itr!=renderGraphList.end();
            ++itr)
        {
            (*itr)->sortFrontToBack();
        }

//        std::sort(renderGraphList.begin(),renderGraphList.end(),SortByAverageDistanceFunctor());
       std::sort(renderGraphList.begin(),renderGraphList.end(),SortByMinimumDistanceFunctor());
    }
};

void write_usage(std::ostream& out,const std::string& name)
{
    out << std::endl;
    out <<"usage:"<< std::endl;
    out <<"    "<<name<<" [options] infile1 [infile2 ...]"<< std::endl;
    out << std::endl;
    out <<"options:"<< std::endl;
    out <<"    -l libraryName      - load plugin of name libraryName"<< std::endl;
    out <<"                          i.e. -l osgdb_pfb"<< std::endl;
    out <<"                          Useful for loading reader/writers which can load"<< std::endl;
    out <<"                          other file formats in addition to its extension."<< std::endl;
    out <<"    -e extensionName    - load reader/wrter plugin for file extension"<< std::endl;
    out <<"                          i.e. -e pfb"<< std::endl;
    out <<"                          Useful short hand for specifying full library name as"<< std::endl;
    out <<"                          done with -l above, as it automatically expands to"<< std::endl;
    out <<"                          the full library name appropriate for each platform."<< std::endl;
    out <<std::endl;
    out <<"    -stereo             - switch on stereo rendering, using the default of,"<< std::endl;
    out <<"                          ANAGLYPHIC or the value set in the OSG_STEREO_MODE "<< std::endl;
    out <<"                          environmental variable. See doc/stereo.html for "<< std::endl;
    out <<"                          further details on setting up accurate stereo "<< std::endl;
    out <<"                          for your system. "<< std::endl;
    out <<"    -stereo ANAGLYPHIC  - switch on anaglyphic(red/cyan) stereo rendering."<< std::endl;
    out <<"    -stereo QUAD_BUFFER - switch on quad buffered stereo rendering."<< std::endl;
    out <<std::endl;
    out <<"    -stencil            - use a visual with stencil buffer enabled, this "<< std::endl;
    out <<"                          also allows the depth complexity statistics mode"<< std::endl;
    out <<"                          to be used (press 'p' three times to cycle to it)."<< std::endl;
    out <<"    -f                  - start with a full screen, borderless window." << std::endl;
    out <<"    -p  pathfile        - Use the AnimationPathManipulator (key binding '4') and use\n"
	  "                          pathfile to define the animation path.  pathfile is an ascii\n"
	  "                          file containing lines of eight floating point numbers representing\n"
	  "                          time, position (x,y,z) and attitude (x,y,z,w as a quaternion)." << std::endl;
    out << std::endl;
}

int main( int argc, char **argv )
{
    std::string pathfile;

    // initialize the GLUT
    glutInit( &argc, argv );

    if (argc<2)
    {
        write_usage(std::cout,argv[0]);
        return 1;
    }

    // create the commandline args.
    std::vector<std::string> commandLine;
    for(int i=1;i<argc;++i) {
	if( std::string(argv[i]) == "-p" ) {
	    if( (i+1) >= argc ) {
		write_usage( std::cout, argv[0]);
	    	return 1;
	    }
	    else
		pathfile = std::string(argv[++i]);
	}
	else
	    commandLine.push_back(argv[i]);
    }

    // initialize the viewer.
    osgGLUT::Viewer viewer;
    viewer.setWindowTitle(argv[0]);

    // configure the viewer from the commandline arguments, and eat any
    // parameters that have been matched.
    viewer.readCommandLine(commandLine);

    // configure the plugin registry from the commandline arguments, and
    // eat any parameters that have been matched.
    osgDB::readCommandLine(commandLine);

    // load the nodes from the commandline arguments.
    osg::Node* rootnode = osgDB::readNodeFiles(commandLine);
    if (!rootnode)
    {
        return 1;
    }

    // run optimization over the scene graph
    osgUtil::Optimizer optimzer;
    optimzer.optimize(rootnode);

    // add a viewport to the viewer and attach the scene graph.
    viewer.addViewport( rootnode );

    // register trackball, flight and drive.
    viewer.registerCameraManipulator(new osgGA::TrackballManipulator);
    viewer.registerCameraManipulator(new osgGA::FlightManipulator);
    viewer.registerCameraManipulator(new osgGA::DriveManipulator);

    if( !pathfile.empty() ) {
	osgGA::AnimationPathManipulator *apm = new osgGA::AnimationPathManipulator(pathfile);
	if( apm->valid() )
        {
            //viewer.registerCameraManipulator(apm);
            // selecting the animation path manipulator up front seems to disable view frustum
            // in a heavy duty way that I'm do understand yet, so I'm commenting out for the
            // time being.  Simply pressing '4' will get you the animation path working correctly.
            unsigned int no = viewer.registerCameraManipulator(apm);
            viewer.selectCameraManipulator(no);
        }
	else
	    delete apm;
    }

//     osgUtil::RenderBin* depth_renderbin = osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin");
//     if (depth_renderbin)
//     {
//         depth_renderbin->setSortMode(osgUtil::RenderBin::SORT_BY_STATE);
//     }

    osgUtil::RenderStage* renderstage = viewer.getViewportSceneView(0)->getRenderStage();
    if (renderstage)
    {
       renderstage->setSortCallback(new MySortCallback);
//        renderstage->setSortMode(osgUtil::RenderBin::SORT_FRONT_TO_BACK);
    }

    // open the viewer window.
    viewer.open();

    // fire up the event loop.
    viewer.run();

    return 0;
}
<commit_msg>Added usage info in -O option.<commit_after>#include <stdio.h>
#include <osg/GL>
#include <osgGLUT/glut>
#include <osgGLUT/Viewer>

#include <osg/Node>
#include <osg/Notify>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/AnimationPathManipulator>

#include <osgUtil/Optimizer>

struct SortByAverageDistanceFunctor
{
    bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
    {
        return lhs->getAverageDistance()<rhs->getAverageDistance();
    }
};

struct SortByMinimumDistanceFunctor
{
    bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
    {
        return lhs->getMinimumDistance()<rhs->getMinimumDistance();
    }
};

struct MySortCallback : public osgUtil::RenderBin::SortCallback
{
    virtual void sortImplementation(osgUtil::RenderBin* renderbin)
    {

        osgUtil::RenderBin::RenderGraphList& renderGraphList = renderbin->_renderGraphList;
        for(osgUtil::RenderBin::RenderGraphList::iterator itr=renderGraphList.begin();
            itr!=renderGraphList.end();
            ++itr)
        {
            (*itr)->sortFrontToBack();
        }

//        std::sort(renderGraphList.begin(),renderGraphList.end(),SortByAverageDistanceFunctor());
       std::sort(renderGraphList.begin(),renderGraphList.end(),SortByMinimumDistanceFunctor());
    }
};

void write_usage(std::ostream& out,const std::string& name)
{
    out << std::endl;
    out <<"usage:"<< std::endl;
    out <<"    "<<name<<" [options] infile1 [infile2 ...]"<< std::endl;
    out << std::endl;
    out <<"options:"<< std::endl;
    out <<"    -l libraryName      - load plugin of name libraryName"<< std::endl;
    out <<"                          i.e. -l osgdb_pfb"<< std::endl;
    out <<"                          Useful for loading reader/writers which can load"<< std::endl;
    out <<"                          other file formats in addition to its extension."<< std::endl;
    out <<"    -e extensionName    - load reader/wrter plugin for file extension"<< std::endl;
    out <<"                          i.e. -e pfb"<< std::endl;
    out <<"                          Useful short hand for specifying full library name as"<< std::endl;
    out <<"                          done with -l above, as it automatically expands to"<< std::endl;
    out <<"                          the full library name appropriate for each platform."<< std::endl;
    out <<std::endl;
    out <<"    -O \"options string\" - create an options string to pass to the reader/wrter "<< std::endl;
    out <<"                          for controlling reading and writing parameters."<< std::endl;
    out <<std::endl;
    out <<"    -stereo             - switch on stereo rendering, using the default of,"<< std::endl;
    out <<"                          ANAGLYPHIC or the value set in the OSG_STEREO_MODE "<< std::endl;
    out <<"                          environmental variable. See doc/stereo.html for "<< std::endl;
    out <<"                          further details on setting up accurate stereo "<< std::endl;
    out <<"                          for your system. "<< std::endl;
    out <<"    -stereo ANAGLYPHIC  - switch on anaglyphic(red/cyan) stereo rendering."<< std::endl;
    out <<"    -stereo QUAD_BUFFER - switch on quad buffered stereo rendering."<< std::endl;
    out <<std::endl;
    out <<"    -stencil            - use a visual with stencil buffer enabled, this "<< std::endl;
    out <<"                          also allows the depth complexity statistics mode"<< std::endl;
    out <<"                          to be used (press 'p' three times to cycle to it)."<< std::endl;
    out <<"    -f                  - start with a full screen, borderless window." << std::endl;
    out <<"    -p  pathfile        - Use the AnimationPathManipulator (key binding '4') and use\n"
	  "                          pathfile to define the animation path.  pathfile is an ascii\n"
	  "                          file containing lines of eight floating point numbers representing\n"
	  "                          time, position (x,y,z) and attitude (x,y,z,w as a quaternion)." << std::endl;
    out << std::endl;
}

int main( int argc, char **argv )
{
    std::string pathfile;

    // initialize the GLUT
    glutInit( &argc, argv );

    if (argc<2)
    {
        write_usage(std::cout,argv[0]);
        return 1;
    }

    // create the commandline args.
    std::vector<std::string> commandLine;
    for(int i=1;i<argc;++i) {
	if( std::string(argv[i]) == "-p" ) {
	    if( (i+1) >= argc ) {
		write_usage( std::cout, argv[0]);
	    	return 1;
	    }
	    else
		pathfile = std::string(argv[++i]);
	}
	else
	    commandLine.push_back(argv[i]);
    }

    // initialize the viewer.
    osgGLUT::Viewer viewer;
    viewer.setWindowTitle(argv[0]);

    // configure the viewer from the commandline arguments, and eat any
    // parameters that have been matched.
    viewer.readCommandLine(commandLine);

    // configure the plugin registry from the commandline arguments, and
    // eat any parameters that have been matched.
    osgDB::readCommandLine(commandLine);

    // load the nodes from the commandline arguments.
    osg::Node* rootnode = osgDB::readNodeFiles(commandLine);
    if (!rootnode)
    {
        return 1;
    }

    // run optimization over the scene graph
    osgUtil::Optimizer optimzer;
    optimzer.optimize(rootnode);

    // add a viewport to the viewer and attach the scene graph.
    viewer.addViewport( rootnode );

    // register trackball, flight and drive.
    viewer.registerCameraManipulator(new osgGA::TrackballManipulator);
    viewer.registerCameraManipulator(new osgGA::FlightManipulator);
    viewer.registerCameraManipulator(new osgGA::DriveManipulator);

    if( !pathfile.empty() ) {
	osgGA::AnimationPathManipulator *apm = new osgGA::AnimationPathManipulator(pathfile);
	if( apm->valid() )
        {
            //viewer.registerCameraManipulator(apm);
            // selecting the animation path manipulator up front seems to disable view frustum
            // in a heavy duty way that I'm do understand yet, so I'm commenting out for the
            // time being.  Simply pressing '4' will get you the animation path working correctly.
            unsigned int no = viewer.registerCameraManipulator(apm);
            viewer.selectCameraManipulator(no);
        }
	else
	    delete apm;
    }

//     osgUtil::RenderBin* depth_renderbin = osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin");
//     if (depth_renderbin)
//     {
//         depth_renderbin->setSortMode(osgUtil::RenderBin::SORT_BY_STATE);
//     }

    osgUtil::RenderStage* renderstage = viewer.getViewportSceneView(0)->getRenderStage();
    if (renderstage)
    {
       renderstage->setSortCallback(new MySortCallback);
//        renderstage->setSortMode(osgUtil::RenderBin::SORT_FRONT_TO_BACK);
    }

    // open the viewer window.
    viewer.open();

    // fire up the event loop.
    viewer.run();

    return 0;
}
<|endoftext|>