BSP内核构建走读
camdriod中对lichee的构建过程
使用BSP内核的话，需要使用官方sdk编译camdriod并从中取出uImage。
鉴于camdriod较大，所以我们先简单走读下camdriod中对lichee的构建过程，扣出这部分内容。
camdriod的构建脚本：
~~~~ {.sourceCode .bash}
!/bin/bash
source build/envsetup.sh &&
lunch &&
mklichee &&
extract-bsp &&
make -j8 &&
pack
~~~~
source build/envsetup.sh 这里是include各种环境变量，比如就添加了
tiger_cdr-eng 选项，这里先不管它。
lunch就是选择目标板配置了，是在 build/envsetup.sh 中的函数。
接着就是关键的mklichee了，在 device/softwinner/common/vendorsetup.sh
里，深入看下：
~~ {.sourceCode .bash}~
function set_environment()
{
LICHEE_CHIP="sun8iw8p1"
export CAMLINUX_BUILD_TOP=pwd
export DEVICE_DIR=$CAMLINUX_BUILD_TOP/device/softwinner
export TARGET_OUT=$CAMLINUX_BUILD_TOP/output
export OUT_DIR=$CAMLINUX_BUILD_TOP/out
export LICHEE_DIR=$CAMLINUX_BUILD_TOP/../lichee
export LICHEE_OUT_DIR=$LICHEE_DIR/out/sun8iw8p1/linux
export BR_ROOTFS_DIR=$TARGET_OUT/target
export LICHEE_BR_DIR=${LICHEE_DIR}/buildroot
export LICHEE_KERN_DIR=${LICHEE_DIR}/linux-3.4
export LINUXOUT_MODULE_DIR=$LICHEE_KERN_DIR/output/lib/modules//
export LICHEE_KERN_OUTDIR=$LICHEE_KERN_DIR/output
export LICHEE_TOOLS_DIR=${LICHEE_DIR}/tools
export LICHEE_UBOOT_DIR=${LICHEE_DIR}/brandy/u-boot-2011.09
}
~
~~ {.sourceCode .bash}~
function mklichee()
{
mksetting #显示目前的配置信息
mk_info "build lichee ---"
mkbr && mkkernel
# mkbr && mkkernel && mkuboot
[ $? -ne 0 ] && return 1
return 0
}
~
mkbr是运行了 buildroot/scripts/build.sh buildroot linux sun8iw8p1
~~~~ {.sourceCode .bash}
function mkbr()
{
mk_info "build buildroot ---"
local build_script
build_script="scripts/build.sh"
LICHEE_PLATFORM="linux"
(cd ${LICHEE_BR_DIR} && [ -x ${build_script} ] && ./${build_script} "buildroot" ${LICHEE_PLATFORM} ${LICHEE_CHIP})
[ $? -ne 0 ] && mk_error "build buildroot Failed" && return 1
mk_info "build buildroot OK."
}
~~~~
~~ {.sourceCode .bash}~
if [ "x${LICHEE_PLATFORM}" = "xlinux" ] ; then
build_buildroot
export PATH=${LICHEE_BR_OUT}/external-toolchain/bin:$PATH
build_external
else
build_toolchain
~
LICHEE_PLATFORM并没有被传入，实际执行的是下面这个build_toolchain：
~~~~ {.sourceCode .bash}
build_toolchain()
{
local tooldir="${LICHEE_BR_OUT}/external-toolchain"
mkdir -p ${tooldir}
if [ -f ${tooldir}/.installed ] ; then
printf "external toolchain has been installed\n"
else
printf "installing external toolchain\n"
printf "please wait for a few minutes ---\n"
tar --strip-components=1 \
-jxf ${LICHEE_BR_DIR}/dl/gcc-linaro.tar.bz2 \
-C ${tooldir}
[ $? -eq 0 ] && touch ${tooldir}/.installed
fi
export PATH=${tooldir}/bin:${PATH}
}
~~~~
这里LICHEE_BR_OUT是 lichee/out/sun8iw8p1/linux/common/buildroot
LICHEE_BR_DIR是lichee/buildroot, 需要先导入。
这里使用的linaro版本比较老。注意如果使用较新的gcc反而会出错。
这里就是解压了linaro-gcc，并加入到环境变量。
mkbr看完了，接下来看mkkernel。
~~~~ {.sourceCode .bash}
function mkkernel()
{
local platformdef=$tdevice
if [ ! -n $tdevice ]; then
echo "Please lunch device"
return 1
fi
echo "Make the kernel"
echo "platformdef="${platformdef}
(cd ${LICHEE_KERN_DIR}/; ./build.sh -p ${platformdef})
[ $? -ne 0 ] && mk_error "build mkkernel fail" && return 1
echo "Make the kernel finish"
return 0
}
~~~~
执行的是lichee/linux-3.4/build.sh, 跟下去是执行了：
./scripts/build_${PLATFORM}.sh all
看script目录下，有：
build_crane-cdr.sh
build_crane-ipc.sh
build_crane-sdv.sh
build_crane-standard.sh
build_rootfs.sh
build.sh
build_sun6i.sh
build_sun8iw8p1.sh
build_tiger-cdr.sh
build_tiger-ipc.sh
build_tiger-standard.sh
就是代表的可以构建的板子型号。我们实际编译的时候只需要执行
build_tiger-cdr.sh 即可。
综上所述，需要剥离camdriod所用的lichee内核，只需要：
- 解压buildroot/dl/gcc-linarno.tar.gz
到lichee/out/sun8iw8p1/linux/common/buildroot/external-toolchain，并加入环境变量（这步其实在下一步里包含了）- 执行build_tiger-cdr.sh
启动信息
~~~~ {.sourceCode .python}
Starting kernel ---
Start: 0x40000000
Size: 64MB
ion_carveout reserve: 28m@0 28m@0
ion_reserve_common: ion reserve: [0x42400000, 0x44000000]!
[ 0.000000] Booting Linux on physical CPU 0
[ 0.000000] Linux version 3.4.39 (root@bf756b445919) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #29 Wed Nov 29 10:53:16 UTC 2017
[ 0.000000] bootconsole [earlycon0] enabled
[ 0.000000] Initialized persistent memory from 41d20800-41d307ff
[ 0.000000] Kernel command line: console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
[ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Memory: 64MB = 64MB total
[ 0.000000] Memory: 29312k/29312k available, 36224k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc050d000 (5140 kB)
[ 0.000000] .init : 0xc050d000 - 0xc0530000 ( 140 kB)
[ 0.000000] .data : 0xc0530000 - 0xc05ab500 ( 494 kB)
[ 0.000000] .bss : 0xc05ab524 - 0xc068c28c ( 900 kB)
[ 0.000000] NR_IRQS:544
[ 0.000000] Architected local timer running at 24.00MHz.
[ 0.000000] Switching to timer-based delay loop
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[ 0.000000] Console: colour dummy device 80x30
[ 0.014545] Calibrating delay loop (skipped), value calculated using timer frequency.. 4800.00 BogoMIPS (lpj=24000000)
[ 0.022936] pid_max: default: 32768 minimum: 301
[ 0.027778] Mount-cache hash table entries: 512
[ 0.030637] CPU: Testing write buffer coherency: ok
[ 0.035150] Setting up static identity map for 0x40396048 - 0x403960a0
[ 0.040773] devtmpfs: initialized
[ 0.045346] pinctrl core: initialized pinctrl subsystem
[ 0.049168] NET: Registered protocol family 16
[ 0.050362] DMA: preallocated 128 KiB pool for atomic coherent allocations
[ 0.056956] script_sysfs_init success
[ 0.060951] gpiochip_add: registered GPIOs 0 to 223 on device: sunxi-pinctrl
[ 0.068164] sunxi-pinctrl sunxi-pinctrl: initialized sunXi PIO driver
[ 0.070438] gpiochip_add: registered GPIOs 1024 to 1031 on device: axp-pinctrl
[ 0.078235] persistent_ram: uncorrectable error in header
[ 0.080020] persistent_ram: no valid data in buffer (sig = 0x75371537)
[ 0.091722] console [ram-1] enabled
[ 0.092266] Not Found clk pll_isp in script
[ 0.094113] Not Found clk pll_video in script
[ 0.098719] Not Found clk pll_ve in script
[ 0.100012] Not Found clk pll_periph0 in script
[ 0.104666] Not Found clk pll_de in script
[ 0.113517] bio: create slab
[ 0.113966] pwm module init!
[ 0.118375] SCSI subsystem initialized
[ 0.120028] usbcore: registered new interface driver usbfs
[ 0.125313] usbcore: registered new interface driver hub
[ 0.130165] usbcore: registered new device driver usb
[ 0.135149] twi_chan_cfg()340 - [twi0] has no twi_regulator.
[ 0.140018] twi_chan_cfg()340 - [twi1] has no twi_regulator.
[ 0.146123] Linux video capture interface: v2.00
[ 0.150126] gpiochip_add: gpios 1024..1028 (axp_pin) failed to register
[ 0.156916] Advanced Linux Sound Architecture Driver Version 1.0.25.
[ 0.160794] Switching to clocksource arch_sys_counter
[ 0.171015] NET: Registered protocol family 2
[ 0.171466] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.177306] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[ 0.184207] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.190440] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.196921] TCP: reno registered
[ 0.200126] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.206122] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.212647] NET: Registered protocol family 1
[ 0.217253] standby_mode = 1.
[ 0.219870] wakeup src cnt is : 3.
[ 0.223491] pmu1_enable = 0x0.
[ 0.226639] config_pmux_para: script_parser_fetch err.
[ 0.232034] pmu2_enable = 0x0.
[ 0.235126] add_sys_pwr_dm: get ldo name failed
[ 0.239818] add_sys_pwr_dm: get ldo name failed
[ 0.244317] add_sys_pwr_dm: get ldo name failed
[ 0.248900] add_sys_pwr_dm: get ldo name failed
[ 0.253610] add_sys_pwr_dm: get ldo name failed
[ 0.258090] add_sys_pwr_dm: get ldo name failed
[ 0.262796] add_sys_pwr_dm: get ldo name failed
[ 0.267274] add_sys_pwr_dm: get ldo name failed
[ 0.271877] add_sys_pwr_dm: get ldo name failed
[ 0.276566] add_sys_pwr_dm: get ldo name failed
[ 0.281061] after inited: sys_mask config = 0x0.
[ 0.285927] dynamic_standby enalbe = 0x0.
[ 0.290049] sunxi_reg_init enter
[ 0.295521] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.299326] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
[ 0.306584] msgmni has been set to 57
[ 0.311246] io scheduler noop registered
[ 0.313995] io scheduler deadline registered
[ 0.318410] io scheduler cfq registered (default)
[ 0.323712] [DISP]disp_module_init
[ 0.326990] cmdline,disp=
[ 0.329889] [DISP] disp_get_rotation_sw,line:68:disp 0 out of range? g_rot_sw=0
[ 0.336609] [DISP] disp_init_connections,line:289:NULL pointer: 0, 0
[ 0.344754] [DISP] Fb_map_kernel_logo,line:924:Fb_map_kernel_logo failed!
[ 0.352381] [DISP] disp_sys_power_enable,line:387:some error happen, fail to get regulator
[ 0.358275] [DISP] disp_sys_gpio_set_value,line:374:OSAL_GPIO_DevWRITE_ONEPIN_DATA, hdl is NULL
[ 0.367297] [DISP]disp_module_init finish
[ 0.371458] sw_uart_get_devinfo()1503 - uart0 has no uart_regulator.
[ 0.378007] uart0: ttyS0 at MMIO 0x1c28000 (irq = 32) is a SUNXI
[ 0.383640] sw_uart_pm()890 - uart0 clk is already enable
[ 0.389159] sw_console_se 0.397781] console [ttyS0] enabled, bootconsole disabled
[ 0.397781] console [ttyS0] enabled, bootconsole disabled
[ 0.405808] sunxi_spi_chan_cfg()1376 - [spi-0] has no spi_regulator.
[ 0.417215] spi spi0: master is unqueued, this is deprecated
[ 0.423980] m25p_probe()988 - Use the Dual Mode Read.
[ 0.429818] m25p80 spi0.0: found W25q128, expected at25df641
[ 0.436364] m25p80 spi0.0: W25q128 (16384 Kbytes)
[ 0.442069] Creating 4 MTD partitions on "spi0.0":
[ 0.447623] 0x000000000000-0x000000100000 : "uboot"
[ 0.454335] 0x000000100000-0x000000110000 : "script"
[ 0.461007] 0x000000110000-0x000000510000 : "kernel"
[ 0.467737] 0x000000510000-0x000001000000 : "rootfs"
[ 0.474560] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.502308] sunxi-ehci sunxi-ehci.1: SW USB2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.511538] sunxi-ehci sunxi-ehci.1: new USB bus registered, assigned bus number 1
[ 0.520232] sunxi-ehci sunxi-ehci.1: irq 104, io mem 0xf1c1a000
[ 0.540038] sunxi-ehci sunxi-ehci.1: USB 0.0 started, EHCI 1.00
[ 0.547565] hub 1-0:1.0: USB hub found
[ 0.552045] hub 1-0:1.0: 1 port detected
[ 0.557035] sunxi-ehci sunxi-ehci.1: remove, state 1
[ 0.562716] usb usb1: USB disconnect, device number 1
[ 0.570093] [DISP] disp_lcd_pwm_enable,line:1021:pwm device hdl is NULL
[ 0.577820] sunxi-ehci sunxi-ehci.1: USB bus 1 deregistered
[ 0.594381] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.621611] sunxi-ohci sunxi-ohci.1: SW USB2.0 'Open' Host Controller (OHCI) Driver
[ 0.630292] sunxi-ohci sunxi-ohci.1: new USB bus registered, assigned bus number 1
[ 0.638963] sunxi-ohci sunxi-ohci.1: irq 105, io mem 0xf1c1a400
[ 0.704775] hub 1-0:1.0: USB hub found
[ 0.709188] hub 1-0:1.0: 1 port detected
[ 0.714159] sunxi-ohci sunxi-ohci.1: remove, state 1
[ 0.719942] usb usb1: USB disconnect, device number 1
[ 0.726383] sunxi-ohci sunxi-ohci.1: USB bus 1 deregistered
[ 0.742856] Initializing USB Mass Storage driver---
[ 0.748591] usbcore: registered new interface driver usb-storage
[ 0.755417] USB Mass Storage support registered.
[ 0.761162] file system registered
[ 0.766892] android_usb gadget: Mass Storage Function, version: 2009/09/11
[ 0.774821] android_usb gadget: Number of LUNs=1
[ 0.780100] lun0: LUN: removable file: (no medium)
[ 0.786312] android_usb gadget: android_usb ready
[ 0.791843] sunxikbd_script_init: key para not found, used default para.
[ 0.800884] sunxi-rtc sunxi-rtc: rtc core: registered sunxi-rtc as rtc0
[ 0.808628] [VFE]cci probe start cci_sel = 0!
[ 0.813793] [VFE]cci probe end cci_sel = 0!
[ 0.818593] [VFE]cci_init end
[ 0.822038] [VFE]Welcome to Video Front End driver
[ 0.827986] [VFE]pdev->id = 0
[ 0.831435] [VFE]dev->mipi_sel = 0
[ 0.835324] [VFE]dev->vip_sel = 0
[ 0.839114] [VFE]dev->isp_sel = 0
[ 0.849164] [VFE_WARN]vfe vpu clock is null
[ 0.860599] [VFE]pdev->id = 1
[ 0.864021] [VFE]dev->mipi_sel = 1
[ 0.868014] [VFE]dev->vip_sel = 1
[ 0.871864] [VFE]dev->isp_sel = 0
[ 0.875672] [VFE]probe_work_handle start!
[ 0.880358] [VFE]------------------------..vfe clk open!---------------------..
[ 0.889010] [VFE]v4l2 subdev register input_num = 0
[ 0.894683] [VFE_WARN]vfe vpu clock is null
[ 0.899688] [VFE_ERR]vip1 request pinctrl handle for device [csi1] failed!
[ 0.907603] [VFE_ERR]get regulator csi_avdd error!
[ 0.913056] [VFE_ERR]vfe_device_regulator_get error at input_num = 0
[ 0.920482] [VFE]vfe_init end
[ 0.924426] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 0.933586] [VFE]V4L2 device registered as video0
[ 0.938969] [VFE]------------------------..vfe clk close!---------------------..
[ 0.947676] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 0.956440] [VFE]probe_work_handle end!
[ 0.960938] [VFE]probe_work_handle start!
[ 0.965515] [VFE]------------------------..vfe clk open!---------------------..
[ 0.974033] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 0.982739] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 0.991682] [VFE]v4l2 subdev register input_num = 0
[ 0.997227] [VFE]vfe sensor detect start! input_num = 0
[ 1.003274] [VFE]Find sensor name is "ov2640", i2c address is 60, type is "YUV" !
[ 1.011824] [VFE]Sub device register "ov2640" i2c_addr = 0x60 start!
[ 1.018998] [VFE_ERR]Error registering v4l2 subdevice No such device!
[ 1.026388] [VFE_ERR]vfe sensor register check error at input_num = 0
[ 1.033813] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.042602] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.051390] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.060339] sunxi_wdt_init_module: sunxi WatchDog Timer Driver v1.0
[ 1.067734] sunxi_wdt_probe: devm_ioremap return wdt_reg 0xf1c20ca0, res->start 0x01c20ca0, res->end 0x01c20cbf
[ 1.079242] [VFE]V4L2 device registered as video1
[ 1.084960] [VFE]------------------------..vfe clk close!---------------------..
[ 1.093623] sunxi_wdt_probe: initialized (g_timeout=16s, g_nowayout=0)
[ 1.101032] wdt_enable, write reg 0xf1c20cb8 val 0x00000000
[ 1.107445] wdt_set_tmout, write 0x000000b0 to mode reg 0xf1c20cb8, actual timeout 16 sec
[ 1.116779] [VFE]probe_work_handle end!
[ 1.127839] sunxi_leds_fetch_sysconfig_para leds is not used in config
[ 1.135343] =========script_get_err============
[ 1.140895] usbcore: registered new interface driver usbhid
[ 1.147192] usbhid: USB HID core driver
[ 1.152295] ashmem: initialized
[ 1.156010] logger: created 256K log 'log_main'
[ 1.161344] logger: created 32K log 'log_events'
[ 1.166840] logger: created 32K log 'log_radio'
[ 1.173330] logger: created 32K log 'log_system'
[ 1.181135] *****Try sdio*****
[ 1.188578] script_get_item return type err, consider it no ldo
[ 1.196448] asoc: sndcodec <-> sunxi-codec mapping ok
[ 1.203087] *****Try sd *****
[ 1.210630] TCP: cubic registered
[ 1.214424] NET: Registered protocol family 17
[ 1.219580] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[ 1.228464] ThumbEE CPU extension supported.
[ 1.233373] Registering SWP/SWPB emulation handler
[ 1.243467] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.252523] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.261210] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.269839] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.278387] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.287040] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.295877] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.304676] sunxi-rtc sunxi-rtc: setting system clock to 1970-01-01 00:52:23 UTC (3143)
[ 1.315547] ALSA device list:
[ 1.318966] #0: audiocodec
[ 1.322763] Waiting for root device /dev/mmcblk0p2---
[ 1.330265] mmc0: new high speed SDHC card at address 0007
[ 1.336986] mmcblk0: mmc0:0007 SD16G 14.4 GiB
[ 1.344244] mmcblk0: p1 p2
[ 1.348240] mmcblk mmc0:0007: Card claimed for testing.
[ 1.354284] mmc0:0007: SD16G 14.4 GiB
[ 1.358650] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.367505] *****sd init ok*****
[ 1.373971] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.382857] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.392791] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.401342] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.409966] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.418782] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.430110] fs_names=/dev/root
[ 1.433712] fs_name=ext3
[ 1.439951] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[ 1.451442] err=-22
[ 1.453911] fs_name=ext2
[ 1.456821] *****Try sdio*****
[ 1.465105] EXT4-fs (mmcblk0p2): couldn't mount as ext2 due to feature incompatibilities
[ 1.474453] err=-22
[ 1.476890] fs_name=ext4
[ 1.489053] mmc1: new high speed SDIO card at address 0001
[ 1.495719] *****sdio init ok*****
[ 2.726144] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 2.735371] VFS: Mounted root (ext4 filesystem) on device 179:2.
[ 2.742251] err=0
[ 2.747567] devtmpfs: mounted
[ 2.751204] Freeing init memory: 140K
Welcome to Debian GNU/Linux 8 (jessie)!
Expecting device dev-ttyS0.device---
[ OK ] Reached target Remote File Systems (Pre).
[ OK ] Reached target Paths.
[ OK ] Reached target Encrypted Volumes.
[ OK ] Reached target Swap.
Expecting device dev-mmcblk0p1.device---
[ OK ] Created slice Root Slice.
[ OK ] Listening on /dev/initctl Compatibility Named Pipe.
[ OK ] Listening on Delayed Shutdown Socket.
[ OK ] Listening on Journal Socket (/dev/log).
[ OK ] Listening on udev Control Socket.
[ OK ] Listening on udev Kernel Socket.
[ OK ] Created slice User and Session Slice.
[ OK ] Listening on Journal Socket.
[ OK ] Reached target Sockets.
[ OK ] Created slice System Slice.
Mounting Debug File System---
Starting Load Kernel Modules---
Starting udev Coldplug all Devices---
Starting Create Static Device Nodes in /dev---
[ OK ] Created slice system-getty.slice.
[ OK ] Created slice system-serial\x2dgetty.slice.
Starting Journal Service---
[ OK ] Started Journal Service.
[ OK ] Reached target Slices.
[ OK ] Mounted Debug File System.
[ OK ] Started Load Kernel Modules.
[ OK ] Started Create Static Device Nodes in /dev.
Starting udev Kernel Device Manager---
Starting Apply Kernel Variables---
ager.
[ OK ] Started udev Coldplug all Devices.
[ OK ] Started Apply Kernel Variables.
Starting Copy rules generated while the root was ro---
Starting LSB: Set preliminary keymap---
[ OK ] Started Copy rules generated while the root was ro.
[ OK ] Started LSB: Set preliminary keymap.
Starting Remount Root and Kernel File Systems---
[ 4.640531] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[ OK ] Started Remount Root and Kernel File Systems.
[ OK ] Reached target Local File Systems (Pre).
Starting Load/Save Random Seed---
[ OK ] Reached target Sound Card.
[ OK ] Started Load/Save Random Seed.
[ 5.012110] [VFE]vfe_open
[ OK [ 5.043465] [VFE]vfe_open
] Found device /dev/mmcblk0p1.
[ 5.058511] [VFE]------------------------..vfe clk open!---------------------..
[ 5.082179] [VFE]------------------------..vfe clk open!---------------------..
[ OK ] Found device /dev/ttyS0.
[ 5.112320] [VFE]vfe_open ok
[ 5.115853] [VFE]vfe_close
[ 5.118958] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.126480] [VFE]------------------------..vfe clk close!---------------------..
[ 5.144821] [VFE]vfe_open ok
[ 5.148348] [VFE]vfe_close
[ 5.151598] [VFE]vfe select input flag = 0, s_input have not be used .
[ 5.158972] [VFE]------------------------..vfe clk close!---------------------..
Mounting /boot---
[ 5.224773] [VFE]vfe_close end
[ 5.282919] [VFE]vfe_close end
[ OK ] Mounted /boot.
[ OK ] Reached target Local File Systems.
Starting Create Volatile Files and Directories---
[ OK ] Reached target Remote File Systems.
Starting Trigger Flushing of Journal to Persistent Storage---
Starting LSB: Set console font and keymap---
Starting LSB: Raise network interfaces---.
[ OK ] Started LSB: Set console font and keymap.
[ OK ] Started Trigger Flushing of Journal to Persistent Storage.
[ OK ] Started Create Volatile Files and Directories.
Starting Update UTMP about System Boot/Shutdown---
[ OK ] Started Update UTMP about System Boot/Shutdown.
[ OK ] Started LSB: Raise network interfaces..
[ OK ] Reached target Network.
[ OK ] Reached target System Initialization.
[ OK ] Reached target Timers.
Starting Restore Sound Card State---
[ OK ] Reached target Basic System.
Starting Regular background program processing daemon---
[ OK ] Started Regular background program processing daemon.
Starting OpenBSD Secure Shell server---
[ OK ] Started OpenBSD Secure Shell server.
Starting /etc/rc.local Compatibility---
Starting Permit User Sessions---
Starting getty on tty2-tty6 if dbus and logind are not available---
[ OK ] Started Restore Sound Card State.
[ OK ] Started /etc/rc.local Compatibility.
[ OK ] Started Permit User Sessions.
Starting Getty on tty2---
[ OK ] Started Getty on tty2.
Starting Getty on tty1---
[ OK ] Started Getty on tty1.
Starting Serial Getty on ttyS0---
[ OK ] Started Serial Getty on ttyS0.
[ OK ] Started getty on tty2-tty6 if dbus and logind are not available.
Starting Getty on tty6---
[ OK ] Started Getty on tty6.
Starting Getty on tty5---
[ OK ] Started Getty on tty5.
Starting Getty on tty4---
[ OK ] Started Getty on tty4.
Starting Getty on tty3---
[ OK ] Started Getty on tty3.
[ OK ] Reached target Login Prompts.
[ OK ] Reached target Multi-User System.
[ OK ] Reached target Graphical Interface.
Starting Update UTMP about System Runlevel Changes---
[ OK ] Started Update UTMP about System Runlevel Changes.
Debian GNU/Linux 8 LicheePi ttyS0
LicheePi login: root
~~~~


WITNESS LIST Subcommittee on Agriculture Committee March 11, 1999-1:00P SB 705 FOR: Gibson, Foy (Texas Wheat Producers Association), Bend Walzel, Jerry (Texas Produce Association), Mission Registering, but not testifying: For: Powers, Bill (Texas Farm Bureau), Austin Small, Ed (Texas & Southwestern Cattle Raisers Association), Austin Wilson, Ross (Texas Cattle Feeders Association), Amarillo On: Hubert, Martin (Texas Department of Agriculture), Austin SB 754 FOR: Walzel, Jerry (Texas Produce Association), Mission Registering, but not testifying: On: Garcia, Buddy (Senator Lucio), Austin


The audience that was used in the authentication request
When true
, ignores the cache and always sends a
request to Auth0.
There's no actual redirect when getting a token silently,
but, according to the spec, a redirect_uri
param is required.
Auth0 uses this parameter to validate that the current origin
matches the redirect_uri
origin
when sending the response.
It must be whitelisted in the "Allowed Web Origins" in your
Auth0 Application's settings.
The scope that was used in the authentication request
A maximum number of seconds to wait before declaring the background /authorize call as failed for timeout Defaults to 60s.
If you need to send custom parameters to the Authorization Server, make sure to use the original parameter name.


{% extends 'layouts/app.html' %} {% import 'macros/form.html' as f with context %} {% import 'billing/macros/billing.html' as billing %} {% block title %}Purchase coins{% endblock %} {% block body %}


Flash cards is web site for creating and sharing user created flash cards.
You can get started by register through the menu above or look below to take
a peek of what has already been created.
{% endblock header %}
{% block content %}
{% include 'partials/deck_list.html' %}
See More
{% endblock %}


Best Places to rest your head for a sensible price.
Our Resorts are second to none when it comes down to location and price! Do you want to see the beautiful beaches of Hawaii? Explore the Ape Caves in Washington? Or maybe just relax off out in the forest. We have you covered, (literally)!


SGI STL provides what we believe to be the most useful form of thread-safety. This explains some of the design decisions made in the SGI STL implementation.
The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses to distinct containers are safe, and simultaneous read accesses to to shared containers are safe. If multiple threads access a single container, and at least one thread may potentially write, then the user is responsible for ensuring mutual exclusion between the threads during the container accesses.
This is the only way to ensure full performance for containers that do not need concurrent access. Locking or other forms of synchronization are typically expensive and should be avoided when not necessary.
It is easy for the client or another library to provide the necessary locking by wrapping the underlying container operations with a lock acquisition and release. For example, it would be possible to provide a locked_queue container adapter that provided a container with atomic queue operations.
For most clients, it would be insufficient to simply make container operations atomic; larger grain atomic actions are needed. If a user's code needs to increment the third element in a vector of counters, it would be insuffcient to guarantee that fetching the third element and storing the third element is atomic; it is also necessary to guarantee that no other updates occur in the middle. Thus it would be useless for vector operations to acquire the lock; the user code must provide for locking in any case.
This decision is different from that made by the Java designers. There are two reasons for that. First, for security reasons Java must guarantee that even in the presence of unprotected concurrent accesses to a container, the integrity of the virtual machine cannot be violated. Such safety constraints were clearly not a driving force behind either C++ or STL. Secondly, performance was a more important design goal for STL then it was for the Java standard library.
On the other hand, this notion of thread-safety is stronger than that provided by reference-counted string implementations that try to follow the CD2 version of the draft standard. Such implementations require locking between multiple readers of a shared string.
The SGI STL implementation removes all nonconstant static data from container implementations. The only potentially shared static data resides in the allocator implementations. To this end, the code to implement per-class node allocation in HP STL was transformed into inlined code for per-size node allocation in the SGI STL allocators. Currently the only explicit locking is performed inside allocators.
Many other container implementations should also benefit from this design. It will usually be possible to implement thread-safe containers in portable code that does not depend on any particular thread package or locking primitives.
Alloc.h uses three different locking primitives depending on the environment.  The three styles of locking are:
It would be preferable if we could always use the OS-supplied locking primitives. Unfortunately, these often do not perform well, for very short critical sections such as those used by the allocator.
Allocation intensive applications using Pthreads to obtain concurrency on multiprocessors should consider using pthread_alloc from pthread_alloc.h. It imposes the restriction that memory deallocated by a thread can only be reallocated by that thread. However, it often obtains significant performance advantages as a result.


Service design patterns - Web services
15 Dec 2014Challenges:
- When should a particular api style be used
- client-service communication + foundations for complex conversations (multiple parties, extended periods of time)
- Approaches for implementing service logic
- Decoupling clients from the underlying systems used by the service
- Discover information about a service
- How to support generic functions (authentication, validation, caching) on client / service
- Service changes which break clients
- Version services
- Support continuous evolution (business logic) without requiring users to upgrade
What are Webservices
- Software function which carries a business task, provide access to files or perform generic functions (authenticating, logging, etc)
- Many different stacks
- Share logical functions
- Webservices integrate disparate systems and expose reusable business functions over HTTP
- Either leverage to HTTP as simple transport over which the data is transfered (SOAP/WSDL) or use it as a complete application protocol that defines the semantics for service behavior (RESTful services)
From local objects to distributed objects
- Objects = encapsulate behavior (e.g business logic) and data
- White-box reuse = access objects internals
- State between client calls
- Components = group related objects into deployable binary software units, that can be plugged into applications. Blackbox reuse - normally not accessible internal objects.
- Remoting technologies to support distribution (e.g. CORBA, DCOM, Java RMI)
- Complex implementation.
- Lack of standards (different vendor toolkits had problems to communicate).
State issue
Distributed objects typically maintained state between client calls, what led to a number of scalability problems.
- Memory utilization degradation with increased client load
- Effective load balance difficulty: User state was hold on a single server, coupling the user to that specific node.
- Server needs to implement a strategy to free memory
Why Webservices
- Share common logic with different clients (mobile, desktop, web apps)
- Open standards: independent on the underlying technologies.
- Facilitate complex business processes through composition - possible assembling simple services into workflows
- Clients and services may evolve independently = indirection = isolation
When to use
- Client and service belongs to different domains
- Service functions cannot be easily imported on client
- Client is a complex business process
- Separation between clients and services is natural.
Downs
- Expensive calls (e.g serialization / desserialization)
- Network latency
- Partial failures: Client, service or network fails while the others continue operating - requires strategies to detect and handle them
Alternatives
- Service libraries: Imported and executed on the client application
- If client and service were implemented on different platforms, there are ways to integrate them (e.g. JNI / Third-party bridging techniques).
- Network overhead (high-performance / high-load scenario). A connectionless protocol like UDP may be an alternative.
- HTTP is Good for large documents / messages. There are better alternatives for real-time delivery, such as RTSP (real time streaming protocol), RTP (real time transport protocol), RTCP (real time control protocol).
Loose coupling
- There will be always some sort of coupling
- Function coupling: Clients indirectly depend on the service implementation.
- Data structure coupling: Clients need to know which are the input / output formats, encoding, http status codes, etc.
- Temporal coupling: Occurs when the message needs to be processed as soon as it is received. Synchronous (blocking) processes increase this kind of coupling, and asynchronous processes reduces it, despite it adds complexity
- URI coupling: Clients are normally tighly coupled to service URIs. There are a number of patterns to reduce this coupling, as Linked service, service connector, etc.
To be continued...


Package io.inversion.utils
Class Configurator
- java.lang.Object
-
- io.inversion.utils.Configurator
-
public class Configurator extends java.lang.Object
Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.Configurator works in two different modes:
Dependency Injection Mode
- If the Engine already has an Api set on it, then it is assumed that a developer has at least partially wired up their own Api via code. In this case, the Configurator looks for named beans in the Api object graph(s) and sets any corresponding "beanName.propertyName" values fromconfiguration
on the bean. This is a great way to inject runtime dependencies such as database credentials. If developers are hard core SpringBoot-ers, or are otherwise coding up their Inversion Api using some existing DI framework, they may find this capability to be redundant and prefer to use their own party DI which is totally fine.Full Wiring Mode
- when an Engine starts up and no Api's have been added to the Engine via code, then the Configurator does all of the work to fully instantiate/configure/bootstrap the Api object model based on data found in theconfiguration
. Here is an outline how Full Wiring Mode works.- All beans with key/value properties "${beanName}.class=className" are instantiated and all "${beanName}.${propertyName}" values are set.
startup()
is called on all Db objects effectively bootstrapping the full Api model.- The now populated object graph is re-serialized to name/value property pairs in memory.
- All instantiated objects to this point are thrown away.
- All of the values from
configuration
are merged down on top of the in memory pairs. This allows the configuration author to overwrite any of the bean properties set during the Db.startup() default bootstrapping. - The merged properties model is decoded and the full Api(s) object model/graph that is set on the Engine.
- When the Engine calls startup() on the Apis (right after configure(Engine) returns), the Apis will call startup() on their Dbs. In the first pass, above, the Dbs had empty configurations so calling Db.startup() caused the Dbs to reflectively inspect their underlying data source and create Collections to represent underlying tables etc. These Collections were serialized out and then instantiated and set on the new copies of the Db in the final wiring above. Now when Db.startup() is called, the Db has Collection(s) already set on them and the Db will skip the reflective bootstrapping phase.
- NOTE: If you don't supply at least one "${myApiName}.class=io.inversion.Api" property in your
configuration
, a default api named "api" will be instantiated for you and the Configurator will assume all Db, Endpoints and Actions declared in theconfiguration
belong to that single implicit Api. - NOTE: If you have a single Api and you don't supply at least one "${myEndpointName}.class=io.inversion.Endpoint" property in our
configuration
, a default Endpoint named "endpoint" that matches on all HTTP methods and URL paths will be inferred by the Configurator. If you declear multiple Apis, you must declare Endpoints if you want your Api to do anything. - NOTE: If you only have a single Api, all Dbs, Endpoints, and global Actions will be set on the Api.
If you have more than one Api in your
configuration
, you must assign Dbs, Endpoints, and global Actions to the appropriate Api. A "global" Action is one that is not explicitly assigned to an Endpoint but is instead assigned directly to the Api and can then be selected to run across requests to multiple different Endpoints.
Here is an example minimal configuration for Full Wiring Mode that will produce a fully running REST API for the underlying data source. These name/value pairs can come from any combination of property sources loaded into
configuration
.myAction.class=io.inversion.db.DbAction myDb.class=io.inversion.jdbc.JdbcDb myDb.driver=${YOUR JDBC DRIVER CLASS NAME} myDb.url=${YOUR JDBC URL} myDb.user=${YOUR JDBC USERNAME} myDb.pass=${YOUR JDBC PASSWORD}
By default, the
configuration
is going to the global default CombinedConfiguration from Config.
-
-
Field Summary
Fields Modifier and Type Field Description static java.lang.String
MASK
static java.lang.Object[]
MASKED_FIELDS
If a bean property field name appears in this list, it will not be logged but replaced with "************" in the output.
-
Constructor Summary
Constructors Constructor Description Configurator()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
configure(Engine engine, org.apache.commons.configuration2.Configuration configuration)
Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.
-
-
-
Field Detail
-
MASKED_FIELDS
public static final java.lang.Object[] MASKED_FIELDS
If a bean property field name appears in this list, it will not be logged but replaced with "************" in the output.Put values here in lower case.
-
MASK
public static final java.lang.String MASK
- See Also:
- Constant Field Values
-
-
Method Detail
-
configure
public void configure(Engine engine, org.apache.commons.configuration2.Configuration configuration)
Wires up an Api at runtime by reflectively setting bean properties based on key/value configuration properties.- Parameters:
engine
- the engine to be configuredconfiguration
- the name/value pairs used to wire up the Api's that will be added toengine
.- See Also:
Engine.startup()
,Config
-
-


#include "linked_list.h"
#include "client.h"
#include "constants.h"
Go to the source code of this file.
◆ HpbClientsList
◆ HpbClientsListNode
◆ hpb_list_clients_add()
Adds an HpbClient to a HpbClientsList.
- Parameters
-
| list_cl | List in which the HpbClient should be added. |
| client_id | ID of the HpbClient to be added. |
- Returns
- Returns a pointer to the added HpbClient.
◆ hpb_list_clients_create()
Allocates space for a linked list of HpbClient elements.
- Returns
- Returns a pointer to the created linked list or NULL if the space could not be allocated.
◆ hpb_list_clients_destroy()
Deallocates the space previously allocated for a linked list of HpbClient elements.
- Parameters
-
| list_cl | Pointer to the pointer of the HpbClient linked list to be deallocated. |
◆ hpb_list_clients_find()
Finds a given client in a linked list.
- Parameters
-
| list_cl | List in which the HpbClient should be searched. |
| client_id | ID of the HpbClient to be searched. |
- Returns
- Returns a pointer to the HpbClient if the search is successful or NULL otherwise.
◆ hpb_list_clients_remove()
Removes an HpbClient from a HpbClientsList.
- Parameters
-
| list_cl | List from which the HpbClient should be removed. |
| client_id | ID of the HpbClient to be removed. |
- Returns
- Returns >=0 if the HpbClient was removed and <0 otherwise.


Hey guys! After a long battle and countless hours of work, I was finally able to complete my rails project. It took me sometime to do. I even had to re-create it just to gain a better perspective on rails. Rails is difficult at first because of all its “magic”, but once you get a deeper understanding of what’s going on in the backend it’ll click right away.
This is a pretty simple rails app. It’s a recipe app. The goal was just to allow users to create a recipe along with all of its ingredients. It also allows users to comment and rate on their own or other users recipes. There are some additional features that I will add later on to this app such as giving certain users roles using pundit, which is pretty much allowing and limiting users to deleting other users recipe, comments, ratings etc.
I’m going to explain my thought process with some of my code and try to explain it in the best techincal way I can. Again, I still don’t consider myself good at programming yet, but I just want to keep working on getting better as best I can.
Using Devise and Omniauth
When you start the application you’re sent to the home page. In order to start creating and seeing other users recipes you will need to register/login into an account. I used two authentications in this app, devise and omniauth.
The devise gem comes with a lot of neat features and it’s highly customizable. It takes care of so many different aspects for you such as controllers, views, mailers, errors, and routes. This is pretty much what a user will need to signin/register themselves with the app. Its a pretty popular gem to use and its pretty dependable.
The Omniauth gem is pretty cool too. Let me explain what it is. Ever go to a website and decide to register with them? When you start the registration it gives you an option to signin with google, twitter, Facebook, etc. Well, thats pretty much the omniauth gem. There are so many omniauth gems available to you but I choose to use facebook. Now users have the options of creating an account with their email or facebook account.
Structure
Now the most difficult part of this project is deciding the structure of your app. There are already guidelines and requirements Learn.co requires inorder for you pass this project. Now that we have the user models, controllers, and views set up, we can start creating how I want the app to function.
The user should be allowed to create a recipe. The recipe has many ingredients, comments, and rating. FYI I used a gem for the ratings, just wanted to add some pretty jQuery for the ratings. Now even though recipe has many ingredients, I also want the ingredient to have many recipes. For this task, I’ll need a ActiveRecord join table. The join table will be called recipe_ingredients.
Recipe model looks like this:
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
validates :name, :presence => true
validates :name, :uniqueness => true
end
Ingredient model looks like this:
class Ingredient < ActiveRecord::Base
has_many :recipe_ingredients
has_many :recipes, through: :recipe_ingredients
validates :name, :presence => true
validates_uniqueness_of :name
end
I went ahead and added some validations to both models just to avoid any dublicate names and make sure the user doesn’t leave any blank spaces in the forms.
This is what got me started and allowed me to complete this project. It’s a simple app. Feel free to use it. I will soon add some jQuery to the entire app for my next project. I had a lot of headaces and fun building this app and look forward to improving my programming skills.
Have Fun! Learn, Love, Code.


Design for the Web With enthusiasm and passion we develop your solution. Design and programming goes Hand in Hand.


--- layout: post title: Polymorphic enums in C#, generic incrementation date: 2012-10-09 11:41:25.000000000 +02:00 type: post published: true status: publish categories: - Programmation tags: - C# - enum - Puzzle meta: _edit_last: '1' _activeshortener: tiny _twitterrelated_short_url: http://tinyurl.com/9xludnl _twitterrelated_short_urlHash: a6514bf7fd1fb8a8b565cc52879c1fb2 sfw_pwd: E3Jh5diLUYzl author: login: pierre irrmann email<EMAIL_ADDRESS>display_name: Pierre Irrmann first_name: Pierre last_name: Irrmann ---
Consultez ici l'article précédent
During the implementation of my polymorphic enum, I have chosen to allow several types for the underlying “ordinal” value, as it is also possible for standard C# enums…
From the MSDN documentation, the allowed underlying types for enum types are the following (although other value types such as char are eligible, their use is not recommended) :
| Type | Size |
|---|---|
| sbyte | Signed 8-bit integer |
| byte | Unsigned 8-bit integer |
| short | Signed 16-bit integer |
| ushort | Unsigned 16-bit integer |
| int | Signed 32-bit integer |
| uint | Unsigned 32-bit integer |
| long | Signed 64-bit integer |
| ulong | Unsigned 64-bit integer |
In order to enable the ordinal parameter to be optional in the registration of enum values, I had to find a way to compute an automatic value. The rule I wanted to apply was very simple : if there is no value already register, use zero, else use the maximum value already registered, plus one. But how do you write such code without checking the type in an ugly fashion ?
Generic constraints are somehow limited : I can force the ordinal type to be a value type by using a “where T : struct” constraints, but there is no such thing as a “IPrimitiveNumericValue” interface !
Here is where I got to, using generics and lambdas…
public static class Incrementer { private static Func<T, T> GetFunc<T>(Func<T, T> f) { return f; } [...] |
I first define static class and a private static helper function that take a Func<T, T> and returns… the unmodified argument. This is just a hint for the compiler, because I’m going to use lambdas and as you might know, a lambda can either be converted to a delegate (code) or to an expression tree representing the lambda (data). Without any indication, the compiler can’t infer the expected type, so we have to help him…
Then, the class defines a static field and initialises it in its static constructor :
private static Dictionary<Type, object> incrementers; static Incrementer() { incrementers = new Dictionary<Type, object>(); incrementers.Add(typeof(sbyte), GetFunc<sbyte>(i => (sbyte)(i + 1))); incrementers.Add(typeof(byte), GetFunc<byte>(i => (byte)(i + 1))); incrementers.Add(typeof(short), GetFunc<short>(i => (short)(i + 1))); incrementers.Add(typeof(ushort), GetFunc<ushort>(i => (ushort)(i + 1))); incrementers.Add(typeof(int), GetFunc<int>(i => i + 1)); incrementers.Add(typeof(uint), GetFunc<uint>(i => i + 1)); incrementers.Add(typeof(long), GetFunc<long>(i => i + 1)); incrementers.Add(typeof(ulong), GetFunc<ulong>(i => i + 1)); } |
At this point, all the required incrementing functions are expressed as lambdas and registered in a dictionary.
The only method left to write is the PlusOne method :
public static T PlusOne<T>(this T value) where T : struct { object incrementer; if (!incrementers.TryGetValue(typeof(T), out incrementer)) throw new NotSupportedException( "This type is not supported."); return ((Func<T, T>)incrementer).Invoke(value); } |
Type checking and dictionary lookup. That’s it !


'Uncharted territory' as bushfires rage across Australia's east
by AFPSYDNEY: Dozens of bushfires raged out of control across eastern Australia on Friday, blocking escape routes for residents and shuttering the main highway linking major cities on the country’s Pacific coast.
More than 90 blazes pockmarked the New South Wales countryside, 50 of them uncontained, tearing through tens of thousands of hectares.
“We are in uncharted territory,” New South Wales Rural Fire Service Commissioner Shane Fitzsimmons told public broadcaster ABC. “We have never seen this many fires concurrently at emergency warning level.”
Authorities said fires had breached containment lines and forced the closure of the Pacific Highway linking Sydney and Brisbane in two places.
Emergency warnings were introduced for 14 flashpoints, bringing warnings to evacuate immediately.
In some areas, residents were told to simply “seek shelter as it is too late to leave”.
Local radio stopped normal programming and provided instructions about how to try to survive fires if trapped at home or in a vehicle.
A prolonged drought, strong winds, low humidity and high temperatures have conspired to make the landscape a tinderbox.
“It’s a very dynamic, volatile and dangerous set of circumstances,” said Fitzsimmons.
Bushfires are common in Australia, but the country is gearing up for busy bushfire season with record temperatures predicted for the summer months.


Source code for torch.nn.utils.parametrizations
from enum import Enum, auto
import torch
from torch import Tensor
from ..utils import parametrize
from ..modules import Module
from .. import functional as F
from typing import Optional
__all__ = ['orthogonal', 'spectral_norm', 'weight_norm']
def _is_orthogonal(Q, eps=None):
n, k = Q.size(-2), Q.size(-1)
Id = torch.eye(k, dtype=Q.dtype, device=Q.device)
# A reasonable eps, but not too large
eps = 10. * n * torch.finfo(Q.dtype).eps
return torch.allclose(Q.mH @ Q, Id, atol=eps)
def _make_orthogonal(A):
""" Assume that A is a tall matrix.
Compute the Q factor s.t. A = QR (A may be complex) and diag(R) is real and non-negative
"""
X, tau = torch.geqrf(A)
Q = torch.linalg.householder_product(X, tau)
# The diagonal of X is the diagonal of R (which is always real) so we normalise by its signs
Q *= X.diagonal(dim1=-2, dim2=-1).sgn().unsqueeze(-2)
return Q
class _OrthMaps(Enum):
matrix_exp = auto()
cayley = auto()
householder = auto()
class _Orthogonal(Module):
base: Tensor
def __init__(self,
weight,
orthogonal_map: _OrthMaps,
*,
use_trivialization=True) -> None:
super().__init__()
# Note [Householder complex]
# For complex tensors, it is not possible to compute the tensor `tau` necessary for
# linalg.householder_product from the reflectors.
# To see this, note that the reflectors have a shape like:
# 0 0 0
# * 0 0
# * * 0
# which, for complex matrices, give n(n-1) (real) parameters. Now, you need n^2 parameters
# to parametrize the unitary matrices. Saving tau on its own does not work either, because
# not every combination of `(A, tau)` gives a unitary matrix, meaning that if we optimise
# them as independent tensors we would not maintain the constraint
# An equivalent reasoning holds for rectangular matrices
if weight.is_complex() and orthogonal_map == _OrthMaps.householder:
raise ValueError("The householder parametrization does not support complex tensors.")
self.shape = weight.shape
self.orthogonal_map = orthogonal_map
if use_trivialization:
self.register_buffer("base", None)
def forward(self, X: torch.Tensor) -> torch.Tensor:
n, k = X.size(-2), X.size(-1)
transposed = n < k
if transposed:
X = X.mT
n, k = k, n
# Here n > k and X is a tall matrix
if self.orthogonal_map == _OrthMaps.matrix_exp or self.orthogonal_map == _OrthMaps.cayley:
# We just need n x k - k(k-1)/2 parameters
X = X.tril()
if n != k:
# Embed into a square matrix
X = torch.cat([X, X.new_zeros(n, n - k).expand(*X.shape[:-2], -1, -1)], dim=-1)
A = X - X.mH
# A is skew-symmetric (or skew-hermitian)
if self.orthogonal_map == _OrthMaps.matrix_exp:
Q = torch.matrix_exp(A)
elif self.orthogonal_map == _OrthMaps.cayley:
# Computes the Cayley retraction (I+A/2)(I-A/2)^{-1}
Id = torch.eye(n, dtype=A.dtype, device=A.device)
Q = torch.linalg.solve(torch.add(Id, A, alpha=-0.5), torch.add(Id, A, alpha=0.5))
# Q is now orthogonal (or unitary) of size (..., n, n)
if n != k:
Q = Q[..., :k]
# Q is now the size of the X (albeit perhaps transposed)
else:
# X is real here, as we do not support householder with complex numbers
A = X.tril(diagonal=-1)
tau = 2. / (1. + (A * A).sum(dim=-2))
Q = torch.linalg.householder_product(A, tau)
# The diagonal of X is 1's and -1's
# We do not want to differentiate through this or update the diagonal of X hence the casting
Q = Q * X.diagonal(dim1=-2, dim2=-1).int().unsqueeze(-2)
if hasattr(self, "base"):
Q = self.base @ Q
if transposed:
Q = Q.mT
return Q
@torch.autograd.no_grad()
def right_inverse(self, Q: torch.Tensor) -> torch.Tensor:
if Q.shape != self.shape:
raise ValueError(f"Expected a matrix or batch of matrices of shape {self.shape}. "
f"Got a tensor of shape {Q.shape}.")
Q_init = Q
n, k = Q.size(-2), Q.size(-1)
transpose = n < k
if transpose:
Q = Q.mT
n, k = k, n
# We always make sure to always copy Q in every path
if not hasattr(self, "base"):
# Note [right_inverse expm cayley]
# If we do not have use_trivialization=True, we just implement the inverse of the forward
# map for the Householder. To see why, think that for the Cayley map,
# we would need to find the matrix X \in R^{n x k} such that:
# Y = torch.cat([X.tril(), X.new_zeros(n, n - k).expand(*X.shape[:-2], -1, -1)], dim=-1)
# A = Y - Y.mH
# cayley(A)[:, :k]
# gives the original tensor. It is not clear how to do this.
# Perhaps via some algebraic manipulation involving the QR like that of
# Corollary 2.2 in Edelman, Arias and Smith?
if self.orthogonal_map == _OrthMaps.cayley or self.orthogonal_map == _OrthMaps.matrix_exp:
raise NotImplementedError("It is not possible to assign to the matrix exponential "
"or the Cayley parametrizations when use_trivialization=False.")
# If parametrization == _OrthMaps.householder, make Q orthogonal via the QR decomposition.
# Here Q is always real because we do not support householder and complex matrices.
# See note [Householder complex]
A, tau = torch.geqrf(Q)
# We want to have a decomposition X = QR with diag(R) > 0, as otherwise we could
# decompose an orthogonal matrix Q as Q = (-Q)@(-Id), which is a valid QR decomposition
# The diagonal of Q is the diagonal of R from the qr decomposition
A.diagonal(dim1=-2, dim2=-1).sign_()
# Equality with zero is ok because LAPACK returns exactly zero when it does not want
# to use a particular reflection
A.diagonal(dim1=-2, dim2=-1)[tau == 0.] *= -1
return A.mT if transpose else A
else:
if n == k:
# We check whether Q is orthogonal
if not _is_orthogonal(Q):
Q = _make_orthogonal(Q)
else: # Is orthogonal
Q = Q.clone()
else:
# Complete Q into a full n x n orthogonal matrix
N = torch.randn(*(Q.size()[:-2] + (n, n - k)), dtype=Q.dtype, device=Q.device)
Q = torch.cat([Q, N], dim=-1)
Q = _make_orthogonal(Q)
self.base = Q
# It is necessary to return the -Id, as we use the diagonal for the
# Householder parametrization. Using -Id makes:
# householder(torch.zeros(m,n)) == torch.eye(m,n)
# Poor man's version of eye_like
neg_Id = torch.zeros_like(Q_init)
neg_Id.diagonal(dim1=-2, dim2=-1).fill_(-1.)
return neg_Id
[docs]def orthogonal(module: Module,
name: str = 'weight',
orthogonal_map: Optional[str] = None,
*,
use_trivialization: bool = True) -> Module:
r"""Applies an orthogonal or unitary parametrization to a matrix or a batch of matrices.
Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`, the parametrized
matrix :math:`Q \in \mathbb{K}^{m \times n}` is **orthogonal** as
.. math::
\begin{align*}
Q^{\text{H}}Q &= \mathrm{I}_n \mathrlap{\qquad \text{if }m \geq n}\\
QQ^{\text{H}} &= \mathrm{I}_m \mathrlap{\qquad \text{if }m < n}
\end{align*}
where :math:`Q^{\text{H}}` is the conjugate transpose when :math:`Q` is complex
and the transpose when :math:`Q` is real-valued, and
:math:`\mathrm{I}_n` is the `n`-dimensional identity matrix.
In plain words, :math:`Q` will have orthonormal columns whenever :math:`m \geq n`
and orthonormal rows otherwise.
If the tensor has more than two dimensions, we consider it as a batch of matrices of shape `(..., m, n)`.
The matrix :math:`Q` may be parametrized via three different ``orthogonal_map`` in terms of the original tensor:
- ``"matrix_exp"``/``"cayley"``:
the :func:`~torch.matrix_exp` :math:`Q = \exp(A)` and the `Cayley map`_
:math:`Q = (\mathrm{I}_n + A/2)(\mathrm{I}_n - A/2)^{-1}` are applied to a skew-symmetric
:math:`A` to give an orthogonal matrix.
- ``"householder"``: computes a product of Householder reflectors
(:func:`~torch.linalg.householder_product`).
``"matrix_exp"``/``"cayley"`` often make the parametrized weight converge faster than
``"householder"``, but they are slower to compute for very thin or very wide matrices.
If ``use_trivialization=True`` (default), the parametrization implements the "Dynamic Trivialization Framework",
where an extra matrix :math:`B \in \mathbb{K}^{n \times n}` is stored under
``module.parametrizations.weight[0].base``. This helps the
convergence of the parametrized layer at the expense of some extra memory use.
See `Trivializations for Gradient-Based Optimization on Manifolds`_ .
Initial value of :math:`Q`:
If the original tensor is not parametrized and ``use_trivialization=True`` (default), the initial value
of :math:`Q` is that of the original tensor if it is orthogonal (or unitary in the complex case)
and it is orthogonalized via the QR decomposition otherwise (see :func:`torch.linalg.qr`).
Same happens when it is not parametrized and ``orthogonal_map="householder"`` even when ``use_trivialization=False``.
Otherwise, the initial value is the result of the composition of all the registered
parametrizations applied to the original tensor.
.. note::
This function is implemented using the parametrization functionality
in :func:`~torch.nn.utils.parametrize.register_parametrization`.
.. _`Cayley map`: https://en.wikipedia.org/wiki/Cayley_transform#Matrix_map
.. _`Trivializations for Gradient-Based Optimization on Manifolds`: https://arxiv.org/abs/1909.09501
Args:
module (nn.Module): module on which to register the parametrization.
name (str, optional): name of the tensor to make orthogonal. Default: ``"weight"``.
orthogonal_map (str, optional): One of the following: ``"matrix_exp"``, ``"cayley"``, ``"householder"``.
Default: ``"matrix_exp"`` if the matrix is square or complex, ``"householder"`` otherwise.
use_trivialization (bool, optional): whether to use the dynamic trivialization framework.
Default: ``True``.
Returns:
The original module with an orthogonal parametrization registered to the specified
weight
Example::
>>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_LAPACK)
>>> orth_linear = orthogonal(nn.Linear(20, 40))
>>> orth_linear
ParametrizedLinear(
in_features=20, out_features=40, bias=True
(parametrizations): ModuleDict(
(weight): ParametrizationList(
(0): _Orthogonal()
)
)
)
>>> # xdoctest: +IGNORE_WANT
>>> Q = orth_linear.weight
>>> torch.dist(Q.T @ Q, torch.eye(20))
tensor(4.9332e-07)
"""
weight = getattr(module, name, None)
if not isinstance(weight, Tensor):
raise ValueError(
f"Module '{module}' has no parameter or buffer with name '{name}'"
)
# We could implement this for 1-dim tensors as the maps on the sphere
# but I believe it'd bite more people than it'd help
if weight.ndim < 2:
raise ValueError("Expected a matrix or batch of matrices. "
f"Got a tensor of {weight.ndim} dimensions.")
if orthogonal_map is None:
orthogonal_map = "matrix_exp" if weight.size(-2) == weight.size(-1) or weight.is_complex() else "householder"
orth_enum = getattr(_OrthMaps, orthogonal_map, None)
if orth_enum is None:
raise ValueError('orthogonal_map has to be one of "matrix_exp", "cayley", "householder". '
f'Got: {orthogonal_map}')
orth = _Orthogonal(weight,
orth_enum,
use_trivialization=use_trivialization)
parametrize.register_parametrization(module, name, orth, unsafe=True)
return module
class _WeightNorm(Module):
def __init__(
self,
dim: Optional[int] = 0,
) -> None:
super().__init__()
if dim is None:
dim = -1
self.dim = dim
def forward(self, weight_g, weight_v):
return torch._weight_norm(weight_v, weight_g, self.dim)
def right_inverse(self, weight):
weight_g = torch.norm_except_dim(weight, 2, self.dim)
weight_v = weight
return weight_g, weight_v
def weight_norm(module: Module, name: str = 'weight', dim: int = 0):
r"""Applies weight normalization to a parameter in the given module.
.. math::
\mathbf{w} = g \dfrac{\mathbf{v}}{\|\mathbf{v}\|}
Weight normalization is a reparameterization that decouples the magnitude
of a weight tensor from its direction. This replaces the parameter specified
by :attr:`name` with two parameters: one specifying the magnitude
and one specifying the direction.
By default, with ``dim=0``, the norm is computed independently per output
channel/plane. To compute a norm over the entire weight tensor, use
``dim=None``.
See https://arxiv.org/abs/1602.07868
Args:
module (Module): containing module
name (str, optional): name of weight parameter
dim (int, optional): dimension over which to compute the norm
Returns:
The original module with the weight norm hook
Example::
>>> m = weight_norm(nn.Linear(20, 40), name='weight')
>>> m
ParametrizedLinear(
in_features=20, out_features=40, bias=True
(parametrizations): ModuleDict(
(weight): ParametrizationList(
(0): _WeightNorm()
)
)
)
>>> m.parametrizations.weight.original0.size()
torch.Size([40, 1])
>>> m.parametrizations.weight.original1.size()
torch.Size([40, 20])
"""
_weight_norm = _WeightNorm(dim)
parametrize.register_parametrization(module, name, _weight_norm, unsafe=True)
def _weight_norm_compat_hook(state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs):
g_key = f"{prefix}{name}_g"
v_key = f"{prefix}{name}_v"
if g_key in state_dict and v_key in state_dict:
original0 = state_dict.pop(g_key)
original1 = state_dict.pop(v_key)
state_dict[f"{prefix}parametrizations.{name}.original0"] = original0
state_dict[f"{prefix}parametrizations.{name}.original1"] = original1
module._register_load_state_dict_pre_hook(_weight_norm_compat_hook)
return module
class _SpectralNorm(Module):
def __init__(
self,
weight: torch.Tensor,
n_power_iterations: int = 1,
dim: int = 0,
eps: float = 1e-12
) -> None:
super().__init__()
ndim = weight.ndim
if dim >= ndim or dim < -ndim:
raise IndexError("Dimension out of range (expected to be in range of "
f"[-{ndim}, {ndim - 1}] but got {dim})")
if n_power_iterations <= 0:
raise ValueError('Expected n_power_iterations to be positive, but '
'got n_power_iterations={}'.format(n_power_iterations))
self.dim = dim if dim >= 0 else dim + ndim
self.eps = eps
if ndim > 1:
# For ndim == 1 we do not need to approximate anything (see _SpectralNorm.forward)
self.n_power_iterations = n_power_iterations
weight_mat = self._reshape_weight_to_matrix(weight)
h, w = weight_mat.size()
u = weight_mat.new_empty(h).normal_(0, 1)
v = weight_mat.new_empty(w).normal_(0, 1)
self.register_buffer('_u', F.normalize(u, dim=0, eps=self.eps))
self.register_buffer('_v', F.normalize(v, dim=0, eps=self.eps))
# Start with u, v initialized to some reasonable values by performing a number
# of iterations of the power method
self._power_method(weight_mat, 15)
def _reshape_weight_to_matrix(self, weight: torch.Tensor) -> torch.Tensor:
# Precondition
assert weight.ndim > 1
if self.dim != 0:
# permute dim to front
weight = weight.permute(self.dim, *(d for d in range(weight.dim()) if d != self.dim))
return weight.flatten(1)
@torch.autograd.no_grad()
def _power_method(self, weight_mat: torch.Tensor, n_power_iterations: int) -> None:
# See original note at torch/nn/utils/spectral_norm.py
# NB: If `do_power_iteration` is set, the `u` and `v` vectors are
# updated in power iteration **in-place**. This is very important
# because in `DataParallel` forward, the vectors (being buffers) are
# broadcast from the parallelized module to each module replica,
# which is a new module object created on the fly. And each replica
# runs its own spectral norm power iteration. So simply assigning
# the updated vectors to the module this function runs on will cause
# the update to be lost forever. And the next time the parallelized
# module is replicated, the same randomly initialized vectors are
# broadcast and used!
#
# Therefore, to make the change propagate back, we rely on two
# important behaviors (also enforced via tests):
# 1. `DataParallel` doesn't clone storage if the broadcast tensor
# is already on correct device; and it makes sure that the
# parallelized module is already on `device[0]`.
# 2. If the out tensor in `out=` kwarg has correct shape, it will
# just fill in the values.
# Therefore, since the same power iteration is performed on all
# devices, simply updating the tensors in-place will make sure that
# the module replica on `device[0]` will update the _u vector on the
# parallelized module (by shared storage).
#
# However, after we update `u` and `v` in-place, we need to **clone**
# them before using them to normalize the weight. This is to support
# backproping through two forward passes, e.g., the common pattern in
# GAN training: loss = D(real) - D(fake). Otherwise, engine will
# complain that variables needed to do backward for the first forward
# (i.e., the `u` and `v` vectors) are changed in the second forward.
# Precondition
assert weight_mat.ndim > 1
for _ in range(n_power_iterations):
# Spectral norm of weight equals to `u^T W v`, where `u` and `v`
# are the first left and right singular vectors.
# This power iteration produces approximations of `u` and `v`.
self._u = F.normalize(torch.mv(weight_mat, self._v), # type: ignore[has-type]
dim=0, eps=self.eps, out=self._u) # type: ignore[has-type]
self._v = F.normalize(torch.mv(weight_mat.t(), self._u),
dim=0, eps=self.eps, out=self._v) # type: ignore[has-type]
def forward(self, weight: torch.Tensor) -> torch.Tensor:
if weight.ndim == 1:
# Faster and more exact path, no need to approximate anything
return F.normalize(weight, dim=0, eps=self.eps)
else:
weight_mat = self._reshape_weight_to_matrix(weight)
if self.training:
self._power_method(weight_mat, self.n_power_iterations)
# See above on why we need to clone
u = self._u.clone(memory_format=torch.contiguous_format)
v = self._v.clone(memory_format=torch.contiguous_format)
# The proper way of computing this should be through F.bilinear, but
# it seems to have some efficiency issues:
# https://github.com/pytorch/pytorch/issues/58093
sigma = torch.dot(u, torch.mv(weight_mat, v))
return weight / sigma
def right_inverse(self, value: torch.Tensor) -> torch.Tensor:
# we may want to assert here that the passed value already
# satisfies constraints
return value
[docs]def spectral_norm(module: Module,
name: str = 'weight',
n_power_iterations: int = 1,
eps: float = 1e-12,
dim: Optional[int] = None) -> Module:
r"""Applies spectral normalization to a parameter in the given module.
.. math::
\mathbf{W}_{SN} = \dfrac{\mathbf{W}}{\sigma(\mathbf{W})},
\sigma(\mathbf{W}) = \max_{\mathbf{h}: \mathbf{h} \ne 0} \dfrac{\|\mathbf{W} \mathbf{h}\|_2}{\|\mathbf{h}\|_2}
When applied on a vector, it simplifies to
.. math::
\mathbf{x}_{SN} = \dfrac{\mathbf{x}}{\|\mathbf{x}\|_2}
Spectral normalization stabilizes the training of discriminators (critics)
in Generative Adversarial Networks (GANs) by reducing the Lipschitz constant
of the model. :math:`\sigma` is approximated performing one iteration of the
`power method`_ every time the weight is accessed. If the dimension of the
weight tensor is greater than 2, it is reshaped to 2D in power iteration
method to get spectral norm.
See `Spectral Normalization for Generative Adversarial Networks`_ .
.. _`power method`: https://en.wikipedia.org/wiki/Power_iteration
.. _`Spectral Normalization for Generative Adversarial Networks`: https://arxiv.org/abs/1802.05957
.. note::
This function is implemented using the parametrization functionality
in :func:`~torch.nn.utils.parametrize.register_parametrization`. It is a
reimplementation of :func:`torch.nn.utils.spectral_norm`.
.. note::
When this constraint is registered, the singular vectors associated to the largest
singular value are estimated rather than sampled at random. These are then updated
performing :attr:`n_power_iterations` of the `power method`_ whenever the tensor
is accessed with the module on `training` mode.
.. note::
If the `_SpectralNorm` module, i.e., `module.parametrization.weight[idx]`,
is in training mode on removal, it will perform another power iteration.
If you'd like to avoid this iteration, set the module to eval mode
before its removal.
Args:
module (nn.Module): containing module
name (str, optional): name of weight parameter. Default: ``"weight"``.
n_power_iterations (int, optional): number of power iterations to
calculate spectral norm. Default: ``1``.
eps (float, optional): epsilon for numerical stability in
calculating norms. Default: ``1e-12``.
dim (int, optional): dimension corresponding to number of outputs.
Default: ``0``, except for modules that are instances of
ConvTranspose{1,2,3}d, when it is ``1``
Returns:
The original module with a new parametrization registered to the specified
weight
Example::
>>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_LAPACK)
>>> # xdoctest: +IGNORE_WANT("non-deterministic")
>>> snm = spectral_norm(nn.Linear(20, 40))
>>> snm
ParametrizedLinear(
in_features=20, out_features=40, bias=True
(parametrizations): ModuleDict(
(weight): ParametrizationList(
(0): _SpectralNorm()
)
)
)
>>> torch.linalg.matrix_norm(snm.weight, 2)
tensor(1.0081, grad_fn=<AmaxBackward0>)
"""
weight = getattr(module, name, None)
if not isinstance(weight, Tensor):
raise ValueError(
f"Module '{module}' has no parameter or buffer with name '{name}'"
)
if dim is None:
if isinstance(module, (torch.nn.ConvTranspose1d,
torch.nn.ConvTranspose2d,
torch.nn.ConvTranspose3d)):
dim = 1
else:
dim = 0
parametrize.register_parametrization(module, name, _SpectralNorm(weight, n_power_iterations, dim, eps))
return module


--- tags: - geoscience - landslide author: display_name: ZB email<EMAIL_ADDRESS>date: 2011-11-18 16:09:38 -0700 categories: [] InventoryPolygons: hub: name: Utah Landslide Inventory Polygons item_id: 3be19aad83a940cfa7bb331b5fbc28c6 updates: - 2018 InventoryMappedAreas: hub: name: Utah Landslide Inventory Mapped Areas item_id: e0ec1e7d0d5c47e388cc86e89928fe92 updates: - 2018 CompilationAreas: hub: name: Utah Landslide Compilation Polygons item_id: 4698550fd2aa4029bc295f7e0051780e updates: - 2016 CompilationDebrisFlowPaths: hub: name: Utah Landslide Compilation Debris Flow Paths item_id: cda61391c65a4d4aa94a581f6bf57057 updates: - 2016 CompilationScarps: hub: name: Utah Landslide Compilation Scarps item_id: e22096dacc604d5eb8b2e3c5e21f0a58 updates: - 2016 --- {% include abstract.html name="Landslides and Debris Flows" stewards="UGS" abstract="Landslide debris flow paths, deposition areas, and scarps of Utah. Data represents a compilation of existing mapping of landslides at 1:100,000 pre 2007, and new landslide specific data depicting a more detailed inventory at 1:24,000 post 2008. For specific details on each feature class see the included metadata. More detailed information on landslide hazards in Utah is available from the UGS." %}
Landslide Inventory Polygons depicts landslide activity and debris flows at scales of 1:24,000 or better and were captured using LiDAR, stereo aerial photography, other data, and field reconnaissance by the UGS. Landslide Inventory Polygons represents the most recent landslide mapping efforts of the UGS, and when possible should be used first.
{% include contact.html subject=page.title contact=site.data.contacts.landslides %}
Landslide Inventory Mapped Areas is a reference layer displaying the extent of higher resolution Landslide Inventory Polygon mapping efforts.
{% include contact.html subject=page.title contact=site.data.contacts.landslides %}
Landslide depositions throughout Utah at a variety of scales and accuracies. This dataset represents a compilation of digitizing efforts by the Utah Geological Survey (UGS), and is not new landslide-specific mapping. Landslides were compiled from all known pre-1989 published and unpublished references available at the time, additional landslide paths were later added from 1989-2007 geologic maps and UGS landslide investigations.
{% include contact.html subject=page.title contact=site.data.contacts.landslides %}
Landslide Compilation Debris Flow Paths represents debris flow paths throughout Utah at a variety of scales and accuracies. Data was compiled by the UGRC and UGS from all known pre-1989 published and unpublished references available at the time. Additional landslide paths were later added from 1989-2007 geologic maps and UGS landslide investigations.
{% include contact.html subject=page.title contact=site.data.contacts.landslides %}
Landslide scarp information of Utah compiled by the Utah Geological Survey (UGS). Data was compiled by the UGRC and UGS from all known pre-1989 published and unpublished references available at the time. Additional landslide paths were later added from 1989-2007 geologic maps and UGS landslide investigations.
{% include contact.html subject=page.title contact=site.data.contacts.landslides %}


Please ensure that LocalTest is running on port 5101
> cd src/development/LocalTest > dotnet run
Alternaltivly you can run localtest in docker with the localtest profile
> cd src/development > docker compose --profile localtest up --build


{{obj.name}}
Click on event to edit the function
or
Select a product to update event flow
[X] {{obj.name}}


Staples Team Supervisor/Software Engineering Graduate of @flatiron-school
Published Nov 01, 2019
Sinatra is a DSL (Domain Specific Language) in Ruby that can be used to simplify the process of creating web applications, cutting down on the time it takes to get the general base of a web app set up and take care of the more repetitive tasks. Sinatra is a more lightweight and flexible Web Application Framework than some others WAF’s such as Rails, giving the developer just the bare minimum so its a perfect way for new developers to get a good feel for how things are actually working under the hood of more advanced frameworks like Rails.
We will be setting up a simple todo web app that uses active record and Sinatra to allow users to create, edit, update and delete tasks. We will also create a user model to allow users to login and out plus create new users. The main models here will be tasks and users and we will use Active Record Associations to create the relationships between the models.
To facilitate the creation of our file structure and to get the project started we will be using a gem called Corneal. Corneal is defined as “A Ruby gem that is a Sinatra app generator with Rails-like simplicity. I built this to help fellow Flatiron School students with their Sinatra assessments” and is built by a fellow Flatiron student to ease the tedious setup part. Make sure to familiarize yourself with the files and setup that we get from Corneal as it will help your understanding later on.
##### Requirements
### Creating your project directory
Setting up your application with Corneal is as easy as corneal new APP-NAME
. Of couse your would replace ‘APP-NAME’ with your apps name so in this case we would run corneal new todo-app
, while you can always change your apps name later on be aware that corneal will be inserting the app name given in multiple files so all will need to edited if you do change the app name. This will give you the following file structure.
### Initialize git
Next you should initialize and commit to git by running git init
and then git add .
to stage all the files and finally git commit -m "Add initial project creating files with Corneal"
to commit the changes and include a descriptive message. No we are ready to start planning how we want the app to work.
### App planning
Just to make your life easier and help others who may want to contribute to the project I created a outline.md
file to list out the features and plan the flow of the application so that I can better organize my thoughts and refer to this I code.
To start off I wanted to get the main features of the project working, kind of like a minimum viable product, basically the bare bones for our app. We want to be able to
After we that part is complete we want to add the following features as well.
Finally if we have the time will can also add the following features.
Now that we have our basic outline we can started on actually coding. We already know what are going to need a User table and and a Tasks table to store our data so that our app is persistent. Before anything else make sure to run bundle install
to install the required gems from our Gemfile, if the Gemfile.lock is cause a error then just delete it run bundle again. To create our tables we can either use the gem Rake
or Corneal
to help us create migrations, following convention you should make the name of the migration descriptive of what you are doing.
Corneal streamlines the process a little bit for us if we want, knowing we will need both user and task models we can run corneal model user
and corneal model task
which will create the migration file for use automatically as well as our model files. Its important your use the name of the model in its singular form because corneal with make the migrations plural as displayed in the picture below.
So using Rake
to start creating our users table we can do something like this rake db:migrate NAME=create_users
which will add a file called XXXXXX_create_users.rb
inside of the folder db/migrate/
for us, the XXXXXX
part will be a time stamp so rake knows which migrations to run first. Within that file there is a change method already set up for us to use where we would put the following code
def change
create_table :users do |t|
t.string :username
t.string :email
t.integer :password_digest
end
Note the :password_digest
part because we are going to use BCrypt with active record to make secure password authentication and storage. The documentation calls for a attribute XXX_digest
where XXX
is the desired name of the attribute, but you need to have the _digest
for it to work properly.
Next we create the tasks migration by running rake db:create_migration NAME=create_tasks
and put the following code inside the file.
def change
create_table :tasks do |t|
t.string :title
t.text :description
t.boolean :complete, default: false
t.integer :user_id
end
end
This gives our tasks a title, description and completion attributes as well as a :user_id
attribute to store the id of the user that created the task. Now we can create our models and associations.
This is where I really love active record for its simplicity and power, we are going to create a file called user.rb
and task.rb
within the directory app/models/
where the associations will go. This what our file structure should look like now.
Inside of the app/models/user.rb
file we will make our association of users having many tasks like this.
class User < ActiveRecord::Base
has_secure_password
has_many :tasks
validates :username, :email, uniqueness: true
end
Notice the validates
part we have to set the email and username attributes to be unique so that we can’t end up with duplicate usernames and if a user has already signed up with a email we want to alert them of this, active record will ensure that these constraints are met and all we had to do was add two lines of code. Also we need to include has_secure_password
for our secure password setup to function correctly.
Inside of tasks looks like this.
class Task < ActiveRecord::Base
belongs_to :user
validates :title, presence: true
end
This indicates that each task belongs to a single user and validates that we must create a task with a title.
Now we are on the controller files for the application, these files are found in the app/controllers/
folder and container most of the logic for the routes we want to use. Naming convention is to use the name of the model the controller is for then _controller
so in this case we would want to have a app/controllers/users_controller.rb
and a app/controllers/tasks_controller.rb
in addition the the main applicaiton_controller created by Corneal. Again the Corneal app can facilitate the process for use and carry our a number of steps. By running corneal controller tasks
the gem will do the following
use UsersController
in the file config.ru
so we have access to the code in the new filesDo the same thing for users corneal controller users
.
Now we can start the actual coding for the logic of the app. Try to keep the routes that are related to the views within their respective controllers so dont put the /tasks
route in the users_controller.rb
. We want to have the ability to view all tasks, create, edit, update, and delete tasks so we want the following routes to render the corresponding views.
GET /tasks index
GET /tasks/:id show
GET /tasks/new new
GET /tasks/:id/edit edit
PATCH /tasks/:id update
POST /tasks create
DELETE /tasks/:id destroy
Create routes and views for each of the actions listed above for both tasks and users.
To make cookies work and be able to keep track of user sessions we need to add a few lines of code in two files. The first thing we need to do is add the line use Rack::Session::Cookie
to the file config.ru
and then add
enable :sessions
set :session_secret, {ENV['SESSION_SECRET']} {SecureRandom.hex(64)}
The session_secret is looking for a environment variable called SESSION_SECRET
so we can either set that using the following line SESSION_SECRET=$(ruby -e "require 'securerandom'; puts SecureRandom.hex(64)")
or just generate a new secret everytime the app starts up but doing it that way will invalidate any pre-existing sessions.
So at this point we have created a foundation for our to do task application and can start on the actual application routes, features and interfaces that will make the program do what we laid out in the outline.md
file and part 2 will cover the implementation of the models and views to complete the program.


×
HOME
ABOUT
PROJECT
BLOG
CONTACT
☰
CSS Grids Gallery
Gender Base Violence
Gallery Slideshow
SIKI'S WEBSITE
FOUNTAIN OF HOPE WEBSITE


The sites listed on this page ranges from calming sites and breathing regulation to sites designed to teach you more about decreasing your anxiety, and increasing your level of happiness.
"Yoga with Adriene" is a channel dedicated to providing people with free instructional yoga videos. Consider browsing her channel for videos focused on specific things you would like to improve, and even different types of pain you may be experiencing, in order to improve your stress levels!
The focus of this site is mindfulness as practiced in mindfulness-based stress reduction (MBSR), mindfulness-based cognitive therapy (MBCT) and other closely related approaches.
The mission of the Mindful Awareness Research Center (MARC) is to disseminate mindful awareness across the lifespan through education and research.
Tamara Levitt guides this 10 minute Daily Calm mindfulness meditation to powerfully restore and re-connect with the present.
Rest and relaxation. It's such a common expression that it has become a cliche. And although rest really can be relaxing, the pat phrase causes many men to overlook the fact that exercise can also be relaxing.


Mike Ashley demands landlords link rent to sales
by Jessica ClarkRetail tycoon Mike Ashley, the founder of Sports Direct, has demanded that new rent deals are tied to sales across his high street empire.
Ashley has reportedly asked landlords to agree to turnover rents, where up to 15 per cent of the rent payable is linked to in-store sales.
Read more: Sports Direct ends two month wait for new auditor, appointing RSM
The leasing structure allows struggling retailers to share some of the risk – and reward – of operating from the premises with its landlord. It was reported in June that H&M demanded that landlord accept turnover-based rents for lease renewals and new stores.
The retail billionaire, whose portfolio also includes House of Fraser and Flannels, has more than 700 stores across the UK.
He has previously hit out at “greedy” landlords and said they should do more to save the UK high street.
Ashley’s demand to landlords, reported by the Sunday Times, comes as struggling retailers attempt to stay afloat in the increasingly challenging high street environment.
Read more: Sports Direct calls for probe into Nike and Adidas
A number of retailers have decided to pursue company voluntary arrangements over the past few months, including Sir Philip Green’s Arcadia, which owns Topshop and Dorothy Perkins, Monsoon Accessorize and card shop Clintons.
Property companies have been adversely affected by the string of restructuring agreements. British Land last week wrote down the value of its retail portfolio by 10.7 per cent, while Landsec swung to a pre-tax loss of £147m.


Tendency indicators
40$
Average purchasse
30%
Aborted
25480$
Monthly sales
80%
Satisfaction
Average purchasse
Aborted
Monthly sales
Satisfaction
entertainement
High tech
Clothes


n = days, sets, shots
career percentage:
Free Throw Percentage by Day
Free Throw Percentage by Set of 50


There are no new orders
Order
Accept
Decline
There are no proccessing orders
Order
Date
Complete
There are no cancelled orders
Order
Date
Status
There are no completed orders
Order
Date
Status


Week 1 Objectives
These are the concepts in the Week 1 Worksheet:
Bash Profile
- [ ] Export environmental variables to make them always available when they open a terminal shell.
- [ ] Add a file to the $PATH environmental variable.
- [ ] Change the terminal prompt
- [ ] Create an alias **** Upload a small screenshot to prove you’ve changed the terminal and added 1 alias
Vim
- [ ] Open up a file in the Vim editor
- [ ] Navigate around within a file
- [ ] Make basic changes
- [ ] Save changes made to a file
- [ ] Exit the editor (with or without saving changes)
- [ ] Understand the difference between insert and command mode, and how to switch between them.
- [ ] Understand some of the basic structure of how editing commands work
- [ ] Use the help feature to learn more
Professionalism
- [ ] Understand what is meant by “professionalism”
- [ ] Understand why professionalism is important both at Techtonica and in a work setting
- [ ] Understand what behaviors are expected of a professional
- [ ] Understand what accepted standards of professionalism are
Learning How to Learn
- [ ] Their own learning style(s)
- [ ] How to fix new information in their minds What the Growth Mindset is and how to practice it
Operating systems
- [ ] Which two things does the operating system interact with?
- [ ] Describe the managers used by the OS to carry out tasks.
- [ ] Which OS are you using right now? Name two other popular operating systems.
Asking Good Questions
- [ ] How software engineers learn on the job
- [ ] What resources are available to software engineers for getting “unstuck”
- [ ] How software engineers ask questions when they need help
Networking
- [ ] Comfortably meet new people and start conversations, online and in-person, even as introverts
- [ ] Connect with people after meeting
- [ ] Ask for what you need
- [ ] Nurture and build your network
How the Internet Works
- [ ] How are the devices on the internet physically connected to each other?
- [ ] How is information physically transmitted from device to device?
- [ ] How does one device find another it’s trying to communicate with?
- [ ] What methods do devices on the internet use to communicate?
- [ ] How can we send data reliably even if the network is unreliable?


--- layout: page title: Happy & Healthy description: Discovering happiness and health through behavior change. ---
I have spent my career helping people reach their health, fitness and performance goals. Here’s a list of a few of the goals I have helped clients achieve:
These are a few among many challenges and goals that people have come searching for support. They sometimes come with hope and enthusiasm. There are other times that they come in desperation and with doubt.
When you look at the list of outcomes these individuals have achieved, it may seem like they are only loosely connected. However, I would argue that all of these outcomes have one major component in common. That commonality is the most critical component in any of the programs. That component is that each of these individuals had to develop new habits, start new behaviors and recreate a lifestyle that enabled them to be successful.
When you want to be a happier and healthier person, it requires some change of your current habits and behaviors.
The difficulty in wanting to develop a new lifestyle is the process of consistently implementing the required behaviors. It is rarely a lack of knowledge that limits someone’s success. This program is not designed to simply educate you on the strategies you need to be happier and healthier. This program is about taking action. This means taking action every single day. It starts with things that are small and simple, then builds upon your success to ultimately result in the outcome that you might think is unrealistic today.
There are many different actions and strategies that you can take to start making changes in your behavior. This often leaves people overwhelmed and confused. Which strategy is the right strategy. When should each strategy be implemented?
Over the last fifteen years, I have been studying, learning and testing different ways that we can use technology to help individuals through this process. And while I am an enthusiast and evangelist for the potential technology offers us to improve our odds of success, I often see people get consumed choosing the right technology that they forget to focus on making real progress.
This program is designed to remove all the guess work out of your program. It was designed to share strategies in the order that I would introduce them to a client, with the most important strategies first. It is also centered around taking action, opposed to learning and planning. I’ve done all of that work for you. Your challenge is to implement the program. The program is also very lite on the use of technology. While there will be some places that you can utilize different apps and gadgets to support your goals, this program can be completed with nothing more than a $0.50 notebook, used to log your progress and complete the exercises.
I wanted to create this program so someone who has a desire to make a change in their life, had a script to follow that walked them through the process. If implemented, I believe it will lead you to more happiness and greater health. I also wanted to offer the program as an online resource, for free. That way there are no financial barriers to getting started. It simply requires a desire for change and a commitment to follow the program.
I am developing this program using process similar to the way a software developer creates new software. The program is ready for use today, however it will be updated over time. It will include more stories, examples and activities. If you would like to subscribe to receive those updates.


🌞Solcast Power Forecast for Slack🌞
Email support
<EMAIL_ADDRESS>This application is distributed as is and is Open Source.
Built by
@siliconrob
GitHub Project Code:
github/Siliconrob/solcast-slack


public interface ObservableIntegerArray extends ObservableArray<ObservableIntegerArray>
ObservableIntegerArray
is a int[]
array that allows listeners
to track changes when they occur. In order to track changes, the internal
array is encapsulated and there is no direct access available from the outside.
Bulk operations are supported but they always do a copy of the data range.ArrayChangeListener
| Modifier and Type | Method and Description |
|---|---|
void |
addAll(int... elements)
Appends given
elements to the end of this array. |
void |
addAll(int[] src,
int srcIndex,
int length)
Appends a portion of given array to the end of this array.
|
void |
addAll(ObservableIntegerArray src)
Appends content of a given observable array to the end of this array.
|
void |
addAll(ObservableIntegerArray src,
int srcIndex,
int length)
Appends a portion of given observable array to the end of this array.
|
void |
copyTo(int srcIndex,
int[] dest,
int destIndex,
int length)
Copies specified portion of array into
dest array. |
void |
copyTo(int srcIndex,
ObservableIntegerArray dest,
int destIndex,
int length)
Copies specified portion of array into
dest observable array. |
int |
get(int index)
Gets a single value of array.
|
void |
set(int index,
int value)
Sets a single value in the array.
|
void |
set(int destIndex,
int[] src,
int srcIndex,
int length)
Copies a portion of specified array into this observable array.
|
void |
set(int destIndex,
ObservableIntegerArray src,
int srcIndex,
int length)
Copies a portion of specified observable array into this observable array.
|
void |
setAll(int... elements)
Replaces this observable array content with given elements.
|
void |
setAll(int[] src,
int srcIndex,
int length)
Replaces this observable array content with a copy of portion of
a given array.
|
void |
setAll(ObservableIntegerArray src)
Replaces this observable array content with a copy of given observable array.
|
void |
setAll(ObservableIntegerArray src,
int srcIndex,
int length)
Replaces this observable array content with a portion of a given
observable array.
|
int[] |
toArray(int[] dest)
Returns an array containing copy of the observable array.
|
int[] |
toArray(int srcIndex,
int[] dest,
int length)
Returns an array containing copy of specified portion of the observable array.
|
addListener, clear, ensureCapacity, removeListener, resize, size, trimToSize
addListener, removeListener
void copyTo(int srcIndex, int[] dest, int destIndex, int length)
dest
array. Throws
the same exceptions as System.arraycopy()
method.srcIndex
- starting position in the observable arraydest
- destination arraydestIndex
- starting position in destination arraylength
- length of portion to copyvoid copyTo(int srcIndex, ObservableIntegerArray dest, int destIndex, int length)
dest
observable array.
Throws the same exceptions as System.arraycopy()
method.srcIndex
- starting position in the observable arraydest
- destination observable arraydestIndex
- starting position in destination observable arraylength
- length of portion to copyint get(int index)
index
- index of element to getArrayIndexOutOfBoundsException
- if index
is outside
array boundsvoid addAll(int... elements)
elements
to the end of this array. Capacity is increased
if necessary to match the new size of the data.elements
- elements to appendvoid addAll(ObservableIntegerArray src)
src
- observable array with elements to appendvoid addAll(int[] src, int srcIndex, int length)
src
- source arraysrcIndex
- starting position in source arraylength
- length of portion to appendvoid addAll(ObservableIntegerArray src, int srcIndex, int length)
src
- source observable arraysrcIndex
- starting position in source arraylength
- length of portion to appendvoid setAll(int... elements)
elements
- elements to put into array contentNullPointerException
- if src
is nullvoid setAll(int[] src, int srcIndex, int length)
src
- source array to copy.srcIndex
- starting position in source observable arraylength
- length of a portion to copyNullPointerException
- if src
is nullvoid setAll(ObservableIntegerArray src)
src
- source observable array to copy.NullPointerException
- if src
is nullvoid setAll(ObservableIntegerArray src, int srcIndex, int length)
src
- source observable array to copy.srcIndex
- starting position in source observable arraylength
- length of a portion to copyNullPointerException
- if src
is nullvoid set(int destIndex, int[] src, int srcIndex, int length)
System.arraycopy()
method.destIndex
- the starting destination position in this observable arraysrc
- source array to copysrcIndex
- starting position in source arraylength
- length of portion to copyvoid set(int destIndex, ObservableIntegerArray src, int srcIndex, int length)
System.arraycopy()
method.destIndex
- the starting destination position in this observable arraysrc
- source observable array to copysrcIndex
- starting position in source arraylength
- length of portion to copyvoid set(int index, int value)
index
- index of the value to setvalue
- new value for the given indexArrayIndexOutOfBoundsException
- if index
is outside
array boundsint[] toArray(int[] dest)
dest
- the array into which the observable array to be copied,
if it is big enough; otherwise, a new int array is allocated.
Ignored, if null.int[] toArray(int srcIndex, int[] dest, int length)
srcIndex
- starting position in the observable arraydest
- the array into which specified portion of the observable array
to be copied, if it is big enough;
otherwise, a new int array is allocated.
Ignored, if null.length
- length of portion to copySubmit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 2008, 2021, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.