singa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wang...@apache.org
Subject [50/57] [partial] incubator-singa git commit: create github pages
Date Thu, 07 May 2015 13:08:14 GMT
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/Rakefile
----------------------------------------------------------------------
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..0c0aa41
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,311 @@
+require "rubygems"
+require 'rake'
+require 'yaml'
+require 'time'
+
+SOURCE = "."
+CONFIG = {
+  'version' => "0.3.0",
+  'themes' => File.join(SOURCE, "_includes", "themes"),
+  'layouts' => File.join(SOURCE, "_layouts"),
+  'posts' => File.join(SOURCE, "_posts"),
+  'post_ext' => "md",
+  'theme_package_version' => "0.1.0"
+}
+
+# Path configuration helper
+module JB
+  class Path
+    SOURCE = "."
+    Paths = {
+      :layouts => "_layouts",
+      :themes => "_includes/themes",
+      :theme_assets => "assets/themes",
+      :theme_packages => "_theme_packages",
+      :posts => "_posts"
+    }
+    
+    def self.base
+      SOURCE
+    end
+
+    # build a path relative to configured path settings.
+    def self.build(path, opts = {})
+      opts[:root] ||= SOURCE
+      path = "#{opts[:root]}/#{Paths[path.to_sym]}/#{opts[:node]}".split("/")
+      path.compact!
+      File.__send__ :join, path
+    end
+  
+  end #Path
+end #JB
+
+# Usage: rake post title="A Title" [date="2012-02-09"] [tags=[tag1,tag2]] [category="category"]
+desc "Begin a new post in #{CONFIG['posts']}"
+task :post do
+  abort("rake aborted: '#{CONFIG['posts']}' directory not found.") unless FileTest.directory?(CONFIG['posts'])
+  title = ENV["title"] || "new-post"
+  tags = ENV["tags"] || "[]"
+  category = ENV["category"] || ""
+  category = "\"#{category.gsub(/-/,' ')}\"" if !category.empty?
+  slug = title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
+  begin
+    date = (ENV['date'] ? Time.parse(ENV['date']) : Time.now).strftime('%Y-%m-%d')
+  rescue => e
+    puts "Error - date format must be YYYY-MM-DD, please check you typed it correctly!"
+    exit -1
+  end
+  filename = File.join(CONFIG['posts'], "#{date}-#{slug}.#{CONFIG['post_ext']}")
+  if File.exist?(filename)
+    abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+  end
+  
+  puts "Creating new post: #{filename}"
+  open(filename, 'w') do |post|
+    post.puts "---"
+    post.puts "layout: post"
+    post.puts "title: \"#{title.gsub(/-/,' ')}\""
+    post.puts 'description: ""'
+    post.puts "category: #{category}"
+    post.puts "tags: #{tags}"
+    post.puts "---"
+    post.puts "{% include JB/setup %}"
+  end
+end # task :post
+
+# Usage: rake page name="about.html"
+# You can also specify a sub-directory path.
+# If you don't specify a file extention we create an index.html at the path specified
+desc "Create a new page."
+task :page do
+  name = ENV["name"] || "new-page.md"
+  filename = File.join(SOURCE, "#{name}")
+  filename = File.join(filename, "index.html") if File.extname(filename) == ""
+  title = File.basename(filename, File.extname(filename)).gsub(/[\W\_]/, " ").gsub(/\b\w/){$&.upcase}
+  if File.exist?(filename)
+    abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+  end
+  
+  mkdir_p File.dirname(filename)
+  puts "Creating new page: #{filename}"
+  open(filename, 'w') do |post|
+    post.puts "---"
+    post.puts "layout: page"
+    post.puts "title: \"#{title}\""
+    post.puts 'description: ""'
+    post.puts "---"
+    post.puts "{% include JB/setup %}"
+  end
+end # task :page
+
+desc "Launch preview environment"
+task :preview do
+  system "jekyll serve -w"
+end # task :preview
+
+# Public: Alias - Maintains backwards compatability for theme switching.
+task :switch_theme => "theme:switch"
+
+namespace :theme do
+  
+  # Public: Switch from one theme to another for your blog.
+  #
+  # name - String, Required. name of the theme you want to switch to.
+  #        The theme must be installed into your JB framework.
+  #
+  # Examples
+  #
+  #   rake theme:switch name="the-program"
+  #
+  # Returns Success/failure messages.
+  desc "Switch between Jekyll-bootstrap themes."
+  task :switch do
+    theme_name = ENV["name"].to_s
+    theme_path = File.join(CONFIG['themes'], theme_name)
+    settings_file = File.join(theme_path, "settings.yml")
+    non_layout_files = ["settings.yml"]
+
+    abort("rake aborted: name cannot be blank") if theme_name.empty?
+    abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path)
+    abort("rake aborted: '#{CONFIG['layouts']}' directory not found.") unless FileTest.directory?(CONFIG['layouts'])
+
+    Dir.glob("#{theme_path}/*") do |filename|
+      next if non_layout_files.include?(File.basename(filename).downcase)
+      puts "Generating '#{theme_name}' layout: #{File.basename(filename)}"
+
+      open(File.join(CONFIG['layouts'], File.basename(filename)), 'w') do |page|
+        if File.basename(filename, ".html").downcase == "default"
+          page.puts "---"
+          page.puts File.read(settings_file) if File.exist?(settings_file)
+          page.puts "---"
+        else
+          page.puts "---"
+          page.puts "layout: default"
+          page.puts "---"
+        end 
+        page.puts "{% include JB/setup %}"
+        page.puts "{% include themes/#{theme_name}/#{File.basename(filename)} %}" 
+      end
+    end
+    
+    puts "=> Theme successfully switched!"
+    puts "=> Reload your web-page to check it out =)"
+  end # task :switch
+  
+  # Public: Install a theme using the theme packager.
+  # Version 0.1.0 simple 1:1 file matching.
+  #
+  # git  - String, Optional path to the git repository of the theme to be installed.
+  # name - String, Optional name of the theme you want to install.
+  #        Passing name requires that the theme package already exist.
+  #
+  # Examples
+  #
+  #   rake theme:install git="https://github.com/jekyllbootstrap/theme-twitter.git"
+  #   rake theme:install name="cool-theme"
+  #
+  # Returns Success/failure messages.
+  desc "Install theme"
+  task :install do
+    if ENV["git"]
+      manifest = theme_from_git_url(ENV["git"])
+      name = manifest["name"]
+    else
+      name = ENV["name"].to_s.downcase
+    end
+
+    packaged_theme_path = JB::Path.build(:theme_packages, :node => name)
+    
+    abort("rake aborted!
+      => ERROR: 'name' cannot be blank") if name.empty?
+    abort("rake aborted! 
+      => ERROR: '#{packaged_theme_path}' directory not found.
+      => Installable themes can be added via git. You can find some here: http://github.com/jekyllbootstrap
+      => To download+install run: `rake theme:install git='[PUBLIC-CLONE-URL]'`
+      => example : rake theme:install git='git@github.com:jekyllbootstrap/theme-the-program.git'
+    ") unless FileTest.directory?(packaged_theme_path)
+    
+    manifest = verify_manifest(packaged_theme_path)
+    
+    # Get relative paths to packaged theme files
+    # Exclude directories as they'll be recursively created. Exclude meta-data files.
+    packaged_theme_files = []
+    FileUtils.cd(packaged_theme_path) {
+      Dir.glob("**/*.*") { |f| 
+        next if ( FileTest.directory?(f) || f =~ /^(manifest|readme|packager)/i )
+        packaged_theme_files << f 
+      }
+    }
+    
+    # Mirror each file into the framework making sure to prompt if already exists.
+    packaged_theme_files.each do |filename|
+      file_install_path = File.join(JB::Path.base, filename)
+      if File.exist? file_install_path and ask("#{file_install_path} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
+        next
+      else
+        mkdir_p File.dirname(file_install_path)
+        cp_r File.join(packaged_theme_path, filename), file_install_path
+      end
+    end
+    
+    puts "=> #{name} theme has been installed!"
+    puts "=> ---"
+    if ask("=> Want to switch themes now?", ['y', 'n']) == 'y'
+      system("rake switch_theme name='#{name}'")
+    end
+  end
+
+  # Public: Package a theme using the theme packager.
+  # The theme must be structured using valid JB API.
+  # In other words packaging is essentially the reverse of installing.
+  #
+  # name - String, Required name of the theme you want to package.
+  #        
+  # Examples
+  #
+  #   rake theme:package name="twitter"
+  #
+  # Returns Success/failure messages.
+  desc "Package theme"
+  task :package do
+    name = ENV["name"].to_s.downcase
+    theme_path = JB::Path.build(:themes, :node => name)
+    asset_path = JB::Path.build(:theme_assets, :node => name)
+
+    abort("rake aborted: name cannot be blank") if name.empty?
+    abort("rake aborted: '#{theme_path}' directory not found.") unless FileTest.directory?(theme_path)
+    abort("rake aborted: '#{asset_path}' directory not found.") unless FileTest.directory?(asset_path)
+    
+    ## Mirror theme's template directory (_includes)
+    packaged_theme_path = JB::Path.build(:themes, :root => JB::Path.build(:theme_packages, :node => name))
+    mkdir_p packaged_theme_path
+    cp_r theme_path, packaged_theme_path
+    
+    ## Mirror theme's asset directory
+    packaged_theme_assets_path = JB::Path.build(:theme_assets, :root => JB::Path.build(:theme_packages, :node => name))
+    mkdir_p packaged_theme_assets_path
+    cp_r asset_path, packaged_theme_assets_path
+
+    ## Log packager version
+    packager = {"packager" => {"version" => CONFIG["theme_package_version"].to_s } }
+    open(JB::Path.build(:theme_packages, :node => "#{name}/packager.yml"), "w") do |page|
+      page.puts packager.to_yaml
+    end
+    
+    puts "=> '#{name}' theme is packaged and available at: #{JB::Path.build(:theme_packages, :node => name)}"
+  end
+  
+end # end namespace :theme
+
+# Internal: Download and process a theme from a git url.
+# Notice we don't know the name of the theme until we look it up in the manifest.
+# So we'll have to change the folder name once we get the name.
+#
+# url - String, Required url to git repository.
+#        
+# Returns theme manifest hash
+def theme_from_git_url(url)
+  tmp_path = JB::Path.build(:theme_packages, :node => "_tmp")
+  abort("rake aborted: system call to git clone failed") if !system("git clone #{url} #{tmp_path}")
+  manifest = verify_manifest(tmp_path)
+  new_path = JB::Path.build(:theme_packages, :node => manifest["name"])
+  if File.exist?(new_path) && ask("=> #{new_path} theme package already exists. Override?", ['y', 'n']) == 'n'
+    remove_dir(tmp_path)
+    abort("rake aborted: '#{manifest["name"]}' already exists as theme package.")
+  end
+
+  remove_dir(new_path) if File.exist?(new_path)
+  mv(tmp_path, new_path)
+  manifest
+end
+
+# Internal: Process theme package manifest file.
+#
+# theme_path - String, Required. File path to theme package.
+#        
+# Returns theme manifest hash
+def verify_manifest(theme_path)
+  manifest_path = File.join(theme_path, "manifest.yml")
+  manifest_file = File.open( manifest_path )
+  abort("rake aborted: repo must contain valid manifest.yml") unless File.exist? manifest_file
+  manifest = YAML.load( manifest_file )
+  manifest_file.close
+  manifest
+end
+
+def ask(message, valid_options)
+  if valid_options
+    answer = get_stdin("#{message} #{valid_options.to_s.gsub(/"/, '').gsub(/, /,'/')} ") while !valid_options.include?(answer)
+  else
+    answer = get_stdin(message)
+  end
+  answer
+end
+
+def get_stdin(message)
+  print message
+  STDIN.gets.chomp
+end
+
+#Load custom rake scripts
+Dir['_rake/*.rake'].each { |r| load r }

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_config-prod.yml
----------------------------------------------------------------------
diff --git a/_config-prod.yml b/_config-prod.yml
new file mode 100644
index 0000000..e497b30
--- /dev/null
+++ b/_config-prod.yml
@@ -0,0 +1,5 @@
+# singa.incubator.apache.org
+#
+
+JB:
+  BASE_PATH: ""

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_config.yml
----------------------------------------------------------------------
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..32634db
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,130 @@
+# This is the default format.
+# For more see: http://jekyllrb.com/docs/permalinks/
+permalink: /:categories/:title
+
+exclude: [".rvmrc", ".rbenv-version", "README.md", "Rakefile", "changelog.md"]
+highlighter: pygments
+
+# Themes are encouraged to use these universal variables
+# so be sure to set them if your theme uses them.
+#
+time: 2015-05-06
+title : Apache SINGA
+author :
+  email : dev@singa.incubator.apache.org
+  #name : SINGA
+  #github:
+
+# The production_url is only used when full-domain names are needed
+# such as sitemap.txt
+# Most places will/should use BASE_PATH to make the urls
+#
+# If you have set a CNAME (pages.github.com) set your custom domain here.
+# Else if you are pushing to username.github.io, replace with your username.
+# Finally if you are pushing to a GitHub project page, include the project name at the end.
+##http://nusinga.github.io
+#production_url :
+
+# All Jekyll-Bootstrap specific configurations are namespaced into this hash
+#
+safe : true
+JB :
+  version : 0.3.0
+
+  # All links will be namespaced by BASE_PATH if defined.
+  # Links in your website should always be prefixed with {{BASE_PATH}}
+  # however this value will be dynamically changed depending on your deployment situation.
+  #
+  # CNAME (http://yourcustomdomain.com)
+  #   DO NOT SET BASE_PATH
+  #   (urls will be prefixed with "/" and work relatively)
+  #
+  # GitHub Pages (http://username.github.io)
+  #   DO NOT SET BASE_PATH
+  #   (urls will be prefixed with "/" and work relatively)
+  #
+  # GitHub Project Pages (http://username.github.io/project-name)
+  #
+  #   A GitHub Project site exists in the `gh-pages` branch of one of your repositories.
+  #  REQUIRED! Set BASE_PATH to: http://username.github.io/project-name
+  #
+  # CAUTION:
+  #   - When in Localhost, your site will run from root "/" regardless of BASE_PATH
+  #   - Only the following values are falsy: ["", null, false]
+  #   - When setting BASE_PATH it must be a valid url.
+  #     This means always setting the protocol (http|https) or prefixing with "/"
+  #
+  BASE_PATH :  "/singa" #http://www.comp.nus.edu.sg/~wangwei
+
+  # By default, the asset_path is automatically defined relative to BASE_PATH plus the enabled theme.
+  # ex: [BASE_PATH]/assets/themes/[THEME-NAME]
+  #
+  # Override this by defining an absolute path to assets here.
+  # ex:
+  #   http://s3.amazonaws.com/yoursite/themes/watermelon
+  #   /assets
+  #
+  #ASSET_PATH :
+
+  # These paths are to the main pages Jekyll-Bootstrap ships with.
+  # Some JB helpers refer to these paths; change them here if needed.
+  #
+  archive_path: /archive.html
+  categories_path : /categories.html
+  tags_path : /tags.html
+  atom_path : /atom.xml
+  rss_path : /rss.xml
+
+  # Settings for comments helper
+  # Set 'provider' to the comment provider you want to use.
+  # Set 'provider' to false to turn commenting off globally.
+  #
+  comments :
+    provider : disqus
+    disqus :
+      short_name : nusinga
+    livefyre :
+      site_id : 123
+    intensedebate :
+      account : 123abc
+    facebook :
+      appid : 123
+      num_posts: 5
+      width: 580
+      colorscheme: light
+
+  # Settings for analytics helper
+  # Set 'provider' to the analytics provider you want to use.
+  # Set 'provider' to false to turn analytics off globally.
+  #
+  analytics :
+    provider : google
+    google :
+      tracking_id : 'UA-58709187-1'
+    getclicky :
+      site_id :
+    mixpanel :
+        token : '_MIXPANEL_TOKEN_'
+    piwik :
+        baseURL : 'myserver.tld/piwik' # Piwik installation address (without protocol)
+        idsite : '1'                   # the id of the site on Piwik
+
+  # Settings for sharing helper.
+  # Sharing is for things like tweet, plusone, like, reddit buttons etc.
+  # Set 'provider' to the sharing provider you want to use.
+  # Set 'provider' to false to turn sharing off globally.
+  #
+  sharing :
+    provider : false
+
+  # Settings for all other include helpers can be defined by creating
+  # a hash with key named for the given helper. ex:
+  #
+  #   pages_list :
+  #     provider : "custom"
+  #
+  # Setting any helper's provider to 'custom' will bypass the helper code
+  # and include your custom code. Your custom file must be defined at:
+  #   ./_includes/custom/[HELPER]
+  # where [HELPER] is the name of the helper you are overriding.
+

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_drafts/jekyll-introduction-draft.md
----------------------------------------------------------------------
diff --git a/_drafts/jekyll-introduction-draft.md b/_drafts/jekyll-introduction-draft.md
new file mode 100644
index 0000000..88b93f0
--- /dev/null
+++ b/_drafts/jekyll-introduction-draft.md
@@ -0,0 +1,10 @@
+---
+layout: post
+category : lessons
+tagline: "Supporting tagline"
+tags : [intro, beginner, jekyll, tutorial]
+---
+{% include JB/setup %}
+
+
+This is an example of a draft. Read more here: [http://jekyllrb.com/docs/drafts/](http://jekyllrb.com/docs/drafts/)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/analytics
----------------------------------------------------------------------
diff --git a/_includes/JB/analytics b/_includes/JB/analytics
new file mode 100644
index 0000000..951a0e3
--- /dev/null
+++ b/_includes/JB/analytics
@@ -0,0 +1,16 @@
+{% if site.safe and site.JB.analytics.provider and page.JB.analytics != false %}
+
+{% case site.JB.analytics.provider %}
+{% when "google" %}
+  {% include JB/analytics-providers/google %}
+{% when "getclicky" %}
+  {% include JB/analytics-providers/getclicky %}
+{% when "mixpanel" %}
+  {% include JB/analytics-providers/mixpanel %}
+{% when "piwik" %}
+  {% include JB/analytics-providers/piwik %}
+{% when "custom" %}
+  {% include custom/analytics %}
+{% endcase %}
+
+{% endif %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/analytics-providers/getclicky
----------------------------------------------------------------------
diff --git a/_includes/JB/analytics-providers/getclicky b/_includes/JB/analytics-providers/getclicky
new file mode 100644
index 0000000..e9462f4
--- /dev/null
+++ b/_includes/JB/analytics-providers/getclicky
@@ -0,0 +1,12 @@
+<script type="text/javascript">
+var clicky_site_ids = clicky_site_ids || [];
+clicky_site_ids.push({{ site.JB.analytics.getclicky.site_id }});
+(function() {
+  var s = document.createElement('script');
+  s.type = 'text/javascript';
+  s.async = true;
+  s.src = '//static.getclicky.com/js';
+  ( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( s );
+})();
+</script>
+<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/{{ site.JB.analytics.getclicky.site_id }}ns.gif" /></p></noscript>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/analytics-providers/google
----------------------------------------------------------------------
diff --git a/_includes/JB/analytics-providers/google b/_includes/JB/analytics-providers/google
new file mode 100644
index 0000000..9014866
--- /dev/null
+++ b/_includes/JB/analytics-providers/google
@@ -0,0 +1,11 @@
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', '{{ site.JB.analytics.google.tracking_id }}']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/analytics-providers/mixpanel
----------------------------------------------------------------------
diff --git a/_includes/JB/analytics-providers/mixpanel b/_includes/JB/analytics-providers/mixpanel
new file mode 100644
index 0000000..4406eb0
--- /dev/null
+++ b/_includes/JB/analytics-providers/mixpanel
@@ -0,0 +1,11 @@
+<script type="text/javascript">
+    var mpq = [];
+    mpq.push(["init", "{{ site.JB.analytics.mixpanel.token}}"]);
+    (function(){var b,a,e,d,c;b=document.createElement("script");b.type="text/javascript";
+    b.async=true;b.src=(document.location.protocol==="https:"?"https:":"http:")+
+    "//api.mixpanel.com/site_media/js/api/mixpanel.js";a=document.getElementsByTagName("script")[0];
+    a.parentNode.insertBefore(b,a);e=function(f){return function(){mpq.push(
+    [f].concat(Array.prototype.slice.call(arguments,0)))}};d=["init","track","track_links",
+    "track_forms","register","register_once","identify","name_tag","set_config"];for(c=0;c<
+    d.length;c++){mpq[d[c]]=e(d[c])}})();
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/analytics-providers/piwik
----------------------------------------------------------------------
diff --git a/_includes/JB/analytics-providers/piwik b/_includes/JB/analytics-providers/piwik
new file mode 100755
index 0000000..077a373
--- /dev/null
+++ b/_includes/JB/analytics-providers/piwik
@@ -0,0 +1,10 @@
+<script type="text/javascript">
+  var pkBaseURL = (("https:" == document.location.protocol) ? "https://{{ site.JB.analytics.piwik.baseURL }}/" : "http://{{ site.JB.analytics.piwik.baseURL }}/");
+  document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
+</script><script type="text/javascript">
+  try {
+    var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", {{ site.JB.analytics.piwik.idsite }});
+    piwikTracker.trackPageView();
+    piwikTracker.enableLinkTracking();
+  } catch( err ) {}
+</script><noscript><p><img src="http://{{ site.JB.analytics.piwik.baseURL }}/piwik.php?idsite={{ site.JB.analytics.piwik.idsite }}" style="border:0" alt="" /></p></noscript>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/categories_list
----------------------------------------------------------------------
diff --git a/_includes/JB/categories_list b/_includes/JB/categories_list
new file mode 100644
index 0000000..83be2e2
--- /dev/null
+++ b/_includes/JB/categories_list
@@ -0,0 +1,37 @@
+{% comment %}<!--
+The categories_list include is a listing helper for categories.
+Usage:
+  1) assign the 'categories_list' variable to a valid array of tags.
+  2) include JB/categories_list
+  example:
+    <ul>
+  	  {% assign categories_list = site.categories %}  
+  	  {% include JB/categories_list %}
+  	</ul>
+  
+  Notes: 
+    Categories can be either a Hash of Category objects (hashes) or an Array of category-names (strings).
+    The encapsulating 'if' statement checks whether categories_list is a Hash or Array.
+    site.categories is a Hash while page.categories is an array.
+    
+  This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.categories_list.provider == "custom" %}
+  {% include custom/categories_list %}
+{% else %}
+  {% if categories_list.first[0] == null %}
+    {% for category in categories_list %} 
+    	<li><a href="{{ BASE_PATH }}{{ site.JB.categories_path }}#{{ category }}-ref">
+    		{{ category | join: "/" }} <span>{{ site.categories[category].size }}</span>
+    	</a></li>
+    {% endfor %}
+  {% else %}
+    {% for category in categories_list %} 
+    	<li><a href="{{ BASE_PATH }}{{ site.JB.categories_path }}#{{ category[0] }}-ref">
+    		{{ category[0] | join: "/" }} <span>{{ category[1].size }}</span>
+    	</a></li>
+    {% endfor %}
+  {% endif %}
+{% endif %}
+{% assign categories_list = nil %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/comments
----------------------------------------------------------------------
diff --git a/_includes/JB/comments b/_includes/JB/comments
new file mode 100644
index 0000000..4e9e600
--- /dev/null
+++ b/_includes/JB/comments
@@ -0,0 +1,16 @@
+{% if site.JB.comments.provider and page.comments != false %}
+
+{% case site.JB.comments.provider %}
+{% when "disqus" %}
+  {% include JB/comments-providers/disqus %}
+{% when "livefyre" %}
+  {% include JB/comments-providers/livefyre %}
+{% when "intensedebate" %}
+  {% include JB/comments-providers/intensedebate %}
+{% when "facebook" %}
+  {% include JB/comments-providers/facebook %}
+{% when "custom" %}
+  {% include custom/comments %}
+{% endcase %}
+
+{% endif %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/comments-providers/disqus
----------------------------------------------------------------------
diff --git a/_includes/JB/comments-providers/disqus b/_includes/JB/comments-providers/disqus
new file mode 100644
index 0000000..618a7b7
--- /dev/null
+++ b/_includes/JB/comments-providers/disqus
@@ -0,0 +1,14 @@
+<div id="disqus_thread"></div>
+<script type="text/javascript">
+    {% if site.safe == false %}var disqus_developer = 1;{% endif %}
+    var disqus_shortname = '{{ site.JB.comments.disqus.short_name }}'; // required: replace example with your forum shortname
+    {% if page.wordpress_id %}var disqus_identifier = '{{page.wordpress_id}} {{site.production_url}}/?p={{page.wordpress_id}}';{% endif %}
+    /* * * DON'T EDIT BELOW THIS LINE * * */
+    (function() {
+        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
+        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+    })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/comments-providers/facebook
----------------------------------------------------------------------
diff --git a/_includes/JB/comments-providers/facebook b/_includes/JB/comments-providers/facebook
new file mode 100644
index 0000000..6b3e5e0
--- /dev/null
+++ b/_includes/JB/comments-providers/facebook
@@ -0,0 +1,9 @@
+<div id="fb-root"></div>
+<script>(function(d, s, id) {
+  var js, fjs = d.getElementsByTagName(s)[0];
+  if (d.getElementById(id)) return;
+  js = d.createElement(s); js.id = id;
+  js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId={{ site.JB.comments.facebook.appid }}";
+  fjs.parentNode.insertBefore(js, fjs);
+}(document, 'script', 'facebook-jssdk'));</script>
+<div class="fb-comments" data-href="{{ site.production_url }}" data-num-posts="{{ site.JB.comments.facebook.num_posts }}" data-width="{{ site.JB.comments.facebook.width }}" data-colorscheme="{{ site.JB.comments.facebook.colorscheme }}"></div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/comments-providers/intensedebate
----------------------------------------------------------------------
diff --git a/_includes/JB/comments-providers/intensedebate b/_includes/JB/comments-providers/intensedebate
new file mode 100644
index 0000000..ab0c3c9
--- /dev/null
+++ b/_includes/JB/comments-providers/intensedebate
@@ -0,0 +1,6 @@
+<script>
+var idcomments_acct = '{{ site.JB.comments.intensedebate.account }}';
+var idcomments_post_id;
+var idcomments_post_url;
+</script>
+<script type="text/javascript" src="http://www.intensedebate.com/js/genericLinkWrapperV2.js"></script>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/comments-providers/livefyre
----------------------------------------------------------------------
diff --git a/_includes/JB/comments-providers/livefyre b/_includes/JB/comments-providers/livefyre
new file mode 100644
index 0000000..704b803
--- /dev/null
+++ b/_includes/JB/comments-providers/livefyre
@@ -0,0 +1,6 @@
+<script type='text/javascript' src='http://zor.livefyre.com/wjs/v1.0/javascripts/livefyre_init.js'></script>
+<script type='text/javascript'>
+    var fyre = LF({
+        site_id: {{ site.JB.comments.livefyre.site_id }}
+    });
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/liquid_raw
----------------------------------------------------------------------
diff --git a/_includes/JB/liquid_raw b/_includes/JB/liquid_raw
new file mode 100644
index 0000000..da2d359
--- /dev/null
+++ b/_includes/JB/liquid_raw
@@ -0,0 +1,32 @@
+{% comment%}<!--
+The liquid_raw helper is a way to display raw liquid code, as opposed to parsing it.
+Normally you'd use Liquid's built in 'raw' tag. 
+The problem is GitHub Jekyll does not support the current Liquid release.
+GitHub Jekyll supports the deprecated 'literal' tag.
+Using one will break the other if you plan to deploy to GitHub pages.
+  see: https://github.com/mojombo/jekyll/issues/425
+
+Since I don't want to mess with Liquid versions, I'll just rewrite the way I 
+intend to give liquid examples. It's not an elegant solution by any means:
+
+Usage: 
+  1) Define a 'text' variable with the block of liquid code you intend to display.
+  2) Pass the text variable to include JB/liquid_raw
+
+  example:
+  {% capture text %}|.% for tag in tags_list %.|
+    <li><a href="|.{ site.var.tags_path }.||.{ tag[0] }.|-ref">|.{ tag[0] }.| <span>|.{tag[1].size}.|</span></a></li>
+  |.% endfor %.|
+
+  |.% assign tags_list = null %.|{% endcapture %}    
+  {% include JB/liquid_raw %}
+  
+  As seen here, you must use "|." and ".|" as opening and closing brackets.
+-->{% endcomment%}
+
+{% if site.JB.liquid_raw.provider == "custom" %}
+  {% include custom/liquid_raw %}
+{% else %}
+  <pre><code>{{text | replace:"|.", "&#123;" | replace:".|", "&#125;" | replace:">", "&gt;" | replace:"<", "&lt;" }}</code></pre>
+{% endif %}
+{% assign text = nil %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/pages_list
----------------------------------------------------------------------
diff --git a/_includes/JB/pages_list b/_includes/JB/pages_list
new file mode 100644
index 0000000..05e0525
--- /dev/null
+++ b/_includes/JB/pages_list
@@ -0,0 +1,39 @@
+{% comment %}<!--
+The pages_list include is a listing helper.
+Usage:
+  1) assign the 'pages_list' variable to a valid array of pages or posts.
+  2) include JB/pages_list
+  example:
+    <ul>
+  	  {% assign pages_list = site.pages %}
+  	  {% include JB/pages_list %}
+  	</ul>
+
+  Grouping: (optional):
+  	assign the 'group' variable to constrain the list to only pages/posts
+  	in the given group. Note you must define the group manually in the page/post
+  	meta-data to use this feature.
+  	Grouping is mainly helpful for non-post pages.
+  	If you want to group posts, it's easier/better to tag them, then pass the tagged posts array.
+  	i.e. site.tags.cool_tag (this returns an array of posts tagged: cool_tag)
+
+  This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.pages_list.provider == "custom" %}
+  {% include custom/pages_list %}
+{% else %}
+  {% for node in pages_list %}
+    {% if node.title != null %}
+      {% if group == null or group == node.group %}
+      	{% if page.url == node.url %}
+      	<li class="active"><a href="{{ BASE_PATH }}{{node.url}}" class="active">{{node.title}}</a></li>
+      	{% else %}
+      	<li><a href="{{ BASE_PATH }}{{node.url}}">{{node.title}}</a></li>
+      	{% endif %}
+      {% endif %}
+    {% endif %}
+  {% endfor %}
+{% endif %}
+{% assign pages_list = nil %}
+{% assign group = nil %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/posts_collate
----------------------------------------------------------------------
diff --git a/_includes/JB/posts_collate b/_includes/JB/posts_collate
new file mode 100644
index 0000000..f612ade
--- /dev/null
+++ b/_includes/JB/posts_collate
@@ -0,0 +1,55 @@
+{% comment %}<!--
+Collate_posts helper. Collated posts by year and month.
+Usage:
+  1) assign the 'posts_collate' variable to a valid array of posts.
+  2) include JB/posts_collate
+  example:
+    {% assign posts_collate = site.posts %}
+    {% include JB/posts_collate %}
+
+  Ordering:
+    Posts are displayed in reverse chronological order.
+    For normal chronological order:
+      1) Change the for loop to this:
+        => 'for post in site.posts reversed'
+      2) Next make sure to change 'post.previous.date' to:
+        => 'post.next.date'
+        
+-->{% endcomment %}
+
+{% if site.JB.posts_collate.provider == "custom" %}
+  {% include custom/posts_collate %}
+{% else %}
+  {% for post in posts_collate  %}
+    {% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
+    {% capture this_month %}{{ post.date | date: "%B" }}{% endcapture %}
+    {% capture next_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
+    {% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %}
+  
+    {% if forloop.first %}
+      <h2>{{this_year}}</h2>
+      <h3>{{this_month}}</h3>
+      <ul>
+    {% endif %}
+  
+    <li><span>{{ post.date | date: "%B %e, %Y" }}</span> &raquo; <a href="{{ BASE_PATH }}{{ post.url }}">{{ post.title }}</a></li>
+  
+    {% if forloop.last %}
+      </ul>
+    {% else %}
+      {% if this_year != next_year %}
+        </ul>
+        <h2>{{next_year}}</h2>
+        <h3>{{next_month}}</h3>
+        <ul>
+      {% else %}    
+        {% if this_month != next_month %}
+          </ul>
+          <h3>{{next_month}}</h3>
+          <ul>
+        {% endif %}
+      {% endif %}
+    {% endif %}
+  {% endfor %}
+{% endif %}
+{% assign posts_collate = nil %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/setup
----------------------------------------------------------------------
diff --git a/_includes/JB/setup b/_includes/JB/setup
new file mode 100644
index 0000000..efcd84b
--- /dev/null
+++ b/_includes/JB/setup
@@ -0,0 +1,22 @@
+{% capture jbcache %}
+  <!--
+  - Dynamically set liquid variables for working with URLs/paths
+  -->
+  {% if site.JB.setup.provider == "custom" %}
+    {% include custom/setup %}
+  {% else %}
+    {% if site.safe and site.JB.BASE_PATH and site.JB.BASE_PATH != '' %}
+      {% assign BASE_PATH = site.JB.BASE_PATH %}
+      {% assign HOME_PATH = site.JB.BASE_PATH %}
+    {% else %}
+      {% assign BASE_PATH = nil %}
+      {% assign HOME_PATH = "/" %}
+    {% endif %}
+
+    {% if site.JB.ASSET_PATH %}
+      {% assign ASSET_PATH = site.JB.ASSET_PATH %}
+    {% else %}
+      {% capture ASSET_PATH %}{{ BASE_PATH }}/assets/themes/{{ page.theme.name }}{% endcapture %}
+    {% endif %}  
+  {% endif %}
+{% endcapture %}{% assign jbcache = nil %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/sharing
----------------------------------------------------------------------
diff --git a/_includes/JB/sharing b/_includes/JB/sharing
new file mode 100644
index 0000000..f5b1151
--- /dev/null
+++ b/_includes/JB/sharing
@@ -0,0 +1,8 @@
+{% if site.safe and site.JB.sharing.provider and page.JB.sharing != false %}
+
+{% case site.JB.sharing.provider %}
+{% when "custom" %}
+  {% include custom/sharing %}
+{% endcase %}
+
+{% endif %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/JB/tags_list
----------------------------------------------------------------------
diff --git a/_includes/JB/tags_list b/_includes/JB/tags_list
new file mode 100644
index 0000000..8eb62a7
--- /dev/null
+++ b/_includes/JB/tags_list
@@ -0,0 +1,33 @@
+{% comment %}<!--
+The tags_list include is a listing helper for tags.
+Usage:
+  1) assign the 'tags_list' variable to a valid array of tags.
+  2) include JB/tags_list
+  example:
+    <ul>
+  	  {% assign tags_list = site.tags %}  
+  	  {% include JB/tags_list %}
+  	</ul>
+  
+  Notes: 
+    Tags can be either a Hash of tag objects (hashes) or an Array of tag-names (strings).
+    The encapsulating 'if' statement checks whether tags_list is a Hash or Array.
+    site.tags is a Hash while page.tags is an array.
+    
+  This helper can be seen in use at: ../_layouts/default.html
+-->{% endcomment %}
+
+{% if site.JB.tags_list.provider == "custom" %}
+  {% include custom/tags_list %}
+{% else %}
+  {% if tags_list.first[0] == null %}
+    {% for tag in tags_list %} 
+    	<li><a href="{{ BASE_PATH }}{{ site.JB.tags_path }}#{{ tag }}-ref">{{ tag }} <span>{{ site.tags[tag].size }}</span></a></li>
+    {% endfor %}
+  {% else %}
+    {% for tag in tags_list %} 
+    	<li><a href="{{ BASE_PATH }}{{ site.JB.tags_path }}#{{ tag[0] }}-ref">{{ tag[0] }} <span>{{ tag[1].size }}</span></a></li>
+    {% endfor %}
+  {% endif %}
+{% endif %}
+{% assign tags_list = nil %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/bootstrap-3/default.html
----------------------------------------------------------------------
diff --git a/_includes/themes/bootstrap-3/default.html b/_includes/themes/bootstrap-3/default.html
new file mode 100644
index 0000000..bc5b220
--- /dev/null
+++ b/_includes/themes/bootstrap-3/default.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+
+    <title>{{ page.title }}</title>
+    {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
+    <meta name="author" content="{{ site.author.name }}">
+
+    <!-- Enable responsive viewport -->
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    <!-- Bootstrap styles -->
+    <link href="{{ ASSET_PATH }}/bootstrap/css/bootstrap.min.css" rel="stylesheet">
+    <!-- Optional theme -->
+    <link href="{{ ASSET_PATH }}/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet">
+    <!-- Sticky Footer -->
+    <link href="{{ ASSET_PATH }}/bootstrap/css/bs-sticky-footer.css" rel="stylesheet">
+    
+    <!-- Custom styles -->
+    <link href="{{ ASSET_PATH }}/css/style.css?body=1" rel="stylesheet" type="text/css" media="all">
+
+    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
+    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
+    <!--[if lt IE 9]>
+      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
+      <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
+    <![endif]-->
+
+    <!-- Fav and touch icons -->
+    <!-- Update these with your own images
+      <link rel="shortcut icon" href="images/favicon.ico">
+      <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
+      <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
+      <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
+    -->
+
+    <!-- atom & rss feed -->
+    <link href="{{ BASE_PATH }}{{ site.JB.atom_path }}" type="application/atom+xml" rel="alternate" title="Sitewide ATOM Feed">
+    <link href="{{ BASE_PATH }}{{ site.JB.rss_path }}" type="application/rss+xml" rel="alternate" title="Sitewide RSS Feed">
+
+  </head>
+
+  <body>
+    <div id="wrap">
+      <nav class="navbar navbar-default" role="navigation">
+        <!-- Brand and toggle get grouped for better mobile display -->
+        <div class="navbar-header">
+          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#jb-navbar-collapse">
+            <span class="sr-only">Toggle navigation</span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+            <span class="icon-bar"></span>
+          </button>
+          <a class="navbar-brand" href="{{ HOME_PATH }}">{{ site.title }}</a>
+        </div>
+
+        <!-- Collect the nav links, forms, and other content for toggling -->
+        <div class="collapse navbar-collapse" id="jb-navbar-collapse">
+          <ul class="nav navbar-nav">
+            {% assign pages_list = site.pages %}
+            {% assign group = 'navigation' %}
+            {% include JB/pages_list %}
+          </ul>
+          <form class="navbar-form navbar-right" role="search">
+            <div class="form-group">
+              <input type="text" class="form-control" placeholder="Search">
+            </div>
+            <button type="submit" class="btn btn-default">Submit</button>
+          </form>
+        </div><!-- /.navbar-collapse -->
+      </nav>
+
+      <div class="container">
+        {{ content }}
+      </div>
+
+    </div>
+
+    <div id="footer">
+      <div class="container">
+        <p>&copy; {{ site.time | date: '%Y' }} {{ site.author.name }}
+          with help from <a href="http://jekyllbootstrap.com" target="_blank" title="The Definitive Jekyll Blogging Framework">Jekyll Bootstrap</a>
+          and <a href="http://twitter.github.com/bootstrap/" target="_blank">Twitter Bootstrap</a>
+        </p>
+      </div>
+    </div>
+
+    {% include JB/analytics %}
+
+
+    <!-- Latest compiled and minified JavaScript, requires jQuery 1.x (2.x not supported in IE8) -->
+    <!-- Placed at the end of the document so the pages load faster -->
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+    <script src="{{ ASSET_PATH }}/bootstrap/js/bootstrap.min.js"></script>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/bootstrap-3/page.html
----------------------------------------------------------------------
diff --git a/_includes/themes/bootstrap-3/page.html b/_includes/themes/bootstrap-3/page.html
new file mode 100644
index 0000000..e981ad9
--- /dev/null
+++ b/_includes/themes/bootstrap-3/page.html
@@ -0,0 +1,9 @@
+<div class="page-header">
+  <h1>{{ page.title }} {% if page.tagline %} <small>{{ page.tagline }}</small>{% endif %}</h1>
+</div>
+
+<div class="row">
+  <div class="col-xs-12">
+    {{ content }}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/bootstrap-3/post.html
----------------------------------------------------------------------
diff --git a/_includes/themes/bootstrap-3/post.html b/_includes/themes/bootstrap-3/post.html
new file mode 100644
index 0000000..85cc0f4
--- /dev/null
+++ b/_includes/themes/bootstrap-3/post.html
@@ -0,0 +1,47 @@
+<div class="page-header">
+  <h1>{{ page.title }} {% if page.tagline %}<small>{{page.tagline}}</small>{% endif %}</h1>
+</div>
+
+<div class="row post-full">
+  <div class="col-xs-12">
+    <div class="date">
+      <span>{{ page.date | date_to_long_string }}</span>
+    </div>
+    <div class="content">
+      {{ content }}
+    </div>
+
+  {% unless page.categories == empty %}
+    <ul class="tag_box inline">
+      <li><i class="glyphicon glyphicon-open"></i></li>
+      {% assign categories_list = page.categories %}
+      {% include JB/categories_list %}
+    </ul>
+  {% endunless %}  
+
+  {% unless page.tags == empty %}
+    <ul class="tag_box inline">
+      <li><i class="glyphicon glyphicon-tags"></i></li>
+      {% assign tags_list = page.tags %}
+      {% include JB/tags_list %}
+    </ul>
+  {% endunless %}  
+  
+    <hr>
+    <ul class="pagination">
+    {% if page.previous %}
+      <li class="prev"><a href="{{ BASE_PATH }}{{ page.previous.url }}" title="{{ page.previous.title }}">&laquo; Previous</a></li>
+    {% else %}
+      <li class="prev disabled"><a>&larr; Previous</a></li>
+    {% endif %}
+      <li><a href="{{ BASE_PATH }}{{ site.JB.archive_path }}">Archive</a></li>
+    {% if page.next %}
+      <li class="next"><a href="{{ BASE_PATH }}{{ page.next.url }}" title="{{ page.next.title }}">Next &raquo;</a></li>
+    {% else %}
+      <li class="next disabled"><a>Next &rarr;</a>
+    {% endif %}
+    </ul>
+    <hr>
+    {% include JB/comments %}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/bootstrap-3/settings.yml
----------------------------------------------------------------------
diff --git a/_includes/themes/bootstrap-3/settings.yml b/_includes/themes/bootstrap-3/settings.yml
new file mode 100644
index 0000000..379bfbc
--- /dev/null
+++ b/_includes/themes/bootstrap-3/settings.yml
@@ -0,0 +1,2 @@
+theme :
+  name : bootstrap-3
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/twitter/default.html
----------------------------------------------------------------------
diff --git a/_includes/themes/twitter/default.html b/_includes/themes/twitter/default.html
new file mode 100644
index 0000000..6074ac0
--- /dev/null
+++ b/_includes/themes/twitter/default.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>{{ page.title }}</title>
+    {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
+    <meta name="author" content="{{ site.author.name }}">
+
+    <!-- Enable responsive viewport -->
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
+    <!--[if lt IE 9]>
+      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+    <![endif]-->
+
+    <!-- Le styles -->
+    <link href="{{ ASSET_PATH }}/bootstrap/css/bootstrap.2.2.2.min.css" rel="stylesheet">
+    <link href="{{ ASSET_PATH }}/css/style.css?body=1" rel="stylesheet" type="text/css" media="all">
+    <link rel="shortcut icon" type="image/x-icon" href="{{ ASSET_PATH }}/css/favicon.ico">
+
+    <!-- Le fav and touch icons -->
+  <!-- Update these with your own images
+    <link rel="shortcut icon" href="images/favicon.ico">
+    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
+  -->
+
+    <!-- atom & rss feed -->
+    <link href="{{ BASE_PATH }}{{ site.JB.atom_path }}" type="application/atom+xml" rel="alternate" title="Sitewide ATOM Feed">
+    <link href="{{ BASE_PATH }}{{ site.JB.rss_path }}" type="application/rss+xml" rel="alternate" title="Sitewide RSS Feed">
+
+    <!-- toc -->
+    <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+    <script src="{{ ASSET_PATH }}/js/toc.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function() {
+        $('#toc').toc();
+        });
+    </script>
+    <style >
+        .clickable-header {
+            cursor:pointer;
+        }
+        .clickable-header:hover {
+            text-decoration:underline;
+        }
+        .top-level-header {
+            display:inline;
+        }
+        .back-to-top {
+            margin-left:5px;
+              cursor:pointer;
+        }
+        #backtotop {
+          position: fixed;
+          left: 50%;
+          bottom: 100px;
+          margin-left:520px;
+          width: 30px;
+          height: 30px;
+        }
+        #toc, .toc, .mw-warning {
+          background-color: #FFF;
+          border-left: 1px solid #AAAAAA;
+          font-size: 95%;
+          padding-top: 45px;
+          position: fixed;
+          top: 0px;
+          left: 50%;
+          margin-left: 520px;
+        }
+        #toc strong{
+          margin:20px;
+        }
+    </style>
+
+  </head>
+
+  <body>
+  <a href="https://github.com/apache/incubator-singa"><img style="position: absolute; top: 0;
+    left: 0; border: 0;"
+    src="https://camo.githubusercontent.com/8b6b8ccc6da3aa5722903da7b58eb5ab1081adee/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6f72616e67655f6666373630302e706e67"
+    alt="Fork me on GitHub"
+    data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_orange_ff7600.png"></a>
+
+  <div id="topanchor"></div>
+    <div class="navbar">
+      <div class="navbar-inner">
+        <div class="container-narrow">
+          <a class="brand" href="{{ HOME_PATH }}">{{ site.title }}</a>
+          <ul class="nav">
+            {% assign pages_list = site.pages %}
+            {% assign group = 'navigation' %}
+            {% include JB/pages_list %}
+          </ul>
+        </div>
+      </div>
+    </div>
+    <div class="container-narrow">
+      <div class="content">
+        {{ content }}
+      </div>
+      <hr>
+      <footer>
+        <p>Copyright &copy; {{ site.time | date: '%Y' }} {{ site.author.name }}
+        The Apache Software Foundation. All rights reserved.
+
+        Apache Singa, Apache, the Apache feather logo, and the Apache Singa
+        project logos are trademarks of The Apache Software Foundation. All
+        other marks mentioned may be trademarks or registered trademarks of
+        their respective owners.
+        <a href="./privacy.html"> Privacy Policy </a>.
+        </p>
+      </footer>
+
+    </div>
+
+    <!-- back to top
+    <div id="backtotop">
+      <a href="#topanchor"><i class="icon-arrow-up back-to-top"></i>Top</a>
+    </div>-->
+
+    {% include JB/analytics %}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/twitter/frontpage.html
----------------------------------------------------------------------
diff --git a/_includes/themes/twitter/frontpage.html b/_includes/themes/twitter/frontpage.html
new file mode 100644
index 0000000..1030c27
--- /dev/null
+++ b/_includes/themes/twitter/frontpage.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>{{ page.title }}</title>
+    {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
+    <meta name="author" content="{{ site.author.name }}">
+
+    <!-- Enable responsive viewport -->
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
+    <!--[if lt IE 9]>
+      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
+    <![endif]-->
+
+    <!-- Le styles -->
+    <link href="{{ ASSET_PATH }}/bootstrap/css/bootstrap.2.2.2.min.css" rel="stylesheet">
+    <link href="{{ ASSET_PATH }}/css/style.css?body=1" rel="stylesheet" type="text/css" media="all">
+    <link rel="shortcut icon" type="image/x-icon" href="{{ ASSET_PATH }}/css/favicon.ico">
+
+    <!-- Le fav and touch icons -->
+  <!-- Update these with your own images
+    <link rel="shortcut icon" href="images/favicon.ico">
+    <link rel="apple-touch-icon" href="images/apple-touch-icon.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
+  -->
+
+    <!-- atom & rss feed -->
+    <link href="{{ BASE_PATH }}{{ site.JB.atom_path }}" type="application/atom+xml" rel="alternate" title="Sitewide ATOM Feed">
+    <link href="{{ BASE_PATH }}{{ site.JB.rss_path }}" type="application/rss+xml" rel="alternate" title="Sitewide RSS Feed">
+
+    <!-- toc -->
+    <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+    <script src="{{ ASSET_PATH }}/js/toc.js"></script>
+    <script type="text/javascript">
+        $(document).ready(function() {
+        $('#toc').toc();
+        });
+    </script>
+    <style >
+        .clickable-header {
+            cursor:pointer;
+        }
+        .clickable-header:hover {
+            text-decoration:underline;
+        }
+        .top-level-header {
+            display:inline;
+        }
+        .back-to-top {
+            margin-left:5px;
+              cursor:pointer;
+        }
+        #backtotop {
+          position: fixed;
+          left: 50%;
+          bottom: 100px;
+          margin-left:520px;
+          width: 30px;
+          height: 30px;
+        }
+        #toc, .toc, .mw-warning {
+          background-color: #FFF;
+          border-left: 1px solid #AAAAAA;
+          font-size: 95%;
+          padding-top: 45px;
+          position: fixed;
+          top: 0px;
+          left: 50%;
+          margin-left: 520px;
+        }
+        #toc strong{
+          margin:20px;
+        }
+    </style>
+
+  </head>
+
+  <body>
+  <div id="topanchor"></div>
+    <div class="navbar">
+      <div class="navbar-inner">
+        <div class="container-narrow">
+          <a class="brand" href="{{ HOME_PATH }}">{{ site.title }}</a>
+          <ul class="nav">
+            {% assign pages_list = site.pages %}
+            {% assign group = 'navigation' %}
+            {% include JB/pages_list %}
+          </ul>
+        </div>
+      </div>
+    </div>
+    <div id="banner">
+  <a href="https://github.com/apache/incubator-singa" style="float: left"><img style="position: relative; top: -9px;
+    left: 0; border: 0;"
+    src="https://camo.githubusercontent.com/8b6b8ccc6da3aa5722903da7b58eb5ab1081adee/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6f72616e67655f6666373630302e706e67"
+    alt="Fork me on GitHub"
+    data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_orange_ff7600.png"></a>
+
+      <div id="logos">
+        <img class="singa-logo" src="{{ BASE_PATH }}/assets/image/singa-logo.png"/>
+        <div>
+          <img class="incubator-logo" src="{{ BASE_PATH }}/assets/image/incubator.png"/>
+          <span> A General Distributed Deep Learning Platform</span>
+      </div>
+      </div>
+    </div>
+    <div class="container-narrow">
+      <div class="content">
+        {{ content }}
+      </div>
+      <hr>
+      <footer>
+        <p>Copyright &copy; {{ site.time | date: '%Y' }} {{ site.author.name }}
+        The Apache Software Foundation. All rights reserved.
+
+        Apache Singa, Apache, the Apache feather logo, and the Apache Singa
+        project logos are trademarks of The Apache Software Foundation. All
+        other marks mentioned may be trademarks or registered trademarks of
+        their respective owners.
+        <a href="./privacy.html"> Privacy Policy </a>.
+        </p>
+      </footer>
+
+    </div>
+
+    <!-- back to top
+    <div id="backtotop">
+      <a href="#topanchor"><i class="icon-arrow-up back-to-top"></i>Top</a>
+    </div>-->
+
+    {% include JB/analytics %}
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/twitter/page.html
----------------------------------------------------------------------
diff --git a/_includes/themes/twitter/page.html b/_includes/themes/twitter/page.html
new file mode 100644
index 0000000..7c060ce
--- /dev/null
+++ b/_includes/themes/twitter/page.html
@@ -0,0 +1,11 @@
+<!--
+<div class="page-header">
+  <h1>{{ page.title }} {% if page.tagline %} <small>{{ page.tagline }}</small>{% endif %} </h1>
+</div>
+-->
+
+<div class="row-fluid">
+  <div class="span12">
+    {{ content }}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/twitter/post.html
----------------------------------------------------------------------
diff --git a/_includes/themes/twitter/post.html b/_includes/themes/twitter/post.html
new file mode 100644
index 0000000..b46dcf5
--- /dev/null
+++ b/_includes/themes/twitter/post.html
@@ -0,0 +1,52 @@
+<div class="page-header">
+  <h1>{{ page.title }} {% if page.tagline %}<small>{{page.tagline}}</small>{% endif %}<img src="{{ BASE_PATH }}/assets/image/singa_logo.jpg", style="width: 100px" align="right"/></h1>
+</div>
+
+<div id="toc" class="toc"></div>
+<div class="row-fluid post-full">
+  <div class="span12">
+    <!--
+    <div class="date">
+      <span>{{ page.date | date_to_long_string }}</span>
+    </div>
+    -->
+    <div class="content">
+      {{ content }}
+    </div>
+
+  {% unless page.categories == empty %}
+    <ul class="tag_box inline">
+      <li><i class="icon-folder-open"></i></li>
+      {% assign categories_list = page.categories %}
+      {% include JB/categories_list %}
+    </ul>
+  {% endunless %}
+
+  {% unless page.tags == empty %}
+    <ul class="tag_box inline">
+      <li><i class="icon-tags"></i></li>
+      {% assign tags_list = page.tags %}
+      {% include JB/tags_list %}
+    </ul>
+  {% endunless %}
+
+    <hr>
+    <div class="pagination">
+      <ul>
+      {% if page.previous %}
+        <li class="prev"><a href="{{ BASE_PATH }}{{ page.previous.url }}" title="{{ page.previous.title }}">&larr; Previous</a></li>
+      {% else %}
+        <li class="prev disabled"><a>&larr; Previous</a></li>
+      {% endif %}
+        <li><a href="{{ BASE_PATH }}{{ site.JB.archive_path }}">Archive</a></li>
+      {% if page.next %}
+        <li class="next"><a href="{{ BASE_PATH }}{{ page.next.url }}" title="{{ page.next.title }}">Next &rarr;</a></li>
+      {% else %}
+        <li class="next disabled"><a>Next &rarr;</a>
+      {% endif %}
+      </ul>
+    </div>
+    <hr>
+    {% include JB/comments %}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_includes/themes/twitter/settings.yml
----------------------------------------------------------------------
diff --git a/_includes/themes/twitter/settings.yml b/_includes/themes/twitter/settings.yml
new file mode 100644
index 0000000..7ca7b73
--- /dev/null
+++ b/_includes/themes/twitter/settings.yml
@@ -0,0 +1,2 @@
+theme :
+  name : twitter
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_layouts/default.html
----------------------------------------------------------------------
diff --git a/_layouts/default.html b/_layouts/default.html
new file mode 100644
index 0000000..2d9be07
--- /dev/null
+++ b/_layouts/default.html
@@ -0,0 +1,6 @@
+---
+theme :
+  name : twitter
+---
+{% include JB/setup %}
+{% include themes/twitter/default.html %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_layouts/frontpage.html
----------------------------------------------------------------------
diff --git a/_layouts/frontpage.html b/_layouts/frontpage.html
new file mode 100644
index 0000000..2226e50
--- /dev/null
+++ b/_layouts/frontpage.html
@@ -0,0 +1,6 @@
+---
+theme :
+  name : twitter
+---
+{% include JB/setup %}
+{% include themes/twitter/frontpage.html %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_layouts/page.html
----------------------------------------------------------------------
diff --git a/_layouts/page.html b/_layouts/page.html
new file mode 100644
index 0000000..6810b93
--- /dev/null
+++ b/_layouts/page.html
@@ -0,0 +1,5 @@
+---
+layout: frontpage
+---
+{% include JB/setup %}
+{% include themes/twitter/page.html %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_layouts/post.html
----------------------------------------------------------------------
diff --git a/_layouts/post.html b/_layouts/post.html
new file mode 100644
index 0000000..9971d7c
--- /dev/null
+++ b/_layouts/post.html
@@ -0,0 +1,5 @@
+---
+layout: default
+---
+{% include JB/setup %}
+{% include themes/twitter/post.html %}

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_plugins/debug.rb
----------------------------------------------------------------------
diff --git a/_plugins/debug.rb b/_plugins/debug.rb
new file mode 100644
index 0000000..e1dde39
--- /dev/null
+++ b/_plugins/debug.rb
@@ -0,0 +1,38 @@
+# A simple way to inspect liquid template variables.
+# Usage:
+#  Can be used anywhere liquid syntax is parsed (templates, includes, posts/pages)
+#  {{ site | debug }}
+#  {{ site.posts | debug }}
+#
+require 'pp'
+module Jekyll
+  # Need to overwrite the inspect method here because the original
+  # uses < > to encapsulate the psuedo post/page objects in which case
+  # the output is taken for HTML tags and hidden from view.
+  #
+  class Post
+    def inspect
+      "#Jekyll:Post @id=#{self.id.inspect}"
+    end
+  end
+  
+  class Page
+    def inspect
+      "#Jekyll:Page @name=#{self.name.inspect}"
+    end
+  end
+  
+end # Jekyll
+  
+module Jekyll
+  module DebugFilter
+    
+    def debug(obj, stdout=false)
+      puts obj.pretty_inspect if stdout
+      "<pre>#{obj.class}\n#{obj.pretty_inspect}</pre>"
+    end
+
+  end # DebugFilter
+end # Jekyll
+
+Liquid::Template.register_filter(Jekyll::DebugFilter)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_plugins/tocGenerator.rb
----------------------------------------------------------------------
diff --git a/_plugins/tocGenerator.rb b/_plugins/tocGenerator.rb
new file mode 100644
index 0000000..12929c6
--- /dev/null
+++ b/_plugins/tocGenerator.rb
@@ -0,0 +1,117 @@
+require 'nokogiri'
+
+module Jekyll
+  module TOCGenerator
+    TOGGLE_HTML = '<div id="toctitle"><h3>%1</h3>%2</div>'
+    TOC_CONTAINER_HTML = '<div id="toc-container"><table class="toc" id="toc"><tbody><tr><td>%1<ul>%2</ul></td></tr></tbody></table></div>'
+    HIDE_HTML = '<span class="toctoggle">[<a id="toctogglelink" class="internal" href="#">%1</a>]</span>'
+
+   def toc_generate(html)
+        # No Toc can be specified on every single page
+        # For example the index page has no table of contents
+        no_toc = @context.environments.first["page"]["noToc"] || false;
+
+        if no_toc
+            return html
+        end
+
+        config = @context.registers[:site].config
+        # Minimum number of items needed to show TOC, default 0 (0 means no minimum)
+        min_items_to_show_toc = config["minItemsToShowToc"] || 0
+
+        anchor_prefix = config["anchorPrefix"] || 'tocAnchor-'
+
+        # Text labels
+        contents_label = config["contentsLabel"] || 'Contents'
+        hide_label = config["hideLabel"] || 'hide'
+        show_label = config["showLabel"] || 'show'
+        show_toggle_button = config["showToggleButton"]
+
+        toc_html = ''
+        toc_level = 1
+        toc_section = 1
+        item_number = 1
+        level_html = ''
+
+        doc = Nokogiri::HTML(html)
+
+        # Find h2 tag and all its h3 siblings until next h2
+        doc.css('h2').each do |h2|
+            # TODO This XPATH expression can greatly improved
+            ct  = h2.xpath('count(following-sibling::h2)')
+            h3s = h2.xpath("following-sibling::h3[count(following-sibling::h2)=#{ct}]")
+
+            level_html = '';
+            inner_section = 0;
+
+            h3s.map.each do |h3|
+                inner_section += 1;
+                anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s + '-' + inner_section.to_s
+                h3['id'] = "#{anchor_id}"
+
+                level_html += create_level_html(anchor_id,
+                    toc_level + 1,
+                    toc_section + inner_section,
+                    item_number.to_s + '.' + inner_section.to_s,
+                    h3.text,
+                    '')
+            end
+            if level_html.length > 0
+                level_html = '<ul>' + level_html + '</ul>';
+            end
+            anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s;
+            h2['id'] = "#{anchor_id}"
+
+            toc_html += create_level_html(anchor_id,
+                toc_level,
+                toc_section,
+                item_number,
+                h2.text,
+                level_html);
+
+            toc_section += 1 + inner_section;
+            item_number += 1;
+        end
+
+        # for convenience item_number starts from 1
+        # so we decrement it to obtain the index count
+        toc_index_count = item_number - 1
+
+        if toc_html.length > 0
+            hide_html = '';
+            if (show_toggle_button)
+                hide_html = HIDE_HTML.gsub('%1', hide_label)
+            end
+
+            if min_items_to_show_toc <= toc_index_count
+                replaced_toggle_html = TOGGLE_HTML
+                    .gsub('%1', contents_label)
+                    .gsub('%2', hide_html);
+                toc_table = TOC_CONTAINER_HTML
+                    .gsub('%1', replaced_toggle_html)
+                    .gsub('%2', toc_html);
+                doc.css('body').children.before(toc_table)
+            end
+            doc.css('body').children.to_xhtml(indent:3, indent_text:" ")
+        else
+            return html
+        end
+   end
+
+private
+
+    def create_level_html(anchor_id, toc_level, toc_section, tocNumber, tocText, tocInner)
+        link = '<a href="#%1"><span class="tocnumber">%2</span> <span class="toctext">%3</span></a>%4'
+            .gsub('%1', anchor_id.to_s)
+            .gsub('%2', tocNumber.to_s)
+            .gsub('%3', tocText)
+            .gsub('%4', tocInner ? tocInner : '');
+        '<li class="toc_level-%1 toc_section-%2">%3</li>'
+            .gsub('%1', toc_level.to_s)
+            .gsub('%2', toc_section.to_s)
+            .gsub('%3', link)
+    end
+  end
+end
+
+Liquid::Template.register_filter(Jekyll::TOCGenerator)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_posts/community/2015-01-20-code-style.md
----------------------------------------------------------------------
diff --git a/_posts/community/2015-01-20-code-style.md b/_posts/community/2015-01-20-code-style.md
new file mode 100644
index 0000000..ff8b24b
--- /dev/null
+++ b/_posts/community/2015-01-20-code-style.md
@@ -0,0 +1,42 @@
+---
+layout: post
+title: Coding and Documentation Style
+category : community
+tagline:
+tags : [coding, contribution, style]
+---
+{% include JB/setup %}
+
+## Coding Styling
+We follow Google's C++ coding [style](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html)
+
+## Documentation Style
+
+### Comments
+
+We follow the [Doxygen](http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html)
+style to add comments for the code. There are at least three points we need to follow,
+
+1. **JAVADOC_AUTOREF** is enabled to write the comment block as,
+
+        /**
+         * brief description with a dot at the end.
+         * detailed description.
+         * @param
+         * @param
+         * @return
+         */
+
+2. One line comment should be like this (actually there are more choices. We use this one),
+
+        int num_procs; /**> total number of mpi processes */
+
+    the comments after double slashes `//` will not be generated to the html API pages but are allowed.
+
+3. Comments are apart from code should use macros like,
+
+        /**
+         * \file this file, solver.h, contains two classes \class Solver and \class Prefetcher
+         */
+
+### Tutorial and User Guide

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_posts/docs/2015-01-10-quick-start.md
----------------------------------------------------------------------
diff --git a/_posts/docs/2015-01-10-quick-start.md b/_posts/docs/2015-01-10-quick-start.md
new file mode 100644
index 0000000..bf953ba
--- /dev/null
+++ b/_posts/docs/2015-01-10-quick-start.md
@@ -0,0 +1,103 @@
+---
+layout: post
+title: Quick Start
+category : docs
+tags : [installation, examples]
+---
+{% include JB/setup %}
+
+
+## Installation
+
+Clone the SINGA code from [Github](https://github.com/apache/incubator-singa)
+or Apache's git repository
+
+    git clone git@github.com:apache/incubator-singa.git
+    or
+    git clone https://github.com/apache/incubator-singa.git
+
+
+Compile SINGA:
+
+    ./configure
+    make
+
+If there are dependent libraries missing, please refer to
+[installation]({{ BASE_PATH }}{% post_url /docs/2015-01-20-installation %}) page
+for guidance on installing them. After successful compilation, the libsinga.so
+and singa executable will be built into the build folder.
+
+## Run in standalone mode
+
+Running SINGA in standalone mode is on the contrary of running it on Mesos or
+YARN. For standalone mode, users have to manage the resources manually. For
+instance, they have to prepare a host file containing all running nodes.
+There is no management on CPU and memory resources, hence SINGA consumes as much
+CPU and memory resources as it needs.
+
+### Training on a single node
+
+For single node training, one process will be launched to run the SINGA code on
+the node where SINGA is started. We train the [CNN model](http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks) over the
+[CIFAR-10](http://www.cs.toronto.edu/~kriz/cifar.html) dataset as an example.
+The hyper-parameters are set following
+[cuda-convnet](https://code.google.com/p/cuda-convnet/).
+
+
+#### Data and model preparation
+
+Download the dataset and create the data shards for training and testing.
+
+    cd examples/cifar10/
+    make download
+    make shard
+
+A training dataset and a test dataset are created under *train-shard* and
+*test-shard* folder respectively. A mena.shard file is also generated, which
+contains the feature mean of all images.
+<!--After creating the data shards, you  to update the paths in the
+model configuration file (*model.conf*) for the
+training data shard, test data shard and the mean file.-->
+
+Since all modules used for training this CNN model are provided by SINGA as
+built-in modules, there is no need to write any code. Instead, you just run the
+executable file (*../../build/singa*) by providing the model configuration file
+(*model.conf*).  If you want to implement your own modules, e.g., layer,
+then you have to register your modules in the driver code. After compiling the
+driver code, link it with the SINGA library to generate the executable. More
+details are described in [Code your own models]().
+
+#### Training without partitioning
+
+To train the model without any partitioning, you just set the numbers
+in the cluster configuration file (*cluster.conf*) as :
+
+    nworker_groups: 1
+    nworkers_per_group: 1
+    nserver_groups: 1
+    nservers_per_group: 1
+
+One worker group trains against one partition of the training dataset. If
+*nworker_groups* is set to 1, then there is no data partitioning. One worker
+runs over a partition of the model. If *nworkers_per_group* is set to 1, then
+there is no model partitioning. More details on the cluster configuration are
+described in the [System Architecture]() page.
+
+Start the training by running:
+
+    #goto top level folder
+    cd ..
+    ./build/singa -model=examples/cifar10/model.conf -cluster=examples/cifar10/cluster.conf
+
+#### Training with data Partitioning
+
+#### Training with model Partitioning
+
+### Training in a cluster
+
+
+## Run with Mesos
+
+*in working*...
+
+## Run with YARN

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_posts/docs/2015-01-20-installation.md
----------------------------------------------------------------------
diff --git a/_posts/docs/2015-01-20-installation.md b/_posts/docs/2015-01-20-installation.md
new file mode 100644
index 0000000..bdc1b28
--- /dev/null
+++ b/_posts/docs/2015-01-20-installation.md
@@ -0,0 +1,9 @@
+---
+layout: post
+title: Installation
+category : docs
+tags : [installation, examples]
+---
+{% include JB/setup %}
+
+

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/666a841d/_posts/docs/2015-01-30-architecture.md
----------------------------------------------------------------------
diff --git a/_posts/docs/2015-01-30-architecture.md b/_posts/docs/2015-01-30-architecture.md
new file mode 100644
index 0000000..f03c2b4
--- /dev/null
+++ b/_posts/docs/2015-01-30-architecture.md
@@ -0,0 +1,171 @@
+---
+layout: post
+title: System Architecture
+category : docs
+tagline:
+tags : [development, documentation, system architecture]
+---
+{% include JB/setup %}
+
+We design the architecture of Singa with the consideration to make it general
+to unify existing architectures. Then users can easily test the performance of
+different architectures and select the best for their models.
+
+## Logical Architecture
+
+<figure>
+<img src="{{ BASE_PATH }}/assets/image/arch/logical.png" align="center" width="550px"/>
+<figcaption><strong> Fig.1 - Logical system architecture</strong></figcaption>
+</figure>
+
+The logical system architecture is shown in Fig.1 with four worker groups and
+two server groups. Each worker group runs against a partition of the
+training dataset (called data parallelism) to compute the updates (e.g., the
+gradients) of parameters of one model replica.  Worker groups run
+asynchronously, while workers within one group run synchronously with each
+worker computing updates for a partition of the model parameters (called
+model parallelism). Each server group maintains one replica of the model
+parameters. It receives requests (e.g., Get/Put/Update) from workers and
+handles these requests. Server groups synchronize with neighboring server groups
+periodically or according to some rules. One worker (or server) group consists
+of multiple (user defined number) threads. These threads may resident in one
+process or span across multiple processes.
+
+Each worker (or server) group has a ParamShard object, which contains a full
+set of Param objects for a model replica. Since the workers (or servers) may
+span across multiple processes, this ParamShard may also be partitioned across
+multiple processes.  The ParamShards can share the same memory space for
+parameter values if they resident in the same process like
+[Caffe](http://caffe.berkeleyvision.org/)'s parallel implementation. Sharing
+memory could save memory space, but it could also change the training logic and
+thus affects the convergence rate.
+
+Each worker (thread) has a PMWorker (abbr for parameter management on workers)
+object, e.g., pmw1, pmw2, which calls the Get/Put/Update functions to get
+parameters, put parameters and update parameters. These functions may send
+requests to servers that use PMServer (abbr for parameter management on
+servers), e.g., pms1, pms2, to handle these requests.
+
+## Physical Architecture
+
+In this section, we describe how to configure Singa to generalize the logical
+architecture to the physical architectures of existing systems, e.g., Caffe and
+Baidu's DeepImage, Google Brain and Microsoft Adam. The architecture
+configuration includes:
+
+  * Number of worker threads per worker group and per process, which decides
+   the partitioning of worker side ParamShard
+
+  * Number of server threads per server group and per process, which decides
+   the partitioning of server side ParamShard
+
+  * Separation of servers and workers in different processes
+
+  * Number of worker groups per server group
+
+  * Topology of server groups, e.g., ring, tree, fully connected, etc.
+
+We put automatic optimization of the configuration as a future feature.
+
+### No Partition of ParamShard
+
+<figure>
+<img src="{{ BASE_PATH }}/assets/image/arch/arch1.png" align="center" width="550px"/>
+<figcaption><strong> Fig.2 - Physical system architecture without partitioning
+ParamShard</strong></figcaption>
+</figure>
+
+Fig.2 shows the architecture by configuring three threads per worker group, two
+threads per server group, two worker groups and one server group per process.
+Worker threads and server threads run as sub-threads. The main thread runs a
+loop as a stub to forward messages. For instance, the Get/Put/Update requests
+from workers are forwarded to the local servers, while Sync requests from the
+local servers are forwarded to remote servers. In this architecture, every
+group is fully contained in one process, hence the ParamShard objects is not
+partitioned.  If the ParamShards within one process share the same memory space
+for parameter values, the training procedure then follows
+[Hogwild](http://i.stanford.edu/hazy/hazy/victor/Hogwild/).  If we only
+launch process 1, Singa then runs in standalone mode. If we launch multiple
+processes, we can connect the server groups to form different topologies,
+e.g., ring or tree. Synchronization is conducted via inter-process
+communication between neighboring server groups. In
+[Caffe's](http://caffe.berkeleyvision.org/) parallel training architecture,
+processes are arranged into a ring. Caffe luanches one thread per model
+replica, hence it only supports data parallelism. Singa can also support
+model parallelism by partition the model replica among multiple worker
+threads within one group.
+
+### Partition Server Side ParamShard
+
+<figure>
+<img src="{{ BASE_PATH }}/assets/image/arch/arch2.png" align="center" width="550px"/>
+<figcaption><strong> Fig.3 - Physical system architecture, partitioning
+server ParamShard</strong></figcaption>
+</figure>
+
+Fig.3 shows another physical architecture by configuring one worker group per
+process, and two processes per server group. Because the server group spans two
+processes, the ParamShard of the server group is partitioned across the two
+processes. We only show one server groups in the figure. The vertical lines
+represent inter-process communication to synchronize server groups if there
+are multiple server groups. In process 1, if the update for a parameter that
+residents in process 2, then the PMWorker's update request would be sent to
+process 2 via inter-process communication. If the parameter is maintained by
+process 1, then the update request is sent to pms2 directly via intra-process
+communication. The processes for other requests are the same. Baidu's
+[DeepImage](http://arxiv.org/abs/1501.02876) system uses one server group and
+its ParamShard is partitioned across all processes. Consequently, the stub of each process is
+connected with all other processes' stubs for updating parameters. Like Caffe,
+it launches only one thread per worker group, thus only support data
+parallelism.
+
+### Partition Worker Side ParamShard
+
+<figure>
+<img src="{{ BASE_PATH }}/assets/image/arch/arch3.png" align="center" width="550px"/>
+<figcaption><strong> Fig.4 - Physical system architecture, partitioning
+worker ParamShard</strong></figcaption>
+</figure>
+
+The main difference of the architectures in Fig.4 and Fig.3 is that the worker
+group is partitioned over two processes in Fig.4. Consequently, the ParamShard
+is partitioned across process 1 and process 2. There are two kinds of
+parameters to consider:
+
+  * unique parameter: this kind of parameter exists in only one of the
+  partitioned ParamShards (due to model partition), and is updated by one
+  worker in its host process.  Hence the update is conducted similar to that in
+  Fig.2.
+
+  * replicated parameter: this kind of parameter is replicated in all
+  ParamShards (due to data partition), and its update is the aggregation of
+  updates from all workers.  The aggregation is processed as follows. First the
+  first process is selected as the leader process. (Update/Get/Put) requests of
+  PMWorkers on other processes are aggregated locally and then forwarded to the
+  leader process which handles it in the main thread. *The main thread of the
+  leader process creates a PMWorker over the ParamShard it owns. It handles
+  the request by calling the correspondingly functions, e.g., Update/Get/Put().
+  The responses from the servers are sent to the first worker of all sub ParamShards.*
+
+### Workers and Servers in Different Processes
+
+<figure>
+<img src="{{ BASE_PATH }}/assets/image/arch/arch4.png" align="center" width="550px"/>
+<figcaption><strong> Fig.5 - Physical system architecture, separating workers
+and servers</strong></figcaption>
+</figure>
+
+Fig.5 shows an architecture similar to that in Fig.4 except that the servers
+and workers are separated into different processes. Consequently all requests
+are sent via inter-process communication and handled by remote servers. More
+details on this architecture are explained in
+[Worker-Server Architecture]({{ BASE_PATH }}{% post_url /docs/2015-03-20-parameter-management %}). This is
+the architecture used by Google's Brain and Microsoft's Adam system. It is also
+called the Downpour architecture.
+
+## Conclusion
+
+We have shown that Singa's architecture is general enough
+to unify the architectures of existing distributed training systems.
+Since the rest architectures can be derived similarly as the above four by
+setting different architecture configurations, we do not numerate them here.


Mime
View raw message