text:
<?php class wedding_style_home_page_class{

	public $homepage;
	public $shorthomepage;
	public $options_homepage;

	function __construct(){
		$this->homepage = "Homepage";
		$this->shorthomepage = "";
		$value_of_std[1]=get_theme_mod($this->shorthomepage."_top_post_cat_name",'');
		$value_of_std[2]=get_theme_mod($this->shorthomepage."_hide_top_posts",'on');
		$value_of_std[3]=get_theme_mod($this->shorthomepage."_top_post_categories",'');
		$value_of_std[5]=get_theme_mod($this->shorthomepage."_home_page_tabs_exclusive",'');
		$value_of_std[6]=get_theme_mod($this->shorthomepage."_hide_content_post",'on');
		$value_of_std[7]=get_theme_mod($this->shorthomepage."_home_content_post",'');
		$value_of_std[9]=get_theme_mod($this->shorthomepage."_content_post_cat_name",'my wedding photos');
		$value_of_std[10]=get_theme_mod($this->shorthomepage."_hide_content_posts",'on');
		$value_of_std[11]=get_theme_mod($this->shorthomepage."_content_post_categories",'');
		$value_of_std[12] = get_theme_mod($this->shorthomepage."_content_post_img", get_template_directory_uri().'/images/Wedding-01.png');

		$this->options_homepage = array(

			"top_post_cat_name" => array(

				"name" => "Top Post Title",

				"description" => "Specify a title for the top posts.",

				"var_name" => "top_post_cat_name",
				"id" => $this->shorthomepage."_top_post_cat_name",
				"std" => $value_of_std[1]

			),

			"hide_top_posts" => array(

				"name" => "Show Top Posts",

				"description" => "Check the box to display the top posts from the homepage.",

				"var_name" => "hide_top_posts",
				"id" => $this->shorthomepage."_hide_top_posts",
				"std" => $value_of_std[2]

			),

			"top_post_categories" => array(

				"name" => "Show Top Posts",

				"description" => "Select the categories from which you want the homepage top posts to be selected (the posts are selected automatically).",

				"var_name" => "top_post_categories",
				"id" => $this->shorthomepage."_top_post_categories",
				"std" => $value_of_std[3]

			),

			"hide_content_post" => array(

				"name" => "Show featured post",

				"description" => "Check the box to display the featured post on homepage.",

				"var_name" => "hide_content_post",
				"id" => $this->shorthomepage."_hide_content_post",
				"std" => $value_of_std[6]

			),

			"home_content_post" => array(

				"name" => "Hide content post.",

				"all_values" => $this->get_all_posts_in_select(),

				"description" => "Select a post for displaying as a featured post",

				"var_name" => "home_content_post",
				"id" => $this->shorthomepage."_home_content_post",
				"std" => $value_of_std[7]

			),

			"content_post_cat_name" => array(

				"name" => "Title for the Content Posts",

				"description" => "Specify a name for the content post group.",

				"var_name" => "content_post_cat_name",
				"id" => $this->shorthomepage."_content_post_cat_name",
				"std" => $value_of_std[9]

			),

			"hide_content_posts" => array(

				"name" => "Content Top Posts",

				"description" => "Check the box to select the categories from which the content top posts will be displayed.",

				"var_name" => "hide_content_posts",
				"id" => $this->shorthomepage."_hide_content_posts",
				"std" => $value_of_std[10]

			),

			"content_post_categories" => array(

				"name" => "",

				"description" => "Select the categories.",

				"var_name" => "content_post_categories",
				"id" => $this->shorthomepage."_content_post_categories",
				"std" => $value_of_std[11]

			),

			'content_post_img' => array(

				"name" => "Featured Post background image",

				"description" => "You can upload a custom image to be used as a background for the featured post.",

				"var_name" => "content_post_img",

				"id" => $this->shorthomepage."_content_post_img",

				"std" => $value_of_std[12]

			),
		);
	}
	/// save changes or reset options
	public function web_dorado_theme_update_and_get_options_home(){
		if (isset($_GET['page']) &&  $_GET['page'] == "web_dorado_theme" && isset($_GET['controller']) && $_GET['controller'] == "home_page") {
			if (isset($_REQUEST['action']) && $_REQUEST['action']=='save' ) {
				foreach ($this->options_homepage as $value) {
					if(isset($_REQUEST[$value['var_name']]))
						set_theme_mod($value['id'], stripslashes($_REQUEST[$value['var_name']]));
				}
				foreach ($this->options_homepage as $value) {
					if (isset($_REQUEST[$value['var_name']])) {
						set_theme_mod($value['id'], stripslashes($_REQUEST[$value['var_name']]));
					} else {
						remove_theme_mod($value['id']);
					}
				}
				header("Location: themes.php?page=web_dorado_theme&controller=home_page&saved=true");
				die;
			}
			else {

				if (isset($_REQUEST['action']) && $_REQUEST['action']=='reset') {

					foreach ($this->options_homepage as $value) {
						remove_theme_mod($value['id']);
					}
					header("Location: themes.php?page=web_dorado_theme&controller=home_page&reset=true");
					die;
				}

			}
		}

	}

	public function web_dorado_home_page_admin_scripts(){
		wp_enqueue_style('home_page_main_style',get_template_directory_uri().'/admin/css/home_page.css');
	}

	public function update_parametr($param_name,$value){
		set_theme_mod($this->options_homepage[$param_name]['id'],$value);
	}
	private function get_all_posts_in_select(){
		$args= array(
				'posts_per_page'   => 3000,
				'orderby'          => 'post_date',
				'order'            => 'DESC',
				'post_type'        => 'post',
				'post_status'      => 'publish',
				 );
		$posts_array_custom=array();

		$posts_array = get_posts( $args );
			foreach($posts_array as $post){
				$posts_array_custom[$post->ID]=$post->post_title;
			}
		return $posts_array_custom;
	}

	public function dorado_theme_admin_home(){

		if (isset($_REQUEST['saved']) && $_REQUEST['saved'] )

			echo '

Home settings are saved.

';

		if (isset($_REQUEST['reset']) && $_REQUEST['reset'] )

			echo '

Home settings are reset.

';

		global $wedding_style_admin_helepr_functions;
		global $wedding_style_web_dor;
		?>

					     <a href="<?php echo esc_url($wedding_style_web_dor).'/wordpress-themes-guide-step-1.html'; ?>" target="_blank" style="color:#126094; text-decoration:none;">User Manual
This section allows you to make changes in default layout of the theme.
                         <a href="<?php echo esc_url($wedding_style_web_dor).'/wordpress-theme-options/3-2.html'; ?>" target="_blank" style="color:#126094; text-decoration:none;">More...

                           <a href="<?php echo esc_url($wedding_style_web_dor).'/wordpress-themes/wedding-style.html'; ?>" target="_blank" style="color:red; text-decoration:none;">
                              <img src="<?php echo get_template_directory_uri() ?>/images/header.png" border="0" alt="" width="215">

Home

			<form method="post"  action="themes.php?page=web_dorado_theme&controller=home_page">

                          <?php
							$wedding_style_admin_helepr_functions->only_input($this->options_homepage['top_post_cat_name']);  /// Home Number of posts
							$wedding_style_admin_helepr_functions->checkbox_category_checkboxses($this->options_homepage['hide_top_posts'],$this->options_homepage['top_post_categories']);  /// Home Top posts
							$wedding_style_admin_helepr_functions->only_upload($this->options_homepage['content_post_img']); /// Content post bg image
							$wedding_style_admin_helepr_functions->checkbox_with_select($this->options_homepage['hide_content_post'],$this->options_homepage['home_content_post']);  /// Home Number of posts
							$wedding_style_admin_helepr_functions->only_input($this->options_homepage['content_post_cat_name']);  /// Home Number of posts
							$wedding_style_admin_helepr_functions->checkbox_category_checkboxses($this->options_homepage['hide_content_posts'],$this->options_homepage['content_post_categories']);  /// Home Top posts
							?>

					<input class="button" name="save" type="submit" value="Save changes"/>
					<input type="hidden" name="action" value="save"/>

			</form>
			<form method="post" action="themes.php?page=web_dorado_theme&controller=home_page">

					<input class="button" name="reset" type="submit" value="Reset"/>
					<input type="hidden" name="action" value="reset"/>

			</form>

	<?php

	}
}


text:
    <repo-finder (stats)="statsLeft = $event;activateButton();">
    </repo-finder>

    <repo-finder (stats)="statsRight = $event;activateButton();"></repo-finder>

    <game-element [detail]="statsLeft"></game-element>

    <game-element [detail]="statsRight"></game-element>

  <button type="button" [disabled]="saveButtonDisabled"  class="btn btn-info" (click)="saveComparison(statsLeft, statsRight)">
    {{ saveButtonMessage }}
  </button>

redpajama_set_name: RedPajamaGithub


text:
//
//// Express
//// Enables a variety of http server functions
//// http://expressjs.com
//

Express = require('express');

router = Express.createServer();
router.listen( 8080 );
router.configure( function(){
	router.use( Express.static( __dirname +'/assets') );
});

router.get( '/', function( req, res ){

	res.send(
		''+
			''+
			'	'+
			'	'+
			'	'+
			'	'+
			'	'+
			'	'+
			''+
			''+
		''
	);

});

//
//// Socket.io
//// Provides cross-browser websockets
//// http://www.socket.io
//

io = require('socket.io').listen( router );

io.configure( function(){

	io.enable('browser client minification');
	io.enable('browser client etag');
	io.enable('browser client gzip');
	io.set( 'log level', 1 );
	io.set( 'transports', [
		'websocket',
		'htmlfile',
		'xhr-polling',
		'jsonp-polling'
	]);

});

var ROOM = 'test';

// Simple messages collection
var ids = 0;
var messages = {};

io.of( '/messages' ).on( 'connection', function( socket ){

	socket.join( ROOM );

	socket.on( 'create', function( data, callback ){

		console.log( 'create', arguments );

		var errors = [];
		var message = data.attributes;
		message.id = ids;
		messages[ids] = message;
		ids++;

		if( errors.length > 0 )
			return callback( errors );

		callback( data );
		io.of('/messages').in( ROOM ).emit( 'create', data );

	});

	socket.on( 'read', function( data, callback ){

		console.log( 'read', messages );

		var errors = [];
		var id = data.id;
		if( id ){
			var message = messages[id];
			data.attributes = message;
		}
		else {
			var messages_array = [];
			for( i in messages )
				messages_array.push( messages[i] );
			data.attributes = messages_array;
		}

		if( errors.length > 0 )
			return callback( errors );

		callback( data );

	});

	socket.on( 'update', function( data, callback ){

		console.log( 'update', arguments );

		var errors = [];
		var id = data.id;
		var message = messages[id];
		message = data.attributes;

		callback( data );
		io.of('/messages').in( ROOM ).emit( 'update', data );

	});

	socket.on( 'delete', function( data, callback ){

		console.log( 'delete', arguments );

		var errors = [];
		var id = data.id;
		delete messages[id];

		callback( data );
		io.of('/messages').in( ROOM ).emit( 'delete', data );

	});

});

var room = {
	title: 'test room',
	subtitle: 'test subtitle'
};

io.of( '/room' ).on( 'connection', function( socket ){

	socket.join( ROOM );

	socket.on( 'read', function( data, callback ){

		data.attributes = room;

		callback( data );

	});

	socket.on( 'update', function( data, callback ){

		room = data.attributes;

		callback( data );
		io.of( '/messages' ).in( ROOM ).emit( 'update', data );

	});

});


text:
<form action="/users/signup.html" method="post">

    Username

      <input class="form-control" placeholder="username" type="text" id="username" name="username">

    First Name

      <input class="form-control" type="text" placeholder="First Name" id="first_name" name="first_name">

    Last Name

      <input class="form-control" type="url" placeholder="Last Name" " id="last_name" name="last_name">

    Email

      <input class="form-control" type="email" id="email" name="email">

    Password

      <input class="form-control" type="password" id="password" name="password">

    Repeat Password

      <input class="form-control" type="password" value="hunter2" id="repeat_password" name="repeat_password">

  <button type="submit" class="btn btn-primary">
    Submit
  </button>
</form>


text:
using FlexLucene.Document;
using FlexLucene.Facet;
using FlexLucene.Search;
using System;
using System.Collections.Generic;
using System.Linq;
using LuceneDocument = FlexLucene.Document.Document;

namespace ExpandoDB.Search
{
    /// <summary>
    /// Implements utility methods for Lucene search.
    /// </summary>
    public static class SearchUtils
    {
        /// <summary>
        /// Validates the specified search criteria.
        /// </summary>
        /// <param name="criteria">The search criteria.</param>
        public static void Validate(this SearchCriteria criteria)
        {
            if (criteria.TopN <= 0)
                throw new ArgumentException("topN cannot be <= zero");
            if (criteria.ItemsPerPage <= 0)
                throw new ArgumentException("itemsPerPage cannot be <= zero");
            if (criteria.PageNumber <= 0)
                throw new ArgumentException("pageNumber cannot be <= zero");
        }

        /// <summary>
        /// Populates the SearchResult object with data from the specified TopFieldDocs object.
        /// </summary>
        /// <param name="result">The SearchResult to be populated.</param>
        /// <param name="topDocs">The TopDocs object returned by Lucene.</param>
        /// <param name="categories">The categories.</param>
        /// <param name="getDoc">A lambda that returns the Lucene document given the doc id.</param>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        public static void PopulateWith(this SearchResult<Guid> result, TopDocs topDocs, IEnumerable<Category> categories, Func<int, LuceneDocument> getDoc)
        {
            if (result == null)
                throw new ArgumentNullException(nameof(result));
            if (topDocs == null)
                throw new ArgumentNullException(nameof(topDocs));
            if (getDoc == null)
                throw new ArgumentNullException(nameof(getDoc));

            result.ItemCount = topDocs.ScoreDocs.Length;
            result.TotalHits = topDocs.TotalHits;

            if (result.ItemCount > 0)
            {
                var itemsToSkip = (result.PageNumber - 1) * result.ItemsPerPage;
                var itemsToTake = result.ItemsPerPage;

                var scoreDocs = topDocs.ScoreDocs
                                            .Skip(itemsToSkip)
                                            .Take(itemsToTake)
                                            .ToList();

                var documentIds = new List<Guid>();
                for (var i = 0; i < scoreDocs.Count; i++)
                {
                    var sd = scoreDocs[i];
                    var doc = getDoc(sd.Doc);
                    if (doc == null)
                        continue;

                    var idField = doc.GetField(Schema.StandardField.ID);
                    var idValue = idField.StringValue();

                    documentIds.Add(Guid.Parse(idValue));
                }

                result.Items = documentIds;
                result.Categories = categories ?? Enumerable.Empty<Category>();
                result.PageCount = ComputePageCount(result.ItemCount, result.ItemsPerPage);
            }
        }

        private static int ComputePageCount(int hitCount, int itemsPerPage)
        {
            var pageCount = 0;
            if (hitCount > 0 && itemsPerPage > 0)
            {
                pageCount = hitCount / itemsPerPage;
                var remainder = hitCount % itemsPerPage;
                if (remainder > 0)
                    pageCount += 1;
            }

            return pageCount;
        }

    }
}


text:
using Aliyun.MNS.Common;
using Aliyun.MNS.Utility;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Xml.Serialization;

namespace Aliyun.MNS
{
    public class ListQueueApiRequest : ApiRequestBase<ListQueueApiResult>
    {
        public string Prefix { get; set; } = string.Empty;

        public int PageSize { get; set; } = 0;

        public string NextMarker { get; set; } = string.Empty;

        protected override string Path => "/queues";

        protected override HttpMethod Method => HttpMethod.Get;

        public ListQueueApiRequest(MnsConfig config, string prefix, int pageSize, string nextMarker) : base(config)
        {
            this.Prefix = prefix;
            this.PageSize = pageSize;
            this.NextMarker = nextMarker;
        }

        protected override void AdditionalHeaders(HttpRequestHeaders headers)
        {
            if (!string.IsNullOrEmpty(this.Prefix))
            {
                headers.Add("x-mns-prefix", this.Prefix);
            }

            if (this.PageSize > 0)
            {
                headers.Add("x-mns-ret-number", this.PageSize.ToString());
            }

            if (!string.IsNullOrEmpty(this.NextMarker))
            {
                headers.Add("x-mns-marker", this.NextMarker);
            }
        }
    }

    public class ListQueueApiResult : ApiResult<QueueListModel>
    {
        public ListQueueApiResult(HttpResponseMessage response) : base(response)
        {
        }

        public override void Validate()
        {
            switch (this.Response.StatusCode)
            {
                case System.Net.HttpStatusCode.OK:
                    this.Result = XmlSerdeUtility.Deserialize<QueueListModel>(this.ResponseText);
                    break;
                default:
                    throw new UnknowException(this.Response);
            }
        }
    }

    [XmlRoot(ElementName = "Queues", Namespace = MnsConstants.MNS_XML_NS)]
    public class QueueListModel
    {
        [XmlElement(ElementName = "Queue")]
        public List<QueueListItem> Items { get; set; }

        [XmlElement(ElementName = "NextMarker")]
        public string NextMarker { get; set; }
    }

    public class QueueListItem
    {
        public string QueueURL { get; set; }
    }
}


text:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h>
#include <getopt.h>

#include "common_args.h"
#include "common.h"

/*
  #ifdef __APPLE__
  #include <OpenCL/opencl.h>
  #else
  #include <CL/opencl.h>
  #endif
*/

/*
  #define CHKERR(err, str) \
  if ( err != CL_SUCCESS) \
  {\
  fprintf(stderr, "Error in executing \"%s\", %d\n", str, err);  \
  exit(EXIT_FAILURE);\
  }
*/
#define CHECK_NULL_ERROR(err, str)                                      \
    if ( err == NULL)                                                   \
    {                                                                   \
	fprintf(stderr, "Error creating objects in \"%s\"\n", str);     \
	exit(EXIT_FAILURE);                                             \
    }

#define T           1000        /* Number of static observations */
#define S           2           /* Number of static symbols */
#define N           60          /* Number of static states */
#define ITERATIONS  1           /* Number of iterations */

#define MAX_THREADS_PER_BLOCK 256
#define BLOCK_DIM 16
#define EXIT_ERROR 1

#define SDOT_BLOCK_SIZE (128)
#define SDOT_BLOCK_NUM (80)

#define MVMUL_BLOCK_SIZE (128)
#define MVMUL_BLOCK_NUM  (64)

cl_event ocdTempEvent;

cl_platform_id           _cl_firstPlatform;
cl_device_id             _cl_firstDevice;
//cl_context               _cl_context;
//cl_command_queue         _cl_commandQueue;
cl_program               _cl_program;

cl_kernel _cl_kernel_init_ones_dev;
cl_kernel _cl_kernel_init_alpha_dev;
cl_kernel _cl_kernel_calc_alpha_dev;
cl_kernel _cl_kernel_scale_alpha_dev;
cl_kernel _cl_kernel_init_beta_dev;
cl_kernel _cl_kernel_calc_beta_dev;
cl_kernel _cl_kernel_calc_gamma_dev;
cl_kernel _cl_kernel_calc_xi_dev;
cl_kernel _cl_kernel_est_a_dev;
cl_kernel _cl_kernel_scale_a_dev;
cl_kernel _cl_kernel_acc_b_dev;
cl_kernel _cl_kernel_est_b_dev;
cl_kernel _cl_kernel_scale_b_dev;
cl_kernel _cl_kernel_est_pi_dev;
cl_kernel _cl_kernel_s_dot_kernel_naive;
cl_kernel _cl_kernel_sgemvt_kernel_naive;
cl_kernel _cl_kernel_sgemvn_kernel_naive;

size_t LoadProgramSource(const char *filename, const char **progSrc)
{
    FILE *f = fopen(filename, "r");
    fseek(f, 0, SEEK_END);
    size_t len = (size_t) ftell(f);
    *progSrc = (const char *) malloc(sizeof(char)*len);
    rewind(f);
    fread((void *) *progSrc, len, 1, f);
    fclose(f);
    return len;
}

/* Simple init the openCL platform */
void init_cl()
{
    cl_int errNum;
    size_t progLen;
    const char *progSrc;

    ocd_initCL();//KK

    /* identify the first platform */
    //errNum = clGetPlatformIDs(1, &_cl_firstPlatform, NULL);
    //CHKERR(errNum , "finding any available OpenCL platform!");

    /* identify the first accessible device associated with the platform */
    //errNum = clGetDeviceIDs(_cl_firstPlatform, CL_DEVICE_TYPE_GPU, 1, &_cl_firstDevice, NULL);
    //CHKERR(errNum, "finding any available OpenCL device!");

    /* create a context containing only one device which is created earlier */
    //context = clCreateContext(NULL, 1, &_cl_firstDevice, NULL, NULL, &errNum);
    //CHKERR(errNum, "creating GPU context!");

    /* create command queue to target the device, which can support profiling */
    //_cl_commandQueue = clCreateCommandQueue(context, _cl_firstDevice, CL_QUEUE_PROFILING_ENABLE, NULL);
    //CHECK_NULL_ERROR(_cl_commandQueue, "_cl_commandQueue");

    /* read the source code into the char array */
    progLen = LoadProgramSource("bwa_hmm_opencl.cl", &progSrc);

    /* create program from the source code */
    _cl_program = clCreateProgramWithSource(context, 1, &progSrc, &progLen, NULL);
    CHECK_NULL_ERROR(_cl_program, "_cl_program");
    free((void *)progSrc);

    /* compile the source code for the device in the context */
    errNum = clBuildProgram(_cl_program, 1, &device_id, "-I .", NULL, NULL);
    if(errNum != CL_SUCCESS)
    {
        char buildLog[16384];
        clGetProgramBuildInfo(_cl_program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buildLog), buildLog, NULL);
        fprintf(stderr, "Error in compiling the kernels: \n");
        fprintf(stderr, "%s\n", buildLog);
    }

    /* create the kernels from the program */
    _cl_kernel_init_ones_dev   = clCreateKernel(_cl_program, "init_ones_dev", NULL);
    _cl_kernel_init_alpha_dev  = clCreateKernel(_cl_program, "init_alpha_dev", NULL);
    _cl_kernel_calc_alpha_dev  = clCreateKernel(_cl_program, "calc_alpha_dev", NULL);
    _cl_kernel_scale_alpha_dev = clCreateKernel(_cl_program, "scale_alpha_dev", NULL);
    _cl_kernel_init_beta_dev   = clCreateKernel(_cl_program, "init_beta_dev", NULL);
    _cl_kernel_calc_beta_dev   = clCreateKernel(_cl_program, "calc_beta_dev", NULL);
    _cl_kernel_calc_gamma_dev  = clCreateKernel(_cl_program, "calc_gamma_dev", NULL);
    _cl_kernel_calc_xi_dev     = clCreateKernel(_cl_program, "calc_xi_dev", NULL);
    _cl_kernel_est_a_dev       = clCreateKernel(_cl_program, "est_a_dev", NULL);
    _cl_kernel_scale_a_dev     = clCreateKernel(_cl_program, "scale_a_dev", NULL);
    _cl_kernel_acc_b_dev       = clCreateKernel(_cl_program, "acc_b_dev", NULL);
    _cl_kernel_est_b_dev       = clCreateKernel(_cl_program, "est_b_dev", NULL);
    _cl_kernel_scale_b_dev     = clCreateKernel(_cl_program, "scale_b_dev", NULL);
    _cl_kernel_est_pi_dev      = clCreateKernel(_cl_program, "est_pi_dev", NULL);
    _cl_kernel_s_dot_kernel_naive    = clCreateKernel(_cl_program, "s_dot_kernel_naive", NULL);
    _cl_kernel_sgemvt_kernel_naive   = clCreateKernel(_cl_program, "mvm_trans_kernel_naive", NULL);
    _cl_kernel_sgemvn_kernel_naive   = clCreateKernel(_cl_program, "mvm_non_kernel_naive", NULL);

    CHECK_NULL_ERROR( _cl_kernel_init_ones_dev, "_cl_kernel_init_ones_dev");
    CHECK_NULL_ERROR( _cl_kernel_init_alpha_dev, "_cl_kernel_init_alpha_dev");
    CHECK_NULL_ERROR( _cl_kernel_calc_alpha_dev, "_cl_kernel_calc_alpha_dev");
    CHECK_NULL_ERROR( _cl_kernel_scale_alpha_dev, "_cl_kernel_scale_alpha_dev");
    CHECK_NULL_ERROR( _cl_kernel_init_beta_dev, "_cl_kernel_init_beta_dev");
    CHECK_NULL_ERROR( _cl_kernel_calc_beta_dev, "_cl_kernel_calc_beta_dev");
    CHECK_NULL_ERROR( _cl_kernel_calc_gamma_dev, "_cl_kernel_calc_gamma_dev");
    CHECK_NULL_ERROR( _cl_kernel_calc_xi_dev, "_cl_kernel_calc_xi_dev");
    CHECK_NULL_ERROR( _cl_kernel_est_a_dev, "_cl_kernel_est_a_dev");
    CHECK_NULL_ERROR( _cl_kernel_scale_a_dev, "_cl_kernel_scale_a_dev");
    CHECK_NULL_ERROR( _cl_kernel_acc_b_dev, "_cl_kernel_acc_b_dev");
    CHECK_NULL_ERROR( _cl_kernel_est_b_dev, "_cl_kernel_est_b_dev");
    CHECK_NULL_ERROR( _cl_kernel_scale_b_dev, "_cl_kernel_scale_b_dev");
    CHECK_NULL_ERROR( _cl_kernel_est_pi_dev, "_cl_kernel_est_pi_dev");
    CHECK_NULL_ERROR( _cl_kernel_s_dot_kernel_naive, "_cl_kernel_s_dot_kernel_naive");
    CHECK_NULL_ERROR( _cl_kernel_sgemvt_kernel_naive, "_cl_kernel_sgemvt_kernel_naive");
    CHECK_NULL_ERROR( _cl_kernel_sgemvn_kernel_naive, "_cl_kernel_sgemvn_kernel_naive");

}

static int imax(int x, int y)
{
    return (x > y) ? x: y;
}

/* Subtracts time values to determine run time */
int timeval_subtract(struct timeval *result, struct timeval *t2,
                     struct timeval *t1)
{
    long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) -
        (t1->tv_usec + 1000000 * t1->tv_sec);
    result->tv_sec = diff / 1000000;
    result->tv_usec = diff % 1000000;

    return (diff<0);
}

/* Starts timer */
void tic(struct timeval *timer)
{
    gettimeofday(timer, NULL);
}

/* Stops timer and prints difference to the screen */
void toc(struct timeval *timer)
{
    struct timeval tv_end, tv_diff;

    gettimeofday(&tv_end, NULL);
    timeval_subtract(&tv_diff, &tv_end, timer);
    fprintf(stderr, "%ld.%06ld seconds \t\n", tv_diff.tv_sec, tv_diff.tv_usec);
}

/* individual paramters of a Hidden Markov Model */
typedef struct {
    int nstates;            /**< number of states in the HMM */
    int nsymbols;           /**< number of possible symbols */
    float *a;               /**< A matrix - state transition probabilities */
    float *b;               /**< B matrix - symbol output probabilities */
    float *pi;              /**< Pi matrix - initial state probabilities */
} Hmm;

/* the observation sequence and length */
typedef struct {
    int length;             /**< the length of the observation sequence */
    int *data;              /**< the observation sequence */
} Obs;

/* Free the memory associated with the HMM and observation sequence */
void free_vars(Hmm *hmm, Obs *obs)
{
    if (hmm != NULL) {
        if (hmm->a != NULL) {
            free(hmm->a);
        }
        if (hmm->b != NULL) {
            free(hmm->b);
        }
        if (hmm->pi != NULL) {
            free(hmm->pi);
        }
        free(hmm);
    }
    if (obs != NULL) {
        if (obs->data != NULL) {
            free(obs->data);
        }
        free(obs);
    }
}

/* Global variables for device */
int nstates;                        /* The number of states in the HMM */
int nsymbols;                       /* The number of possible symbols */
int *obs;                           /* The observation sequence */
int length;                         /* The length of the observation sequence */
float *scale;                       /* Scaling factor as determined by alpha */
cl_mem a_d;                         /* A matrix on GPU */
cl_mem b_d;                         /* B matrix on GPU */
cl_mem pi_d;                        /* Pi matrix on GPU */
cl_mem alpha_d;                     /* Forward variables (alpha) on GPU */
cl_mem beta_d;                      /* Backward variables (beta) on GPU */
cl_mem gamma_sum_d;                 /* Sum of gamma variables on GPU */
cl_mem xi_sum_d;                    /* Sum of xi variables on GPU */
cl_mem c_d;                         /* Temporary array on GPU */
cl_mem ones_n_d;                    /* Length <states> array of 1s on GPU */
cl_mem ones_s_d;                    /* Length <symbols> array of 1s on GPU */

/************************************************************************/
/* This function is used to compute the dot product of two single-      */
/* precision vectors. Add offset support to cl_mem type files           */
/* OUTPUTS:                                                             */
/*   returns single-precision dot product                               */
/*                                                                      */
/************************************************************************/
float dot_production(int n, cl_mem paramA, int offsetA, cl_mem paramB, int offsetB)
{
    float result = 0.0f;
    int i;
    cl_int errNum;

    int blocks, threads;
    if(n < SDOT_BLOCK_NUM)
    {
        blocks = n;
    } else
    {
        blocks = SDOT_BLOCK_NUM ;
    }
    threads =SDOT_BLOCK_SIZE ;

    if(n <= 0)
    {
        return result;
    }

    /* for the sum reduction on CPU */
    float *partialSum = (float*)calloc(n, sizeof(float));

    cl_mem partialSum_d;
    partialSum_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * n, NULL, NULL);
    CHECK_NULL_ERROR(commands, "partialSum_d");

    /* set partialSum_d to all zeros */
    errNum = clEnqueueWriteBuffer(commands, partialSum_d, CL_TRUE, 0,  sizeof(float) * n, partialSum, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "writing buffer partialSum_d");

    errNum  = clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 0, sizeof(int), &n);
    errNum |= clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 1, sizeof(cl_mem), &paramA);
    errNum |= clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 2, sizeof(int), &offsetA);
    errNum |= clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 3, sizeof(cl_mem), &paramB);
    errNum |= clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 4, sizeof(int), &offsetB);
    errNum |= clSetKernelArg(_cl_kernel_s_dot_kernel_naive, 5, sizeof(cl_mem), &partialSum_d);
    CHKERR(errNum, "setting kernel _cl_kernel_s_dot_kernel_naive arguments");

    size_t globalWorkSize[1] = { blocks * threads };
    size_t localWorkSize[1]  = { threads };

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_s_dot_kernel_naive, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_s_dot_kernel_naive");

    errNum = clEnqueueReadBuffer(commands, partialSum_d, CL_TRUE, 0,  sizeof(float) * n, partialSum, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "reading buffer partialSum_d");

    for(i = 0; i < n; i++)
    {
        result += partialSum[i];
    }

    return result;
}

/************************************************************************/
/* This function is used for matrix and vector multiplication.          */
/* Add transposed matrix support                                        */
/************************************************************************/
void mat_vec_mul(char trans, int m, int n, cl_mem A, int lda, cl_mem x, int offsetX, cl_mem y, int offsetY)
{
    cl_int errNum;

    if((trans != 'n') && (trans != 't'))
    {
        return;
    }

    if(trans == 't')
    {
        /*
          errNum  = clSetKernelArg(_cl_kernel_sgemvt_kernel, 0, sizeof(int), &m);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 1, sizeof(int), &n);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 2, sizeof(cl_mem), &A);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 3, sizeof(int), &lda);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 4, sizeof(cl_mem), &x);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 5, sizeof(int), &offsetX);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 6, sizeof(cl_mem), &y);
          errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel, 7, sizeof(int), &offsetY);
          CHKERR(errNum, "setting kernel _cl_kernel_sgemvt_kernel arguments");

          size_t globalWorkSize[1] = { MVMUL_BLOCK_NUM * MVMUL_BLOCK_SIZE };
          size_t localWorkSize[1]  = { MVMUL_BLOCK_SIZE };

          errNum = clEnqueueNDRangeKernel(_cl_commandQueue, _cl_kernel_sgemvt_kernel, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
          CHKERR(errNum, "queuing kernel _cl_kernel_sgemvt_kernel for execution");
        */
        errNum  = clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 0, sizeof(int), &m);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 1, sizeof(int), &n);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 2, sizeof(cl_mem), &A);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 3, sizeof(int), &lda);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 4, sizeof(cl_mem), &x);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 5, sizeof(int), &offsetX);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 6, sizeof(cl_mem), &y);
        errNum |= clSetKernelArg(_cl_kernel_sgemvt_kernel_naive, 7, sizeof(int), &offsetY);
        CHKERR(errNum, "setting kernel _cl_kernel_sgemvt_kernel_naive arguments");

        size_t globalWorkSize[1] = { MVMUL_BLOCK_NUM * MVMUL_BLOCK_SIZE };
        size_t localWorkSize[1]  = { MVMUL_BLOCK_SIZE };

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_sgemvt_kernel_naive, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_sgemvt_kernel_naive for execution");
    } else
    {
        /*
          errNum  = clSetKernelArg(_cl_kernel_sgemvn_kernel, 0, sizeof(int), &m);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 1, sizeof(int), &n);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 2, sizeof(cl_mem), &A);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 3, sizeof(int), &lda);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 4, sizeof(cl_mem), &x);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 5, sizeof(int), &offsetX);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 6, sizeof(cl_mem), &y);
          errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel, 7, sizeof(int), &offsetY);
          CHKERR(errNum, "setting kernel _cl_kernel_sgemvn_kernel arguments");

          size_t globalWorkSize[1] = { MVMUL_BLOCK_NUM * MVMUL_BLOCK_SIZE };
          size_t localWorkSize[1]  = { MVMUL_BLOCK_SIZE };

          errNum = clEnqueueNDRangeKernel(_cl_commandQueue, _cl_kernel_sgemvn_kernel, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL);
          CHKERR(errNum, "queuing kernel _cl_kernel_sgemvn_kernel for execution");
        */
        errNum  = clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 0, sizeof(int), &m);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 1, sizeof(int), &n);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 2, sizeof(cl_mem), &A);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 3, sizeof(int), &lda);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 4, sizeof(cl_mem), &x);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 5, sizeof(int), &offsetX);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 6, sizeof(cl_mem), &y);
        errNum |= clSetKernelArg(_cl_kernel_sgemvn_kernel_naive, 7, sizeof(int), &offsetY);
        CHKERR(errNum, "setting kernel _cl_kernel_sgemvn_kernel_naive arguments");

        size_t globalWorkSize[1] = { MVMUL_BLOCK_NUM * MVMUL_BLOCK_SIZE };
        size_t localWorkSize[1]  = { MVMUL_BLOCK_SIZE };

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_sgemvn_kernel_naive, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_sgemvn_kernel_naive for execution");
    }

}

/*******************************************************************************
 * Supporting functions
 */

/* Calculates the forward variables (alpha) for an HMM and obs. sequence */
float calc_alpha()
{

    int threads_per_block;
    int nblocks;
    int offset_cur;
    int offset_prev;
    float log_lik;
    int t;
    cl_int errNum;

    /* Initialize alpha variables */
    threads_per_block = MAX_THREADS_PER_BLOCK;
    nblocks = (nstates + threads_per_block - 1) / threads_per_block;
    size_t globalWorkSize[1] = { nblocks * threads_per_block };
    size_t localWorkSize[1]  = { threads_per_block };

    // init_alpha_dev<<<nblocks, threads_per_block>>>( b_d,
    //                                                 pi_d,
    //                                                 nstates,
    //                                                 alpha_d,
    //                                                 ones_n_d,
    //                                                 obs[0]);
    errNum  = clSetKernelArg(_cl_kernel_init_alpha_dev, 0, sizeof(cl_mem), &b_d);
    errNum |= clSetKernelArg(_cl_kernel_init_alpha_dev, 1, sizeof(cl_mem), &pi_d);
    errNum |= clSetKernelArg(_cl_kernel_init_alpha_dev, 2, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_init_alpha_dev, 3, sizeof(cl_mem), &alpha_d);
    errNum |= clSetKernelArg(_cl_kernel_init_alpha_dev, 4, sizeof(cl_mem), &ones_n_d);
    errNum |= clSetKernelArg(_cl_kernel_init_alpha_dev, 5, sizeof(int), obs);
    CHKERR(errNum, "setting kernel _cl_kernel_init_alpha_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_init_alpha_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_init_alpha_dev for execution");

    /* Sum alpha values to get scaling factor */
    scale[0] = dot_production(nstates, alpha_d, 0, ones_n_d, 0);

    /* Scale alpha values */
    // scale_alpha_dev<<<nblocks, threads_per_block>>>(    nstates,
    //                                                     alpha_d,
    //                                                     scale[0]);
    int tmp = 0;
    errNum  = clSetKernelArg(_cl_kernel_scale_alpha_dev, 0, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 1, sizeof(cl_mem), &alpha_d);
    errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 2, sizeof(int), &tmp);
    errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 3, sizeof(float), scale);
    CHKERR(errNum, "setting kernel _cl_kernel_scale_alpha_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_scale_alpha_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_scale_alpha_dev for execution");

    /* Initilialize log likelihood */
    log_lik = log10(scale[0]);

    /* Calculate the rest of the alpha variables */
    for (t = 1; t < length; t++) {

        /* Calculate offsets */
        offset_prev = (t - 1) * nstates;
        offset_cur = t * nstates;

        /* Multiply transposed A matrix by alpha(t-1) */
        /* Note: the matrix is auto-transposed by cublas reading column-major */
        // mat_vec_mul( 'N', nstates, nstates, 1.0f, a_d, nstates,
        //              alpha_d + offset_prev, 1, 0, alpha_d + offset_cur, 1 );
        mat_vec_mul( 'n', nstates, nstates, a_d, nstates,
                     alpha_d, offset_prev, alpha_d, offset_cur);

        /* Calculate alpha(t) */
        // calc_alpha_dev<<<nblocks, threads_per_block>>>( nstates,
        //                                                 alpha_d + offset_cur,
        //                                                 b_d,
        //                                                 obs[t]);

        errNum  = clSetKernelArg(_cl_kernel_calc_alpha_dev, 0, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_calc_alpha_dev, 1, sizeof(cl_mem), &alpha_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_alpha_dev, 2, sizeof(int), &offset_cur);
        errNum |= clSetKernelArg(_cl_kernel_calc_alpha_dev, 3, sizeof(cl_mem), &b_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_alpha_dev, 4, sizeof(int), obs + t);
        CHKERR(errNum, "setting kernel _cl_kernel_calc_alpha_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_calc_alpha_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_calc_alpha_dev for execution");

        /* Sum alpha values to get scaling factor */
        scale[t] = dot_production(nstates, alpha_d, offset_cur, ones_n_d, 0);

        /* Scale alpha values */
        // scale_alpha_dev<<<nblocks, threads_per_block>>>(nstates,
        //                                                alpha_d + offset_cur,
        //                                                 scale[t]);
        errNum  = clSetKernelArg(_cl_kernel_scale_alpha_dev, 0, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 1, sizeof(cl_mem), &alpha_d);
        errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 2, sizeof(int), &offset_cur);
        errNum |= clSetKernelArg(_cl_kernel_scale_alpha_dev, 3, sizeof(float), scale + t);
        CHKERR(errNum, "setting kernel _cl_kernel_scale_alpha_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_scale_alpha_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_scale_alpha_dev for execution");
        /* Update log likelihood */
        log_lik += log10(scale[t]);
    }

    return log_lik;
}

/* Calculates the backward variables (beta) */
int calc_beta()
{

    int threads_per_block;
    int nblocks;
    int t;
    int offset;
    cl_int errNum;

    /* Initialize beta variables */
    threads_per_block = MAX_THREADS_PER_BLOCK;
    nblocks = (nstates + threads_per_block - 1) / threads_per_block;
    size_t globalWorkSize[1] = { nblocks * threads_per_block };
    size_t localWorkSize[1]  = { threads_per_block };

    // init_beta_dev<<<nblocks, threads_per_block>>>(  nstates, beta_d +
    //                                                 ((length - 1) * nstates),
    //                                                 scale[length - 1]);
    offset  = ((length - 1) * nstates);
    errNum  = clSetKernelArg(_cl_kernel_init_beta_dev, 0, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_init_beta_dev, 1, sizeof(cl_mem), &beta_d);
    errNum |= clSetKernelArg(_cl_kernel_init_beta_dev, 2, sizeof(int), &offset);
    errNum |= clSetKernelArg(_cl_kernel_init_beta_dev, 3, sizeof(float), scale + length - 1);
    CHKERR(errNum, "setting kernel _cl_kernel_init_beta_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_init_beta_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_init_beta_dev for execution");

    /* Calculate the rest of the beta variables */
    for (t = length - 2; t >= 0; t--) {

        /* Calculate first step of beta: B.*beta/scale */
        // calc_beta_dev<<<nblocks, threads_per_block>>>(  beta_d,
        //                                                 b_d,
        //                                                 scale[t],
        //                                                 nstates,
        //                                                 obs[t+1],
        //                                                 t);
        errNum  = clSetKernelArg(_cl_kernel_calc_beta_dev, 0, sizeof(cl_mem), &beta_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_beta_dev, 1, sizeof(cl_mem), &b_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_beta_dev, 2, sizeof(float), scale + t);
        errNum |= clSetKernelArg(_cl_kernel_calc_beta_dev, 3, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_calc_beta_dev, 4, sizeof(int), obs + t + 1);
        errNum |= clSetKernelArg(_cl_kernel_calc_beta_dev, 5, sizeof(int), &t);
        CHKERR(errNum, "setting kernel _cl_kernel_calc_beta_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_calc_beta_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_calc_beta_dev for execution");

        /* Multiply transposed A matrix by beta(t) */
        // mat_vec_mul( 'T', nstates, nstates, 1.0f, a_d, nstates,
        //             beta_d + (t * nstates), 1, 0, beta_d + (t * nstates), 1 );
        mat_vec_mul( 'n', nstates, nstates, a_d, nstates,
                     beta_d, t * nstates, beta_d, t * nstates);

    }

    return 0;
}

/* Calculates the gamma sum */
void calc_gamma_sum()
{
    int threads_per_block;
    int nblocks;
    int size;
    int t;
    cl_int errNum;

    threads_per_block = MAX_THREADS_PER_BLOCK;
    nblocks = (nstates + threads_per_block - 1) / threads_per_block;
    size_t globalWorkSize[1] = { nblocks * threads_per_block };
    size_t localWorkSize[1]  = { threads_per_block };

    // init to zeros
    int *gamma_sum_zeros = (int*)calloc(nstates, sizeof(float));
    errNum = clEnqueueWriteBuffer(commands, gamma_sum_d, CL_TRUE, 0, sizeof(float) * nstates, gamma_sum_zeros, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "writing buffer gamma_sum_d");
    free(gamma_sum_zeros);

    /* Find sum of gamma variables */
    for (t = 0; t < length; t++) {
        // calc_gamma_dev<<<nblocks, threads_per_block>>>( gamma_sum_d,
        // alpha_d,
        // beta_d,
        // nstates,
        // t);
        errNum  = clSetKernelArg(_cl_kernel_calc_gamma_dev, 0, sizeof(cl_mem), &gamma_sum_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_gamma_dev, 1, sizeof(cl_mem), &alpha_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_gamma_dev, 2, sizeof(cl_mem), &beta_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_gamma_dev, 3, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_calc_gamma_dev, 4, sizeof(int), &t);
        CHKERR(errNum, "setting kernel _cl_kernel_calc_gamma_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_calc_gamma_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_calc_gamma_dev for execution");
    }

}

/* Calculates the sum of xi variables */
int calc_xi_sum()
{
    float sum_ab;
    int nblocks;
    int size;
    int t;
    cl_int errNum;

    // init to zeros
    int *xi_sum_d_zeros = (int*)calloc(nstates * nstates, sizeof(float));
    errNum = clEnqueueWriteBuffer(commands, xi_sum_d, CL_TRUE, 0, sizeof(float) * nstates * nstates, xi_sum_d_zeros, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "writing buffer xi_sum_d");
    free(xi_sum_d_zeros);

    /* Calculate running xi sum */
    // dim3 threads(BLOCK_DIM, BLOCK_DIM);
    nblocks = (nstates + BLOCK_DIM - 1) / BLOCK_DIM;
    // dim3 grid(nblocks, nblocks);

    size_t globalWorkSize[2] = { nblocks * BLOCK_DIM, nblocks * BLOCK_DIM };
    size_t localWorkSize[2]  = { BLOCK_DIM, BLOCK_DIM };

    /* Find the sum of xi variables */
    for (t = 0; t < length - 1; t++) {

        /* Calculate denominator */
        sum_ab = dot_production(nstates, alpha_d, t * nstates,
				beta_d, t * nstates);

        /* Calculate xi sum */
        // calc_xi_dev<<<grid, threads>>>( xi_sum_d,
        // a_d,
        // b_d,
        // alpha_d,
        // beta_d,
        // sum_ab,
        // nstates,
        // obs[t+1],
        // t);
        errNum  = clSetKernelArg(_cl_kernel_calc_xi_dev, 0, sizeof(cl_mem), &xi_sum_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 1, sizeof(cl_mem), &a_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 2, sizeof(cl_mem), &b_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 3, sizeof(cl_mem), &alpha_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 4, sizeof(cl_mem), &beta_d);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 5, sizeof(float), &sum_ab);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 6, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 7, sizeof(int), obs + t + 1);
        errNum |= clSetKernelArg(_cl_kernel_calc_xi_dev, 8, sizeof(int), &t);
        CHKERR(errNum, "setting kernel _cl_kernel_calc_xi_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_calc_xi_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_calc_xi_dev for execution");
    }

    return 0;
}

/* Re-estimates the state transition probabilities (A) */
int estimate_a()
{
    float sum_ab;
    int nblocks;
    cl_int errNum;

    /* Calculate running xi sum */
    // dim3 threads(BLOCK_DIM, BLOCK_DIM);
    nblocks = (nstates + BLOCK_DIM - 1) / BLOCK_DIM;
    // dim3 grid(nblocks, nblocks);

    size_t globalWorkSize[2] = { nblocks * BLOCK_DIM, nblocks * BLOCK_DIM };
    size_t localWorkSize[2]  = { BLOCK_DIM, BLOCK_DIM };

    /* Calculate denominator */
    sum_ab = dot_production(nstates, alpha_d, (length - 1) * nstates,
                            beta_d, (length - 1) * nstates);

    /* Calculate new value of A */
    // est_a_dev<<<grid, threads>>>(   a_d,
    // alpha_d,
    // beta_d,
    // xi_sum_d,
    // gamma_sum_d,
    // sum_ab,
    // nstates,
    // length);
    errNum  = clSetKernelArg(_cl_kernel_est_a_dev, 0, sizeof(cl_mem), &a_d);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 1, sizeof(cl_mem), &alpha_d);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 2, sizeof(cl_mem), &beta_d);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 3, sizeof(cl_mem), &xi_sum_d);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 4, sizeof(cl_mem), &gamma_sum_d);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 5, sizeof(float), &sum_ab);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 6, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_est_a_dev, 7, sizeof(int), &length);
    CHKERR(errNum, "setting kernel _cl_kernel_est_a_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_est_a_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_est_a_dev for execution");

    /* Sum rows of A to get scaling values */
    // mat_vec_mul( 'T', nstates, nstates, 1.0f, a_d, nstates,
    // ones_n_d, 1, 0, c_d, 1 );
    mat_vec_mul( 't', nstates, nstates, a_d, nstates,
                 ones_n_d, 0, c_d, 0);

    /* Normalize A matrix */
    // scale_a_dev<<<grid, threads>>>( a_d,
    // c_d,
    // nstates);
    errNum  = clSetKernelArg(_cl_kernel_scale_a_dev, 0, sizeof(cl_mem), &a_d);
    errNum |= clSetKernelArg(_cl_kernel_scale_a_dev, 1, sizeof(cl_mem), &c_d);
    errNum |= clSetKernelArg(_cl_kernel_scale_a_dev, 2, sizeof(int), &nstates);
    CHKERR(errNum, "setting kernel _cl_kernel_scale_a_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_scale_a_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_scale_a_dev for execution");

    return 0;
}

/* Re-estimates the output symbol probabilities (B) */
int estimate_b()
{

    float sum_ab;
    int size;
    int t;
    int grid_x, grid_y;
    cl_int errNum;

    // init to zeros
    int *b_d_zeros = (int*)calloc(nstates * nsymbols, sizeof(float));
    errNum = clEnqueueWriteBuffer(commands, b_d, CL_TRUE, 0, sizeof(float) * nstates * nsymbols, b_d_zeros, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "writing buffer b_d");
    free(b_d_zeros);

    /* Calculate number of threads and blocks needed */
    grid_x = (nstates + BLOCK_DIM - 1) / BLOCK_DIM;
    grid_y = (nsymbols + BLOCK_DIM - 1) / BLOCK_DIM;

    size_t globalWorkSize[2] = { grid_x * BLOCK_DIM, grid_y * BLOCK_DIM };
    size_t localWorkSize[2]  = { BLOCK_DIM, BLOCK_DIM };

    for (t = 0; t < length; t++) {

        /* Calculate denominator */
        sum_ab = dot_production(nstates, alpha_d, t * nstates,
				beta_d, t * nstates);

        /* Accumulate B values */
        // acc_b_dev<<<grid, threads>>>(   b_d,
        // alpha_d,
        // beta_d,
        // sum_ab,
        // nstates,
        // nsymbols,
        // obs[t],
        // t);
        errNum  = clSetKernelArg(_cl_kernel_acc_b_dev, 0, sizeof(cl_mem), &b_d);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 1, sizeof(cl_mem), &alpha_d);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 2, sizeof(cl_mem), &beta_d);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 3, sizeof(float), &sum_ab);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 4, sizeof(int), &nstates);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 5, sizeof(int), &nsymbols);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 6, sizeof(int), obs + t);
        errNum |= clSetKernelArg(_cl_kernel_acc_b_dev, 7, sizeof(int), &t);
        CHKERR(errNum, "setting kernel _cl_kernel_acc_b_dev arguments");

        errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_acc_b_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
        clFinish(commands);
        CHKERR(errNum, "queuing kernel _cl_kernel_acc_b_dev for execution");

    }

    /* Re-estimate B values */
    // est_b_dev<<<grid, threads>>>(b_d, gamma_sum_d, nstates, nsymbols);
    errNum  = clSetKernelArg(_cl_kernel_est_b_dev, 0, sizeof(cl_mem), &b_d);
    errNum |= clSetKernelArg(_cl_kernel_est_b_dev, 1, sizeof(cl_mem), &gamma_sum_d);
    errNum |= clSetKernelArg(_cl_kernel_est_b_dev, 2, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_est_b_dev, 3, sizeof(int), &nsymbols);
    CHKERR(errNum, "setting kernel _cl_kernel_est_b_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_est_b_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_est_b_dev for execution");

    /* Sum rows of B to get scaling values */
    // mat_vec_mul( 'N', nstates, nsymbols, 1.0f, b_d, nstates,
    // ones_s_d, 1, 0, c_d, 1 );
    mat_vec_mul( 'n', nstates, nsymbols, b_d, nstates,
                 ones_s_d, 0, c_d, 0);

    /* Normalize B matrix */
    // scale_b_dev<<<grid, threads>>>( b_d,
    // c_d,
    // nstates,
    // nsymbols);
    errNum  = clSetKernelArg(_cl_kernel_scale_b_dev, 0, sizeof(cl_mem), &b_d);
    errNum |= clSetKernelArg(_cl_kernel_scale_b_dev, 1, sizeof(cl_mem), &c_d);
    errNum |= clSetKernelArg(_cl_kernel_scale_b_dev, 2, sizeof(int), &nstates);
    errNum |= clSetKernelArg(_cl_kernel_scale_b_dev, 3, sizeof(int), &nsymbols);
    CHKERR(errNum, "setting kernel _cl_kernel_scale_b_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_scale_b_dev, 2, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_scale_b_dev for execution");

    return 0;
}

/* Re-estimates the initial state probabilities (Pi) */
int estimate_pi()
{

    float sum_ab;
    int threads_per_block;
    int nblocks;
    cl_int errNum;

    /* Calculate denominator */
    sum_ab = dot_production(nstates, alpha_d, 0, beta_d, 0);

    /* Estimate Pi values */
    threads_per_block = MAX_THREADS_PER_BLOCK;
    nblocks = (nstates + threads_per_block - 1) / threads_per_block;
    size_t globalWorkSize[1] = { nblocks * threads_per_block };
    size_t localWorkSize[1]  = { threads_per_block };

    // est_pi_dev<<<nblocks, threads_per_block>>>( pi_d,
    // alpha_d,
    // beta_d,
    // sum_ab,
    // nstates);
    errNum  = clSetKernelArg(_cl_kernel_est_pi_dev, 0, sizeof(cl_mem), &pi_d);
    errNum |= clSetKernelArg(_cl_kernel_est_pi_dev, 1, sizeof(cl_mem), &alpha_d);
    errNum |= clSetKernelArg(_cl_kernel_est_pi_dev, 2, sizeof(cl_mem), &beta_d);
    errNum |= clSetKernelArg(_cl_kernel_est_pi_dev, 3, sizeof(float), &sum_ab);
    errNum |= clSetKernelArg(_cl_kernel_est_pi_dev, 4, sizeof(int), &nstates);
    CHKERR(errNum, "setting kernel _cl_kernel_est_pi_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_est_pi_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "queuing kernel _cl_kernel_est_pi_dev for execution");

    return 0;
}

void printM(float *mat, int m, int n){
    int i,j;
    for(i=0;i<m;++i){
        for(j=0;j<n;++j){
            fprintf(stderr, "%lf,", mat[i*n+j]);
        }
        fprintf(stderr, "\n");
    }
}

void printMD(cl_mem *a, int m, int n){
    float *x= malloc(sizeof(float)*m*n);
    clEnqueueReadBuffer(commands, a, CL_TRUE, 0, sizeof(float)*m*n, x, 0, NULL, NULL);
    clFinish(commands);
    printM(x, m, n);
    free(x);
}

/*******************************************************************************
 * BWA function
 */

/* Runs the Baum-Welch Algorithm on the supplied HMM and observation sequence */
float run_hmm_bwa(  Hmm *hmm,
                    Obs *in_obs,
                    int iterations,
                    float threshold)
{

    cl_int errNum;

    /* Host-side variables */
    float *a;
    float *b;
    float *pi;
    int threads_per_block;
    int nblocks;
    int size;
    float new_log_lik;
    float old_log_lik = 0;
    int iter;
    /* init the opencl context and kernels */

    init_cl();

    /* Initialize HMM values */
    a = hmm->a;
    b = hmm->b;
    pi = hmm->pi;
    nsymbols = hmm->nsymbols;
    nstates = hmm->nstates;
    obs = in_obs->data;
    length = in_obs->length;

    /* Allocate host memory */
    scale = (float *) malloc(sizeof(float) * length);
    if (scale == 0) {
        fprintf (stderr, "ERROR: Host memory allocation error (scale)\n");
        return EXIT_ERROR;
    }

    /* Allocate device memory */
    a_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates * nstates, NULL, NULL);
    b_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates * nsymbols, NULL, NULL);
    pi_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates, NULL, NULL);
    alpha_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates * length, NULL, NULL);
    beta_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates * length, NULL, NULL);
    gamma_sum_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates, NULL, NULL);
    xi_sum_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates * nstates, NULL, NULL);
    c_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates, NULL, NULL);
    ones_n_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nstates, NULL, NULL);
    ones_s_d = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * nsymbols, NULL, NULL);

    CHECK_NULL_ERROR( a_d, "Error creating buffer for a_d");
    CHECK_NULL_ERROR( b_d, "Error creating buffer for  b_d");
    CHECK_NULL_ERROR( pi_d, "Error creating buffer for  pi_d");
    CHECK_NULL_ERROR( alpha_d, "Error creating buffer for  alpha_d");
    CHECK_NULL_ERROR( beta_d, "Error creating buffer for  beta_d");
    CHECK_NULL_ERROR( gamma_sum_d, "Error creating buffer for  gamma_sum_d");
    CHECK_NULL_ERROR( xi_sum_d, "Error creating buffer for  xi_sum_d");
    CHECK_NULL_ERROR( c_d, "Error creating buffer for  c_d");
    CHECK_NULL_ERROR( ones_n_d, "Error creating buffer for  ones_n_d");
    CHECK_NULL_ERROR( ones_s_d, "Error creating buffer for  ones_s_d");

    /* Transfer device data */
    errNum = clEnqueueWriteBuffer(commands, a_d, CL_TRUE, 0, sizeof(float) * nstates * nstates, a, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error writing buffer a_d");

    errNum = clEnqueueWriteBuffer(commands, b_d, CL_TRUE, 0, sizeof(float) * nstates * nsymbols, b, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error writing buffer b_d");

    errNum = clEnqueueWriteBuffer(commands, pi_d, CL_TRUE, 0, sizeof(float) * nstates, pi, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error writing buffer pi_d");

    /* Initialize ones array */
    threads_per_block = MAX_THREADS_PER_BLOCK;
    nblocks = (nstates + threads_per_block - 1) / threads_per_block;
    size_t globalWorkSize[1] = { nblocks * threads_per_block };
    size_t localWorkSize[1]  = { threads_per_block };

    // init_ones_dev<<<nblocks, threads_per_block>>>(ones_s_d, nsymbols);
    errNum  = clSetKernelArg(_cl_kernel_init_ones_dev, 0, sizeof(cl_mem), &ones_s_d);
    errNum |= clSetKernelArg(_cl_kernel_init_ones_dev, 1, sizeof(int), &nsymbols);
    CHKERR(errNum, "Error setting kernel _cl_kernel_init_ones_dev arguments");

    errNum = clEnqueueNDRangeKernel(commands, _cl_kernel_init_ones_dev, 1, NULL, globalWorkSize, localWorkSize, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error queuing kernel _cl_kernel_init_ones_dev for execution");

    /* Run BWA for either max iterations or until threshold is reached */
    for (iter = 0; iter < iterations; iter++) {

        new_log_lik = calc_alpha();
        if (new_log_lik == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        if (calc_beta() == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        calc_gamma_sum();

        if (calc_xi_sum() == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        if (estimate_a() == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        if (estimate_b() == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        printMD(b_d, nsymbols, nstates);

        if (estimate_pi() == EXIT_ERROR) {
            return EXIT_ERROR;
        }

        /* check log_lik vs. threshold */
        if (threshold > 0 && iter > 0) {
            if (fabs(pow(10,new_log_lik) - pow(10,old_log_lik)) < threshold) {
                // break;
            }
        }

        old_log_lik = new_log_lik;
    }

    /* Copy device variables back to host */
    errNum = clEnqueueReadBuffer(commands, a_d, CL_TRUE, 0, sizeof(float) * nstates * nstates, a, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error reading buffer a_d");

    errNum = clEnqueueReadBuffer(commands, b_d, CL_TRUE, 0, sizeof(float) * nstates * nsymbols, b, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error reading buffer b_d");

    errNum = clEnqueueReadBuffer(commands, pi_d, CL_TRUE, 0, sizeof(float) * nstates, pi, 0, NULL, &ocdTempEvent);
    clFinish(commands);
    CHKERR(errNum, "Error reading buffer pi_d");

    clFinish(commands);
    /* Free memory */
    free(scale);

    clReleaseMemObject(a_d);
    clReleaseMemObject(b_d);
    clReleaseMemObject(pi_d);
    clReleaseMemObject(alpha_d);
    clReleaseMemObject(beta_d);
    clReleaseMemObject(gamma_sum_d);
    clReleaseMemObject(xi_sum_d);
    clReleaseMemObject(c_d);
    clReleaseMemObject(ones_n_d);
    clReleaseMemObject(ones_s_d);

    clReleaseKernel(_cl_kernel_init_ones_dev);
    clReleaseKernel(_cl_kernel_init_alpha_dev);
    clReleaseKernel(_cl_kernel_calc_alpha_dev);
    clReleaseKernel(_cl_kernel_scale_alpha_dev);
    clReleaseKernel(_cl_kernel_init_beta_dev);
    clReleaseKernel(_cl_kernel_calc_beta_dev);
    clReleaseKernel(_cl_kernel_calc_gamma_dev);
    clReleaseKernel(_cl_kernel_calc_xi_dev);
    clReleaseKernel(_cl_kernel_est_a_dev);
    clReleaseKernel(_cl_kernel_scale_a_dev);
    clReleaseKernel(_cl_kernel_acc_b_dev);
    clReleaseKernel(_cl_kernel_est_b_dev);
    clReleaseKernel(_cl_kernel_scale_b_dev);
    clReleaseKernel(_cl_kernel_est_pi_dev);
    clReleaseKernel(_cl_kernel_s_dot_kernel_naive);
    clReleaseKernel(_cl_kernel_sgemvt_kernel_naive);
    clReleaseKernel(_cl_kernel_sgemvn_kernel_naive);
    clReleaseProgram(_cl_program);
    clReleaseCommandQueue(commands);
    clReleaseContext(context);

    return new_log_lik;
}

static struct option size_opts[] =
{
    /* name, has_tag, flag, val*/
    {"state number", 1, NULL, 'n'},
    {"symbol number", 1, NULL, 's'},
    {"observation number", 1, NULL, 't'},
    {"varying mode", 1, NULL, 'v'},
    {0, 0, 0, 0}
};

/* Time the forward algorithm and vary the number of states */
int main(int argc, char *argv[])
{
    /* Initialize variables */
    Hmm *hmm;                /* Initial HMM */
    Obs *obs;                /* Observation sequence */
    float *a;
    float *b;
    float *pi;
    int *obs_seq;
    float log_lik;           /* Output likelihood of FO */
    int mul;
    int m;
    int s = S, t = T;
    int n = N;
    int i;
    stopwatch sw;

    fprintf(stderr, "Starting bwa_hmm\n");
    ocd_init(&argc, &argv, NULL);

    int opt, opt_index = 0;
    char v_model;
    while((opt = getopt_long(argc, argv, "::n:s:t:v:", size_opts, &opt_index)) != -1)
    {
        //fprintf(stderr, "here");
        switch(opt)
        {
        case 'v':
            v_model = optarg[0];
            break;
        case 'n':
            n = atoi(optarg);
            break;
        case 's':
            s = atoi(optarg);
            break;
        case 't':
            t = atoi(optarg);
            break;
        default:
            fprintf(stderr, "Usage %s [-n state number | -s symbol number | -t observation number] [-v varying model]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    /* Initialize HMM and observation sequence */
    hmm = (Hmm *)malloc(sizeof(Hmm));
    obs = (Obs *)malloc(sizeof(Obs));

    if(v_model == 'n')
    {
        /* Create observation sequence */
        obs->length = T;
        obs_seq = (int *)malloc(sizeof(int) * T);
        for (i = 0; i < T; i++) {
            obs_seq[i] = 0;
        }
        obs->data = obs_seq;

        // fprintf(stderr, "Vary states with S = %i, T = %i\n", S, T);
        // fprintf(stderr, "States\tTime (s)\tLog_likelihood\n");

        /* Run timed tests from 1*mul to 9*mul states */
        if (n >= 8000) {
            return 0;
        }
        // n = 7000;
        /* Assign HMM parameters */
        hmm->nstates = n;
        hmm->nsymbols = S;
        a = (float *)malloc(sizeof(float) * n * n);
        for (i = 0; i < (n * n); i++) {
            a[i] = 1.0f/(float)n;
        }
        hmm->a = a;
        b = (float *)malloc(sizeof(float) * n * S);
        for (i = 0; i < (n * S); i++) {
            b[i] = 1.0f/(float)S;
        }
        hmm->b = b;
        pi = (float *)malloc(sizeof(float) * n);
        for (i = 0; i < n; i++) {
            pi[i] = 1.0f/(float)n;
        }
        hmm->pi = pi;

        /* Run the BWA on the observation sequence */

        stopwatch_start(&sw);
        log_lik = run_hmm_bwa(hmm, obs, ITERATIONS, 0);
        stopwatch_stop(&sw);
        fprintf(stderr, "Observations\tTime (s)\tLog_likelihood\n");
        fprintf(stderr, "%i\t", n);
        fprintf(stderr, "%f\n", log_lik);

        /* Free memory */
        free(a);
        free(b);
        free(pi);

        hmm->a = NULL;
        hmm->b = NULL;
        hmm->pi = NULL;
        free_vars(hmm, obs);

        // fprintf(stderr, "\n");
    } else if(v_model == 's')
    {
        /* Create observation sequence */
        obs->length = T;
        obs_seq = (int *)malloc(sizeof(int) * T);
        for (i = 0; i < T; i++) {
            obs_seq[i] = 0;
        }
        obs->data = obs_seq;

        // fprintf(stderr, "Vary symbols with N = %i, T = %i\n", N, T);
        // fprintf(stderr, "Symbols\tTime (s)\tLog_likelihood\n");

        if (s >= 8000) {
            return 0;
        }

        /* Assign HMM parameters */
        hmm->nstates = N;
        hmm->nsymbols = s;
        a = (float *)malloc(sizeof(float) * N * N);
        for (i = 0; i < (N * N); i++) {
            a[i] = 1.0f/(float)N;
        }
        hmm->a = a;
        b = (float *)malloc(sizeof(float) * N * s);
        for (i = 0; i < (N * s); i++) {
            b[i] = 1.0f/(float)s;
        }
        hmm->b = b;
        pi = (float *)malloc(sizeof(float) * N);
        for (i = 0; i < N; i++) {
            pi[i] = 1.0f/(float)N;
        }
        hmm->pi = pi;

        /* Run the BWA on the observation sequence */

        stopwatch_start(&sw);
        log_lik = run_hmm_bwa(hmm, obs, ITERATIONS, 0);
        stopwatch_stop(&sw);
        fprintf(stderr, "Observations\tTime (s)\tLog_likelihood\n");
        fprintf(stderr, "%i\t", s);
        fprintf(stderr, "%f\n", log_lik);

        /* Free memory */
        free(a);
        free(b);
        free(pi);

        hmm->a = NULL;
        hmm->b = NULL;
        hmm->pi = NULL;
        free_vars(hmm, obs);

        // fprintf(stderr, "\n");

    } else if(v_model == 't')
    {

        if (t >= 10000) {
            return 0;
        }
        /* Create HMM */
        hmm->nstates = N;
        hmm->nsymbols = S;
        a = (float *)malloc(sizeof(float) * N * N);
        for (i = 0; i < (N * N); i++) {
            a[i] = 1.0f/(float)N;
        }
        hmm->a = a;
        b = (float *)malloc(sizeof(float) * N * S);
        for (i = 0; i < (N * S); i++) {
            b[i] = 1.0f/(float)S;
        }
        hmm->b = b;
        pi = (float *)malloc(sizeof(float) * N);
        for (i = 0; i < N; i++) {
            pi[i] = 1.0f/(float)N;
        }
        hmm->pi = pi;

        // fprintf(stderr, "Vary observations with N = %i, S = %i\n", N, S);
        // fprintf(stderr, "Observations\tTime (s)\tLog_likelihood\n");

        /* Create observation sequence */
        obs->length = t;
        obs_seq = (int *)malloc(sizeof(int) * t);
        for (i = 0; i < t; i++) {
            obs_seq[i] = 0;
        }
        obs->data = obs_seq;

        /* Run the BWA on the observation sequence */

        stopwatch_start(&sw);
        log_lik = run_hmm_bwa(hmm, obs, ITERATIONS, 0);
        stopwatch_stop(&sw);
        fprintf(stderr, "Observations\tTime (s)\tLog_likelihood\n");
        fprintf(stderr, "%i\t", t);
        fprintf(stderr, "%f\n", log_lik);

        /* Free memory */
        free(obs_seq);

        obs->data = NULL;
        free_vars(hmm, obs);

        // fprintf(stderr, "\n");
    }

    printf("{ \"status\": %d, \"options\": \"-v %c -n %d\", \"time\": %f }\n", 1, v_model, n, get_interval_by_sec(&sw));

    ocd_finalize();//KK
    return;
}


text:
layout: default
number: 8
---

Congratulations! You've completed all the lessons!

Believe it or not, we've only _just begun_ exploring what can be accomplished
with Markdown. There are many "extended" implementations of Markdown that support
formats like tables, definition lists, footnotes, and more. Because
they're non-standard, they're not essential to learning the basics, as we've
introduced here.

If you'd like to know more about these Markdown implementations, you're welcome
to explore any number of other Markdown apps and tutorials. Here are just a few:

* <http://en.wikipedia.org/wiki/Markdown#Syntax_examples>
* <http://johnmacfarlane.net/babelmark2/faq.html>
* <http://idratherbewriting.com/2013/06/04/exploring-markdown-in-collaborative-authoring-to-publishing-workflows/>


text:
{% block foot %}

    {% for item in assets.main.js %}

    {% endfor %}

    {% if pages._current == 'index' %}

    {% endif %}
{% endblock %}


text:
namespace plugin {

TEST(CallbackParserTest, ParseLineNoArguments) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine("forward OnGameModeInit();", &callback));

  EXPECT_EQ("OnGameModeInit", callback.name);
  EXPECT_EQ(0u, callback.arguments.size());
  EXPECT_FALSE(callback.cancelable);
}

TEST(CallbackParserTest, ParseLineCancelableAnnotation) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine("[Cancelable] forward OnGameModeExit();", &callback));

  EXPECT_EQ("OnGameModeExit", callback.name);
  EXPECT_EQ(0u, callback.arguments.size());
  EXPECT_TRUE(callback.cancelable);
}

TEST(CallbackParserTest, ParseLineUnknownAnnotation) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine("[CatsAreAwesome, ReturnOne, Cancelable] forward OnFilterScriptInit();", &callback));

  EXPECT_EQ("OnFilterScriptInit", callback.name);
  EXPECT_EQ(0u, callback.arguments.size());
  EXPECT_EQ(1, callback.return_value);
  EXPECT_TRUE(callback.cancelable);
}

TEST(CallbackParserTest, ParseLineOneArgument) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine("forward OnPlayerUpdate(playerid);", &callback));

  EXPECT_EQ("OnPlayerUpdate", callback.name);
  ASSERT_EQ(1u, callback.arguments.size());

  const auto& first_argument = callback.arguments[0];
  EXPECT_EQ("playerid", first_argument.first);
  EXPECT_EQ(ARGUMENT_TYPE_INT, first_argument.second);

  EXPECT_FALSE(callback.cancelable);
}

TEST(CallbackParserTest, ParseLineMultipleArguments) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine("forward OnMyCustomCallback(playerid, Float:health, name[]);", &callback));

  EXPECT_EQ("OnMyCustomCallback", callback.name);
  ASSERT_EQ(3u, callback.arguments.size());

  const auto first_argument = callback.arguments[0];
  EXPECT_EQ("playerid", first_argument.first);
  EXPECT_EQ(ARGUMENT_TYPE_INT, first_argument.second);

  const auto second_argument = callback.arguments[1];
  EXPECT_EQ("health", second_argument.first);
  EXPECT_EQ(ARGUMENT_TYPE_FLOAT, second_argument.second);

  const auto third_argument = callback.arguments[2];
  EXPECT_EQ("name", third_argument.first);
  EXPECT_EQ(ARGUMENT_TYPE_STRING, third_argument.second);

  EXPECT_FALSE(callback.cancelable);
}

TEST(CallbackParserTest, ParseWithWhitespace) {
  Callback callback;

  std::unique_ptr<CallbackParser> parser(new CallbackParser());
  ASSERT_TRUE(parser->ParseLine(" [ Cancelable ]  forward  OnMyCustomCallback  ( playerid , Float : health , name [ ] ) ; ", &callback));

  EXPECT_EQ("OnMyCustomCallback", callback.name);
  EXPECT_EQ(3u, callback.arguments.size());
  EXPECT_TRUE(callback.cancelable);
}

TEST(CallbackParserTest, ParseFromString) {
  const char callback_content[] =
      "forward OnMyCallback();\n"
      "forward OnMySecondCallback();";

  std::unique_ptr<CallbackParser> parser(CallbackParser::FromString(callback_content));
  ASSERT_TRUE(parser != nullptr);

  EXPECT_EQ(2u, parser->size());
}

TEST(CallbackParserTest, ParseFromFile) {
  // TODO: Write a test where a file is actually loaded.
}

TEST(CallbackParserTest, ParseIgnoreComments) {
  const char callback_content[] =
      "forward OnMyCallback();\n"
      "forward OnMySecondCallback();\n"
      "# forward OnMyThirdCallback();\n"
      "  # forward OnMyFourthCallback();\n"
      "// forward OnMyFifthCallback();\n"
      "forward OnMySixthCallback();";

  std::unique_ptr<CallbackParser> parser(CallbackParser::FromString(callback_content));
  ASSERT_TRUE(parser != nullptr);

  EXPECT_EQ(3u, parser->size());
}

TEST(CallbackParserTest, Iterable) {
  const char callback_content[] =
      "forward OnMyCallback();\n"
      "forward OnMySecondCallback();";

  std::unique_ptr<CallbackParser> parser(CallbackParser::FromString(callback_content));
  ASSERT_TRUE(parser != nullptr);

  std::set<std::string> remaining_callbacks;
  remaining_callbacks.insert("OnMyCallback");
  remaining_callbacks.insert("OnMySecondCallback");

  ASSERT_EQ(remaining_callbacks.size(), parser->size());

  for (auto& callback : *parser)
    remaining_callbacks.erase(callback.name);

  EXPECT_EQ(0u, remaining_callbacks.size());
}

}  // namespace plugin


text:
docker rm `docker ps -a | grep buildserver | awk '{print $1;}'`

# Always exit cleanly
exit 0


text:
"""
Examples to show how to create async EventHubProducerClient and EventHubConsumerClient that connect to custom endpoint.
"""

import os
from azure.servicebus import ServiceBusClient, ServiceBusMessage

CONNECTION_STR = os.environ['SERVICEBUS_CONNECTION_STR']
QUEUE_NAME = os.environ["SERVICEBUS_QUEUE_NAME"]
# The custom endpoint address to use for establishing a connection to the Service Bus service,
# allowing network requests to be routed through any application gateways
# or other paths needed for the host environment.
CUSTOM_ENDPOINT_ADDRESS = 'sb://<custom_endpoint_hostname>:<custom_endpoint_port>'
# The optional absolute path to the custom certificate file used by client to authenticate the
# identity of the connection endpoint in the case that endpoint has its own issued CA.
# If not set, the certifi library will be used to load certificates.
CUSTOM_CA_BUNDLE_PATH = '<your_custom_ca_bundle_file_path>'

def send_single_message(sender):
    message = ServiceBusMessage("Single Message")
    sender.send_messages(message)

servicebus_client = ServiceBusClient.from_connection_string(
    conn_str=CONNECTION_STR,
    logging_enable=True,
    custom_endpoint_address=CUSTOM_ENDPOINT_ADDRESS,
    connection_verify=CUSTOM_CA_BUNDLE_PATH
    )
with servicebus_client:
    sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
    with sender:
        send_single_message(sender)


text:
module CLasH.Utils.Pretty (prettyShow, pprString, pprStringDebug, zEncodeString) where

-- Standard imports
import qualified Data.Map as Map
import Text.PrettyPrint.HughesPJClass
import Data.Char
import Numeric

-- GHC API
import qualified CoreSyn
import Outputable ( showSDoc, showSDocDebug, ppr, Outputable, OutputableBndr)

-- VHDL Imports
import qualified Language.VHDL.Ppr as Ppr
import qualified Language.VHDL.AST as AST
import qualified Language.VHDL.AST.Ppr

-- Local imports
import CLasH.VHDL.VHDLTypes
import CLasH.Utils.Core.CoreShow

-- | A version of the default pPrintList method, which uses a custom function
--   f instead of pPrint to print elements.
printList :: (a -> Doc) -> [a] -> Doc
printList f = brackets . fsep . punctuate comma . map f

{-
instance Pretty FuncData where
  pPrint (FuncData flatfunc entity arch) =
    text "Flattened: " $$ nest 15 (ppffunc flatfunc)
    $+$ text "Entity" $$ nest 15 (ppent entity)
    $+$ pparch arch
    where
      ppffunc (Just f) = pPrint f
      ppffunc Nothing  = text "Nothing"
      ppent (Just e)   = pPrint e
      ppent Nothing    = text "Nothing"
      pparch Nothing = text "VHDL architecture not present"
      pparch (Just _) = text "VHDL architecture present"
-}

instance Pretty Entity where
  pPrint (Entity id args res decl) =
    text "Entity: " $$ nest 10 (pPrint id)
    $+$ text "Args: " $$ nest 10 (pPrint args)
    $+$ text "Result: " $$ nest 10 (pPrint res)
    $+$ text "Declaration not shown"

instance (OutputableBndr b, Show b) => Pretty (CoreSyn.Bind b) where
  pPrint (CoreSyn.NonRec b expr) =
    text "NonRec: " $$ nest 10 (prettyBind (b, expr))
  pPrint (CoreSyn.Rec binds) =
    text "Rec: " $$ nest 10 (vcat $ map (prettyBind) binds)

instance (OutputableBndr b, Show b) => Pretty (CoreSyn.Expr b) where
  pPrint = text . show

instance Pretty AST.VHDLId where
  pPrint id = Ppr.ppr id

instance Pretty AST.VHDLName where
  pPrint name = Ppr.ppr name

prettyBind :: (Show b, Show e) => (b, e) -> Doc
prettyBind (b, expr) =
  text b' <> text " = " <> text expr'
  where
    b' = show b
    expr' = show expr

instance (Pretty k, Pretty v) => Pretty (Map.Map k v) where
  pPrint =
    vcat . map ppentry . Map.toList
    where
      ppentry (k, v) =
        pPrint k <> text " : " $$ nest 15 (pPrint v)

-- Convenience method for turning an Outputable into a string
pprString :: (Outputable x) => x -> String
pprString = showSDoc . ppr

pprStringDebug :: (Outputable x) => x -> String
pprStringDebug = showSDocDebug . ppr

type UserString = String        -- As the user typed it
type EncodedString = String     -- Encoded form

zEncodeString :: UserString -> EncodedString
zEncodeString cs = case maybe_tuple cs of
                Just n  -> n ++ (go cs)            -- Tuples go to Z2T etc
                Nothing -> go cs
          where
                go []     = []
                go (c:cs) = encode_digit_ch c ++ go' cs
                go' []     = []
                go' (c:cs) = encode_ch c ++ go' cs

maybe_tuple :: UserString -> Maybe EncodedString

maybe_tuple "(# #)" = Just("Z1H")
maybe_tuple ('(' : '#' : cs) = case count_commas (0::Int) cs of
                                 (n, '#' : ')' : _) -> Just ('Z' : shows (n+1) "H")
                                 _                  -> Nothing
maybe_tuple "()" = Just("Z0T")
maybe_tuple ('(' : cs)       = case count_commas (0::Int) cs of
                                 (n, ')' : _) -> Just ('Z' : shows (n+1) "T")
                                 _            -> Nothing
maybe_tuple _                = Nothing

count_commas :: Int -> String -> (Int, String)
count_commas n (',' : cs) = count_commas (n+1) cs
count_commas n cs         = (n,cs)

encode_digit_ch :: Char -> EncodedString
encode_digit_ch c | c >= '0' && c <= '9' = encode_as_unicode_char c
encode_digit_ch c | otherwise            = encode_ch c

encode_ch :: Char -> EncodedString
encode_ch c | unencodedChar c = [c]     -- Common case first

-- Constructors
encode_ch '('  = "ZL"   -- Needed for things like (,), and (->)
encode_ch ')'  = "ZR"   -- For symmetry with (
encode_ch '['  = "ZM"
encode_ch ']'  = "ZN"
encode_ch ':'  = "ZC"

-- Variables
encode_ch '&'  = "za"
encode_ch '|'  = "zb"
encode_ch '^'  = "zc"
encode_ch '$'  = "zd"
encode_ch '='  = "ze"
encode_ch '>'  = "zg"
encode_ch '#'  = "zh"
encode_ch '.'  = "zi"
encode_ch '<'  = "zl"
encode_ch '-'  = "zm"
encode_ch '!'  = "zn"
encode_ch '+'  = "zp"
encode_ch '\'' = "zq"
encode_ch '\\' = "zr"
encode_ch '/'  = "zs"
encode_ch '*'  = "zt"
encode_ch '%'  = "zv"
encode_ch c    = encode_as_unicode_char c

encode_as_unicode_char :: Char -> EncodedString
encode_as_unicode_char c = 'z' : if isDigit (head hex_str) then hex_str
                                                           else '0':hex_str
  where hex_str = showHex (ord c) "U"

unencodedChar :: Char -> Bool   -- True for chars that don't need encoding
unencodedChar c   =  c >= 'a' && c <= 'z'
                  || c >= 'A' && c <= 'Z'
                  || c >= '0' && c <= '9'
                  || c == '_'


text:
SYNONYM

#### According to
Index Fungorum

#### Published in
Unters. Gesammtgeb. Mykol. 15: 143 (1912)

#### Original name
Irpicium Bref.

### Remarks
null


text:
AirbrakeError Constructor
=========================
Initializes a new instance of the [AirbrakeError][1] class

**Namespace:** [Airbraker.Data][2]
**Assembly:**

Syntax
------

```csharp
public AirbrakeError()
```

See Also
--------

### Reference
[AirbrakeError Class][1]
[Airbraker.Data Namespace][2]

[1]: README.md
[2]: ../README.md


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/section_relative_layout"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:clickable="true"
    android:focusable="true"
    android:foreground="?android:attr/selectableItemBackground"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/section_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="8dp"
        android:layout_toLeftOf="@+id/section_notification"
        android:layout_toStartOf="@+id/section_notification"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2"
        android:textColor="@android:color/black"
        android:textSize="@dimen/sectionSize" />

    <TextView
        android:id="@+id/section_notification"
        android:layout_width="40dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="8dp"
        android:gravity="center_horizontal"
        android:lines="1"
        android:maxLength="3"
        android:textColor="@android:color/black"
        android:textSize="@dimen/sectionNotificationSize"
        android:textStyle="bold" />

</RelativeLayout>


text:
package com.ogaclejapan.qiitanium.presentation.activity;

import com.norbsoft.typefacehelper.TypefaceHelper;
import com.ogaclejapan.qiitanium.R;
import com.ogaclejapan.qiitanium.presentation.fragment.ArticleListFragment;
import com.ogaclejapan.qiitanium.presentation.fragment.ComingSoonFragment;
import com.ogaclejapan.qiitanium.presentation.fragment.ComingSoonScrollableFragment;
import com.ogaclejapan.qiitanium.presentation.fragment.TagListFragment;
import com.ogaclejapan.qiitanium.presentation.helper.ParallaxHeaderHelper;
import com.ogaclejapan.qiitanium.presentation.helper.SlidingUpPanelHelper;
import com.ogaclejapan.qiitanium.presentation.listener.Refreshable;
import com.ogaclejapan.qiitanium.presentation.listener.ScrollableTab;
import com.ogaclejapan.qiitanium.presentation.listener.ScrollableTabListener;
import com.ogaclejapan.qiitanium.presentation.view.OverlayTopMenuView;
import com.ogaclejapan.qiitanium.util.ViewUtils;
import com.ogaclejapan.smarttablayout.SmartTabLayout;
import com.ogaclejapan.smarttablayout.utils.v13.FragmentPagerItemAdapter;
import com.ogaclejapan.smarttablayout.utils.v13.FragmentPagerItems;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;

import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TextView;

public class TopActivity extends AppActivity
        implements ScrollableTabListener, Refreshable {

    public static void startActivity(Context context) {
        context.startActivity(intentOf(context));
    }

    public static Intent intentOf(Context context) {
        return new Intent(context, TopActivity.class);
    }

    private final ViewPager.SimpleOnPageChangeListener mPageChangeListener =
            new ViewPager.SimpleOnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    Fragment f = mViewPagerAdapter.getPage(position);
                    if (f instanceof ScrollableTab) {
                        ((ScrollableTab) f).adjustScroll(mHeaderHelper.getTranslationY());
                    }
                }
            };

    private OverlayTopMenuView mTopMenu;
    private ParallaxHeaderHelper mHeaderHelper;
    private SlidingUpPanelHelper mPanelHelper;
    private ViewPager mViewPager;
    private FragmentPagerItemAdapter mViewPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top);

        FragmentManager fm = getFragmentManager();

        View header = findViewById(R.id.header);
        View headerImage = findViewById(R.id.header_image);

        mHeaderHelper = new ParallaxHeaderHelper.Builder(header, headerImage)
                .setMinHeight(getDimensionPixelSize(R.dimen.header_min_height))
                .setElevation(getDimensionPixelSize(R.dimen.header_elevation))
                .create();

        SlidingUpPanelLayout slidingUpPanel = ViewUtils.findById(this, R.id.panel);
        mPanelHelper = new SlidingUpPanelHelper(slidingUpPanel);

        TextView title = ViewUtils.findById(this, R.id.title);
        title.setText(R.string.label_articles);

        mViewPagerAdapter = new FragmentPagerItemAdapter(fm, FragmentPagerItems.with(this)
                .add(R.string.tab_new, ArticleListFragment.class)
                .add(R.string.tab_following, ComingSoonScrollableFragment.class)
                .create());

        mViewPager = ViewUtils.findById(this, R.id.article_top_viewpager);
        mViewPager.setAdapter(mViewPagerAdapter);
        SmartTabLayout viewPagerTab = ViewUtils.findById(this, R.id.viewpagertab);
        viewPagerTab.setCustomTabView(R.layout.view_tab, R.id.view_tab_text);
        viewPagerTab.setViewPager(mViewPager);
        viewPagerTab.setOnPageChangeListener(mPageChangeListener);

        TextView tagTitle = ViewUtils.findById(this, R.id.tag_top_title);
        ViewPager tagViewPager = ViewUtils.findById(this, R.id.tag_top_viewpager);
        tagViewPager.setAdapter(new FragmentPagerItemAdapter(fm, FragmentPagerItems.with(this)
                .add(R.string.tab_popular, TagListFragment.class)
                .add(R.string.tab_following, ComingSoonFragment.class)
                .create()));

        SmartTabLayout tagViewPagerTab = ViewUtils.findById(this, R.id.tag_top_viewpagertab);
        tagViewPagerTab.setViewPager(tagViewPager);

        mTopMenu = ViewUtils.findById(this, R.id.overlay_top);
        mTopMenu.bindTo(this);

        TypefaceHelper.typeface(title);
        TypefaceHelper.typeface(tagTitle);
        TypefaceHelper.typeface(viewPagerTab);
        TypefaceHelper.typeface(tagViewPagerTab);

    }

    @Override
    public void onBackPressed() {
        if (mTopMenu.canTurnOff()) {
            mTopMenu.turnOff();
            return;
        }

        if (!mPanelHelper.isCollapsed()) {
            mPanelHelper.collapse();
            return;
        }

        super.onBackPressed();
    }

    @Override
    public void onScroll(int scrollY, int position) {
        if (mViewPager.getCurrentItem() != position) {
            return;
        }

        mHeaderHelper.scroll(scrollY);
    }

    @Override
    public void refresh() {
        final Fragment f = mViewPagerAdapter.getPage(mViewPager.getCurrentItem());
        if (f instanceof Refreshable) {
            ((Refreshable) f).refresh();
        }
    }

}