1*89928cc5SHong Zhang#!/usr/bin/env bash 2*89928cc5SHong Zhang 3*89928cc5SHong Zhang# Copyright 2017-2018 4*89928cc5SHong Zhang# 5*89928cc5SHong Zhang# Karlsruhe Institute of Technology 6*89928cc5SHong Zhang# Universitat Jaume I 7*89928cc5SHong Zhang# University of Tennessee 8*89928cc5SHong Zhang# 9*89928cc5SHong Zhang# Redistribution and use in source and binary forms, with or without 10*89928cc5SHong Zhang# modification, are permitted provided that the following conditions are met: 11*89928cc5SHong Zhang# 12*89928cc5SHong Zhang# 1. Redistributions of source code must retain the above copyright notice, 13*89928cc5SHong Zhang# this list of conditions and the following disclaimer. 14*89928cc5SHong Zhang# 15*89928cc5SHong Zhang# 2. Redistributions in binary form must reproduce the above copyright notice, 16*89928cc5SHong Zhang# this list of conditions and the following disclaimer in the documentation 17*89928cc5SHong Zhang# and/or other materials provided with the distribution. 18*89928cc5SHong Zhang# 19*89928cc5SHong Zhang# 3. Neither the name of the copyright holder nor the names of its contributors 20*89928cc5SHong Zhang# may be used to endorse or promote products derived from this software 21*89928cc5SHong Zhang# without specific prior written permission. 22*89928cc5SHong Zhang# 23*89928cc5SHong Zhang# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24*89928cc5SHong Zhang# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25*89928cc5SHong Zhang# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26*89928cc5SHong Zhang# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27*89928cc5SHong Zhang# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28*89928cc5SHong Zhang# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29*89928cc5SHong Zhang# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30*89928cc5SHong Zhang# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31*89928cc5SHong Zhang# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32*89928cc5SHong Zhang# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33*89928cc5SHong Zhang# POSSIBILITY OF SUCH DAMAGE. 34*89928cc5SHong Zhang 35*89928cc5SHong Zhangset -e 36*89928cc5SHong Zhang 37*89928cc5SHong ZhangARCHIVE_LOCATION=${ARCHIVE_LOCATION:="./ssget_archive"} 38*89928cc5SHong ZhangTHIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" &>/dev/null && pwd ) 39*89928cc5SHong ZhangSS_URL="https://sparse.tamu.edu" 40*89928cc5SHong Zhang 41*89928cc5SHong Zhangmkdir -p "${ARCHIVE_LOCATION}" 42*89928cc5SHong Zhang 43*89928cc5SHong ZhangCOMMAND=get_database_version 44*89928cc5SHong ZhangMATRIX_TYPE="MM" 45*89928cc5SHong ZhangMATRIX_ID=1 46*89928cc5SHong ZhangPROP_NAMES=( 47*89928cc5SHong Zhang "group" 48*89928cc5SHong Zhang "name" 49*89928cc5SHong Zhang "rows" 50*89928cc5SHong Zhang "cols" 51*89928cc5SHong Zhang "nonzeros" 52*89928cc5SHong Zhang "real" 53*89928cc5SHong Zhang "binary" 54*89928cc5SHong Zhang "2d3d" 55*89928cc5SHong Zhang "posdef" 56*89928cc5SHong Zhang "psym" 57*89928cc5SHong Zhang "nsym" 58*89928cc5SHong Zhang "kind") 59*89928cc5SHong Zhang 60*89928cc5SHong Zhang 61*89928cc5SHong Zhangredownload_info() { 62*89928cc5SHong Zhang curl -Lo "${ARCHIVE_LOCATION}/ssstats.csv" "${SS_URL}/files/ssstats.csv" 63*89928cc5SHong Zhang} 64*89928cc5SHong Zhang 65*89928cc5SHong Zhang 66*89928cc5SHong Zhangdownload_info() { 67*89928cc5SHong Zhang if [ ! -f "${ARCHIVE_LOCATION}/ssstats.csv" ]; then 68*89928cc5SHong Zhang redownload_info 69*89928cc5SHong Zhang fi 70*89928cc5SHong Zhang} 71*89928cc5SHong Zhang 72*89928cc5SHong Zhang 73*89928cc5SHong ZhangPROPS="" 74*89928cc5SHong Zhangget_properties() { 75*89928cc5SHong Zhang download_info 76*89928cc5SHong Zhang if [ "${PROPS}" == "" ]; then 77*89928cc5SHong Zhang PROPS=$(head -$((${MATRIX_ID} + 2)) "${ARCHIVE_LOCATION}/ssstats.csv" \ 78*89928cc5SHong Zhang | tail -1) 79*89928cc5SHong Zhang fi 80*89928cc5SHong Zhang echo "${PROPS}" 81*89928cc5SHong Zhang} 82*89928cc5SHong Zhang 83*89928cc5SHong Zhang 84*89928cc5SHong Zhangget_property() { 85*89928cc5SHong Zhang IFS="," read -ra PROPS <<< "$(get_properties)" 86*89928cc5SHong Zhang NPARAM=${#PROP_NAMES[@]} 87*89928cc5SHong Zhang for (( i=0; i < ${NPARAM}; ++i)); do 88*89928cc5SHong Zhang if [ "$1" = "${PROP_NAMES[$i]}" ]; then 89*89928cc5SHong Zhang echo ${PROPS[$i]} 90*89928cc5SHong Zhang return 91*89928cc5SHong Zhang fi 92*89928cc5SHong Zhang done 93*89928cc5SHong Zhang} 94*89928cc5SHong Zhang 95*89928cc5SHong Zhang 96*89928cc5SHong Zhangget_as_json() { 97*89928cc5SHong Zhang BOOL_MAP=("false" "true") 98*89928cc5SHong Zhang IFS="," read -ra PROPS <<< "$(get_properties)" 99*89928cc5SHong Zhang cat << JSON 100*89928cc5SHong Zhang{ 101*89928cc5SHong Zhang "id": ${MATRIX_ID}, 102*89928cc5SHong Zhang "group": "${PROPS[0]}", 103*89928cc5SHong Zhang "name": "${PROPS[1]}", 104*89928cc5SHong Zhang "rows": ${PROPS[2]}, 105*89928cc5SHong Zhang "cols": ${PROPS[3]}, 106*89928cc5SHong Zhang "nonzeros": ${PROPS[4]}, 107*89928cc5SHong Zhang "real": ${BOOL_MAP[${PROPS[5]}]}, 108*89928cc5SHong Zhang "binary": ${BOOL_MAP[${PROPS[6]}]}, 109*89928cc5SHong Zhang "2d3d": ${BOOL_MAP[${PROPS[7]}]}, 110*89928cc5SHong Zhang "posdef": ${BOOL_MAP[${PROPS[8]}]}, 111*89928cc5SHong Zhang "psym": ${PROPS[9]}, 112*89928cc5SHong Zhang "nsym": ${PROPS[10]}, 113*89928cc5SHong Zhang "kind": "${PROPS[11]}" 114*89928cc5SHong Zhang} 115*89928cc5SHong ZhangJSON 116*89928cc5SHong Zhang} 117*89928cc5SHong Zhang 118*89928cc5SHong Zhang 119*89928cc5SHong Zhangget_path_info() { 120*89928cc5SHong Zhang GROUP=$(get_property group) 121*89928cc5SHong Zhang NAME=$(get_property name) 122*89928cc5SHong Zhang if [ "${MATRIX_TYPE}" = "mat" ]; then 123*89928cc5SHong Zhang EXT="mat" 124*89928cc5SHong Zhang else 125*89928cc5SHong Zhang EXT="tar.gz" 126*89928cc5SHong Zhang fi 127*89928cc5SHong Zhang MATRIX_URI="${MATRIX_TYPE}/${GROUP}/${NAME}" 128*89928cc5SHong Zhang UPSTREAM_URL="${SS_URL}/${MATRIX_URI}.${EXT}" 129*89928cc5SHong Zhang DOWNLOAD_PATH="${ARCHIVE_LOCATION}/${MATRIX_URI}.${EXT}" 130*89928cc5SHong Zhang EXTRACT_PATH="${ARCHIVE_LOCATION}/${MATRIX_URI}" 131*89928cc5SHong Zhang cat <<- EOT 132*89928cc5SHong Zhang ${GROUP} 133*89928cc5SHong Zhang ${NAME} 134*89928cc5SHong Zhang ${MATRIX_URI} 135*89928cc5SHong Zhang ${UPSTREAM_URL} 136*89928cc5SHong Zhang ${DOWNLOAD_PATH} 137*89928cc5SHong Zhang ${EXTRACT_PATH} 138*89928cc5SHong ZhangEOT 139*89928cc5SHong Zhang} 140*89928cc5SHong Zhang 141*89928cc5SHong Zhang 142*89928cc5SHong Zhangdownload_archive() { 143*89928cc5SHong Zhang PATH_INFO=($(get_path_info)) 144*89928cc5SHong Zhang if [ ! -f ${PATH_INFO[4]} ]; then 145*89928cc5SHong Zhang mkdir -p $(dirname ${PATH_INFO[4]}) 146*89928cc5SHong Zhang curl -Lo ${PATH_INFO[4]} ${PATH_INFO[3]} 147*89928cc5SHong Zhang fi 148*89928cc5SHong Zhang echo ${PATH_INFO[4]} 149*89928cc5SHong Zhang} 150*89928cc5SHong Zhang 151*89928cc5SHong Zhang 152*89928cc5SHong Zhangextract_archive() { 153*89928cc5SHong Zhang PATH_INFO=($(get_path_info)) 154*89928cc5SHong Zhang download_archive >/dev/null 155*89928cc5SHong Zhang if [ "${MATRIX_TYPE}" = "mat" ]; then 156*89928cc5SHong Zhang echo ${PATH_INFO[4]} 157*89928cc5SHong Zhang return 158*89928cc5SHong Zhang fi 159*89928cc5SHong Zhang mkdir -p ${PATH_INFO[5]} 160*89928cc5SHong Zhang tar -xzf ${PATH_INFO[4]} -C ${PATH_INFO[5]} --strip-components=1 161*89928cc5SHong Zhang if [ "${MATRIX_TYPE}" = "RB" ]; then 162*89928cc5SHong Zhang EXT="rb" 163*89928cc5SHong Zhang else 164*89928cc5SHong Zhang EXT="mtx" 165*89928cc5SHong Zhang fi 166*89928cc5SHong Zhang echo "${PATH_INFO[5]}/${PATH_INFO[1]}.${EXT}" 167*89928cc5SHong Zhang} 168*89928cc5SHong Zhang 169*89928cc5SHong Zhang 170*89928cc5SHong Zhangclean_extracted() { 171*89928cc5SHong Zhang PATH_INFO=($(get_path_info)) 172*89928cc5SHong Zhang if [ ! -e ${PATH_INFO[5]} ]; then 173*89928cc5SHong Zhang echo 0 174*89928cc5SHong Zhang return 175*89928cc5SHong Zhang fi 176*89928cc5SHong Zhang 177*89928cc5SHong Zhang SIZE=($(du -b ${PATH_INFO[5]})) 178*89928cc5SHong Zhang rm -rf ${PATH_INFO[5]} 179*89928cc5SHong Zhang echo ${SIZE[0]} 180*89928cc5SHong Zhang} 181*89928cc5SHong Zhang 182*89928cc5SHong Zhang 183*89928cc5SHong Zhangremove_archive() { 184*89928cc5SHong Zhang PATH_INFO=($(get_path_info)) 185*89928cc5SHong Zhang SIZE=($(du -b ${PATH_INFO[4]})) 186*89928cc5SHong Zhang rm -rf ${PATH_INFO[4]} 187*89928cc5SHong Zhang echo ${SIZE[0]} 188*89928cc5SHong Zhang} 189*89928cc5SHong Zhang 190*89928cc5SHong Zhang 191*89928cc5SHong Zhangget_collection_size() { 192*89928cc5SHong Zhang download_info 193*89928cc5SHong Zhang head -1 "${ARCHIVE_LOCATION}/ssstats.csv" 194*89928cc5SHong Zhang} 195*89928cc5SHong Zhang 196*89928cc5SHong Zhang 197*89928cc5SHong Zhangget_database_version() { 198*89928cc5SHong Zhang download_info 199*89928cc5SHong Zhang echo -n "${ARCHIVE_LOCATION}/ssstats.csv " 200*89928cc5SHong Zhang echo "$(head -2 "${ARCHIVE_LOCATION}/ssstats.csv" | tail -1)" 201*89928cc5SHong Zhang} 202*89928cc5SHong Zhang 203*89928cc5SHong Zhang 204*89928cc5SHong ZhangCONDITION="" 205*89928cc5SHong ZhangTEMP_PROPS="" 206*89928cc5SHong Zhangreplace_placeholder() { 207*89928cc5SHong Zhang BOOL_MAP=("false" "true") 208*89928cc5SHong Zhang EVAL_COND=${CONDITION} 209*89928cc5SHong Zhang # s/@kind/${TEMP_PROPS[11]}/g is failed because s/@kind/2D/3D Problem/g has 210*89928cc5SHong Zhang # too many slashes 211*89928cc5SHong Zhang REPLACE="s/@group/${TEMP_PROPS[0]}/g;" 212*89928cc5SHong Zhang REPLACE="${REPLACE}s/@name/${TEMP_PROPS[1]}/g;" 213*89928cc5SHong Zhang REPLACE="${REPLACE}s/@rows/${TEMP_PROPS[2]}/g;" 214*89928cc5SHong Zhang REPLACE="${REPLACE}s/@cols/${TEMP_PROPS[3]}/g;" 215*89928cc5SHong Zhang REPLACE="${REPLACE}s/@nonzeros/${TEMP_PROPS[4]}/g;" 216*89928cc5SHong Zhang REPLACE="${REPLACE}s/@real/${BOOL_MAP[${TEMP_PROPS[5]}]}/g;" 217*89928cc5SHong Zhang REPLACE="${REPLACE}s/@binary/${BOOL_MAP[${TEMP_PROPS[6]}]}/g;" 218*89928cc5SHong Zhang REPLACE="${REPLACE}s/@2d3d/${BOOL_MAP[${TEMP_PROPS[7]}]}/g;" 219*89928cc5SHong Zhang REPLACE="${REPLACE}s/@posdef/${BOOL_MAP[${TEMP_PROPS[8]}]}/g;" 220*89928cc5SHong Zhang REPLACE="${REPLACE}s/@psym/${TEMP_PROPS[9]}/g;" 221*89928cc5SHong Zhang REPLACE="${REPLACE}s/@nsym/${TEMP_PROPS[10]}/g;" 222*89928cc5SHong Zhang REPLACE="${REPLACE}s~@kind~${TEMP_PROPS[11]}~g" 223*89928cc5SHong Zhang EVAL_COND=$(echo $EVAL_COND | sed -e "$REPLACE") 224*89928cc5SHong Zhang} 225*89928cc5SHong Zhang 226*89928cc5SHong Zhang 227*89928cc5SHong Zhangsearch_database() { 228*89928cc5SHong Zhang download_info 229*89928cc5SHong Zhang INDEX=-2; 230*89928cc5SHong Zhang while IFS='' read -r LINE || [[ -n "$LINE" ]]; do 231*89928cc5SHong Zhang INDEX=$(( $INDEX + 1 )) 232*89928cc5SHong Zhang if [[ $INDEX -gt 0 ]]; then 233*89928cc5SHong Zhang IFS="," read -ra TEMP_PROPS <<< "$LINE" 234*89928cc5SHong Zhang EVAL_COND="" 235*89928cc5SHong Zhang replace_placeholder 236*89928cc5SHong Zhang if eval $EVAL_COND ; then 237*89928cc5SHong Zhang echo $INDEX 238*89928cc5SHong Zhang fi 239*89928cc5SHong Zhang fi 240*89928cc5SHong Zhang done < "${ARCHIVE_LOCATION}/ssstats.csv" 241*89928cc5SHong Zhang} 242*89928cc5SHong Zhang 243*89928cc5SHong Zhang 244*89928cc5SHong Zhangprint_usage_and_exit() { 245*89928cc5SHong Zhang cat 1>&2 << EOT 246*89928cc5SHong ZhangUsage: $0 [options] 247*89928cc5SHong Zhang 248*89928cc5SHong ZhangAvailable options: 249*89928cc5SHong Zhang -c clean files extracted from archive 250*89928cc5SHong Zhang -d (re)download matrix info file 251*89928cc5SHong Zhang -e download matrix and extract archive 252*89928cc5SHong Zhang -f download matrix and get path to archive 253*89928cc5SHong Zhang -h show this help 254*89928cc5SHong Zhang -i ID matrix id 255*89928cc5SHong Zhang -j print information about the matrix in JSON format 256*89928cc5SHong Zhang -n get number of matrices in collection 257*89928cc5SHong Zhang -p PROPERTY print information about the matrix, PROPERTY is the propery to 258*89928cc5SHong Zhang print, one of group, name, rows, cols, nonzeros, real, binary, 259*89928cc5SHong Zhang 2d3d, posdef, psym, nsym, kind 260*89928cc5SHong Zhang -r remove archive 261*89928cc5SHong Zhang -t TYPE matrix type, TYPE is one of: MM (matrix market, '.mtx'), RB 262*89928cc5SHong Zhang (Rutherford Boeing, '.rb'), mat (MATLAB, '.mat') 263*89928cc5SHong Zhang -v get database version 264*89928cc5SHong Zhang -s search database with conditions. It uses @PROPERTY as the 265*89928cc5SHong Zhang placeholder 266*89928cc5SHong Zhang 267*89928cc5SHong ZhangCalling $0 without arguments is equivalent to: $0 -i 0 -t MM -v 268*89928cc5SHong ZhangEOT 269*89928cc5SHong Zhang exit $1 270*89928cc5SHong Zhang} 271*89928cc5SHong Zhang 272*89928cc5SHong Zhang 273*89928cc5SHong Zhangwhile getopts ":cdefhi:jnp:rt:vs:" opt; do 274*89928cc5SHong Zhang case ${opt} in 275*89928cc5SHong Zhang :) 276*89928cc5SHong Zhang echo 1>&2 "Option -${OPTARG} provided without an argument" 277*89928cc5SHong Zhang print_usage_and_exit 2 278*89928cc5SHong Zhang ;; 279*89928cc5SHong Zhang \?) 280*89928cc5SHong Zhang echo 1>&2 "Unknown option: -${OPTARG}" 281*89928cc5SHong Zhang print_usage_and_exit 1 282*89928cc5SHong Zhang ;; 283*89928cc5SHong Zhang c) 284*89928cc5SHong Zhang COMMAND=clean_extracted 285*89928cc5SHong Zhang ;; 286*89928cc5SHong Zhang d) 287*89928cc5SHong Zhang COMMAND=redownload_info 288*89928cc5SHong Zhang ;; 289*89928cc5SHong Zhang e) 290*89928cc5SHong Zhang COMMAND=extract_archive 291*89928cc5SHong Zhang ;; 292*89928cc5SHong Zhang f) 293*89928cc5SHong Zhang COMMAND=download_archive 294*89928cc5SHong Zhang ;; 295*89928cc5SHong Zhang h) 296*89928cc5SHong Zhang print_usage_and_exit 0 297*89928cc5SHong Zhang ;; 298*89928cc5SHong Zhang i) 299*89928cc5SHong Zhang if [[ ! "${OPTARG}" =~ ^([0-9]+)$ ]]; then 300*89928cc5SHong Zhang echo 1>&2 "Matrix ID has to be a number, got: ${OPTARG}" 301*89928cc5SHong Zhang print_usage_and_exit 4 302*89928cc5SHong Zhang fi 303*89928cc5SHong Zhang MATRIX_ID=${OPTARG} 304*89928cc5SHong Zhang ;; 305*89928cc5SHong Zhang j) 306*89928cc5SHong Zhang COMMAND=get_as_json 307*89928cc5SHong Zhang ;; 308*89928cc5SHong Zhang n) 309*89928cc5SHong Zhang COMMAND=get_collection_size 310*89928cc5SHong Zhang ;; 311*89928cc5SHong Zhang p) 312*89928cc5SHong Zhang PROP_LIST="group|name|rows|cols|nonzeros" 313*89928cc5SHong Zhang PROP_LIST="${PROP_LIST}|real|binary|2d3d|posdef|psym|nsym|kind" 314*89928cc5SHong Zhang if [[ ! "${OPTARG}" =~ ^(${PROP_LIST})$ ]]; then 315*89928cc5SHong Zhang echo 1>&2 "Unknown property: ${OPTARG}" 316*89928cc5SHong Zhang print_usage_and_exit 5 317*89928cc5SHong Zhang fi 318*89928cc5SHong Zhang COMMAND="get_property ${OPTARG}" 319*89928cc5SHong Zhang ;; 320*89928cc5SHong Zhang r) 321*89928cc5SHong Zhang COMMAND=remove_archive 322*89928cc5SHong Zhang ;; 323*89928cc5SHong Zhang t) 324*89928cc5SHong Zhang if [[ ! "${OPTARG}" =~ ^(MM|RB|mat)$ ]]; then 325*89928cc5SHong Zhang echo 1>&2 "Wrong matrix type: ${OPTARG}" 326*89928cc5SHong Zhang print_usage_and_exit 3 327*89928cc5SHong Zhang fi 328*89928cc5SHong Zhang MATRIX_TYPE=${OPTARG} 329*89928cc5SHong Zhang ;; 330*89928cc5SHong Zhang v) 331*89928cc5SHong Zhang COMMAND=get_database_version 332*89928cc5SHong Zhang ;; 333*89928cc5SHong Zhang s) 334*89928cc5SHong Zhang COMMAND=search_database 335*89928cc5SHong Zhang CONDITION=${OPTARG} 336*89928cc5SHong Zhang ;; 337*89928cc5SHong Zhang esac 338*89928cc5SHong Zhangdone 339*89928cc5SHong Zhang 340*89928cc5SHong Zhang 341*89928cc5SHong Zhang${COMMAND} 342