Ubuntu'nun Sanal Belleğini ve / veya Matlab için Takas Nasıl Artırılır?


16

Durum: Out of MemoryUbuntu'nun Matlab Hedefindeki hataları düzeltin
Hedef: harici HDD / SSD'ye bazı sanal bellek ve / veya Takas ayırın; okuma / yazma 20 GB / sn'den 0,1 GB / sn'ye düşer, bu da sorun değil!
Terminoloji: takas ve sanal bellek burada

Hayır, takas ve sanal bellek tamamen farklıdır. Örneğin, 1GB'lık bir dosyanın bellek eşlemesi ek 1GB'lık bir sanal bellek kullanır, ancak takas kullanımında bir değişiklik olmaz. Takas, bir destek mağazasının bir şeklidir. Sanal belleğin birçok kullanımının destek deposuyla ilgisi yoktur. (Ve sanal belleğe sahip olan ve takas olmayan sistemler olduğu gibi, takas olan ancak sanal belleğe sahip olmayan sistemler de vardır.)

Tüketici donanımı sınırlıdır, bu nedenle harici HDD'lerimle daha fazla sanal bellek kullanmam ve / veya değiştirmem gerekiyor. Matlab takas belleği hakkında (sanal bellek hariç TODO mu?)

Linux Sistemleri - mkswapve swaponkomutlarını kullanarak takas alanınızı değiştirin .

Sistemin özellikleri

  • Ne kadarına sahip olduğunuzu görebilirsiniz. swapon -s

    Filename                Type        Size    Used    Priority
    /dev/sda3               partition   8326140 0       -1
    
  • Matlab'ın yapılandırmaları

    % /programming//a/35971040/54964
    com.mathworks.services.Prefs.setIntegerPref('JavaMemHeapMax', 2048); % MB
    
    % TODO cannot find ways how to put Matlab use /dev/sda3
    
  • Matlab'ımın bunu kullanmadığını görüyorsunuz. Out of MemoryMatlab'da büyük matrislerle hata alıyorum . reshapeVektörlere matris oluşturmada ve paralel kod yazmada başarısız oldum . Bu yüzden sanal belleği kullanmak istiyorum çünkü işim bitti; oran önemli değil.

pseudocode

  1. Bir takas oluşturan kabuk betiği, MATLAB'ı başlatın ve MATLAB çıktığında takas silin. ( MichaelHooreman )
  2. Harici HDD'de değiştirmeyi etkinleştir. sudo swapon -aBurada nasıl kullanılır ?
  3. Matlab'ı başlatın.
  4. Matlab takas kullanın.
  5. Matlab çıktığında takas silin.

Micheal'ın komut dosyasında Geçici Değiştirme, İstemci Çalıştırma ve Takas Kapatma / Kaldırma

Durum : ortamı kurma (1), Matlab'ı (2) çalıştırma ve ortamı kapatma (3)
Komut Dosyası hatalarını denetleyemiyor

#!/usr/bin/env bash

# /programming//a/69808/54964
set -e 
# TODO How to do swapoff if any error?

SWAP_FILE="/media/masi/SamiSwapVirtual/.swap_file_20.7.2016"
SIZE_MB=16000
TO_RUN="matlab"

dd if="/dev/zero" of=${SWAP_FILE} bs="1M" count=${SIZE_MB} status="progress"
mkswap ${SWAP_FILE}
chmod 0600 ${SWAP_FILE}
sudo chown 0.0 ${SWAP_FILE} # /unix//a/297153/16920
sudo swapon -v ${SWAP_FILE}
echo "Swap enabled. Press enter to continue"; read
${TO_RUN}
echo "I will remove the swap. Press enter to continue"; read
sudo swapoff -v ${SWAP_FILE}
rm -vf ${SWAP_FILE}

Transcend 25M3 1 TB ile yineleme 1 Dosya sisteminin az kullanıldığı berofe ext4

  1. Komut dosyasını başlattıktan sonra günlükler

    sh start_matlab_with_swap.sh 
    16000+0 records in
    16000+0 records out
    16777216000 bytes (17 GB, 16 GiB) copied, 134.489 s, 125 MB/s
    Setting up swapspace version 1, size = 15.6 GiB (16777211904 bytes)
    no label, UUID=48c2835b-4499-4534-aa49-0648e15bd5d9
    [sudo] password for masi: 
    swapon /media/masi/SamiWeek/tmp/swap_file_18.7.2016
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: insecure file owner 1000, 0 (root) suggested.
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: found swap signature: version 1d, page-size 4, same byte order
    swapon: /media/masi/SamiWeek/tmp/swap_file_18.7.2016: pagesize=4096, swapsize=16777216000, devsize=16777216000
    Swap enabled. Press enter to continue
    start_matlab_with_swap.sh: 11: read: arg count
    
  2. İstemciyi çalıştırma

    • Komut geçmişi, takas belleğindeki (bilet no. 02075943) Matlab'ın ilk başlangıcında gitti , komut geçmişinizi okurken bir sorun oluştu - - . Sadece Matlab'ınızı yeniden başlatın ve varsayılan ayarlarınız varsa sorun çözüldü. Komut varsayılan konum olanı prefdirverir /home/masi/.matlab/R2016a( /home/{username}/.matlab/R2016a. /home/masi/.matlab/R2016a/matlab.prfYeniden başlatmadan sonra dosya var, burada .

    • ... [diğer hatalar] ...

  3. Matlab'ı kapatma ve Terminal'de tekrar şifre yazma

    [sudo] password for masi: 
    swapoff /media/masi/SamiWeek/tmp/swap_file_18.7.2016
    [ bugs here! ]
    

Açık: Hata yakalamanın daha iyi Hata işlemesi nasıl uygulanır? Kaynaktaki örnek için komut dosyama bakın. Konu Hata yakalama ve swapoff Hata / Uyarı eğer Nasıl Yapılacak?

Kalıcı Takas = Çalışan İstemciden Takas Kurulumu Ayrı

Takas Kurulumu

# /unix//q/297767/16920
masi@masi:~$ sudo fallocate -l 20G /mnt/.swapfile

masi@masi:~$ sudo mkswap /mnt/.swapfile 
Setting up swapspace version 1, size = 20 GiB (21474832384 bytes)
no label, UUID=45df9e48-1760-47e8-84d7-7a14f56bbd72

masi@masi:~$ sudo swapon /mnt/.swapfile
swapon: /mnt/.swapfile: insecure permissions 0644, 0600 suggested.

masi@masi:~$ sudo chmod 600 /mnt/.swapfile

masi@masi:~$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7925        1494         175         196        6255        5892
Swap:         28610           0       28610

/etc/fstabKalıcı değişiklik için aşağıdakileri sonuna ekleyin:

# /unix//a/298212/16920
# /unix//a/298543/16920

# If swap is on SSD, trim blocks each time at startup.
#/mnt/.swapfile  none    swap    defaults,discard      0        0

# If swap on External HDD, just use sw.
/media/masi/SamiWeek/.swapfile  none    swap    sw      0        0

Sistem: Linux Ubuntu 16.04 64 bit
Linux çekirdeği: 4.6
Linux çekirdek seçenekleri: wl
Matlab: 2016a
Resmi Matlab belgeleri: "Bellek Yetersiz" Hatalarını Çözme
Harici HDD: Transcend 1 TB StoreJet 25M3 incelemesi , Transcend 2 TB StoreJet 25M3
Harici HDD dosya sistemi: ext4
Harici HDD arabelleği: 8 MB
İlgili konular: Ubuntu'da MATLAB bellek sınırlaması nasıl artırılır? (mkswap nasıl kullanılır, MATLAB için swapon?) , Matlab'da Fiziksel hafıza artışı nasıl azaltılır? , Matlab bellek yetersiz hatası nasıl giderilir? , 10800x10800 matris için Matlab bellek yetersiz hatası nasıl düzeltilir? ,Matlab r2012b'de bellek sınırını (bitişik ve genel olarak) nasıl artırabilirim? , Matlab 2009b'de Dizi Bloğu Nasıl Artırılır ve Bellek Yetersiz Hatası Nasıl Çözülür? , Matlab küçük bir değişken için bu bellek yetersiz sorunu nasıl çözülür? , Matlab'daki 'Bellek yetersiz'. Yavaş ama kalıcı bir çözüm mü?


4
Üzgünüm, bu soruya cevap vermiyor. Ama bunu istediğinizden emin misiniz? Takastan hesaplamalar yapmak inanılmaz derecede uzun sürer. Ram saniyede en az 20 GB okur, harici
HDD'niz

1
@Yılan Evet, biliyorum. Sorun değil. 32/64 GB ile hesaplanabilen ancak şu anki 8 GB ultrabook'umla hesaplanamayan dev matrislerim var. Hala tatillerde tho hesaplama yapmam gerekiyor.
Léo Léopold Hertz 준영

1
Yararlı olmayan başka bir yorum üzgünüm. Bilgisayarı evde bırakabilir misin, böylece SSH'nin üzerinden geçip evde / üniversitede çalıştırabilir misin?
Anake

@Anake Şu anda mümkün değil, özür dilerim. Ayrıca, Matlab burada yerel hesaplamaya ihtiyaç duyar. Ayrıca, şu anda bunu yapmak için yeterli anahtarınız yok.
Léo Léopold Hertz 준영

Bu bağlamda MATLAB hakkında özel olan nedir? Bu sadece takas alanı nasıl artırılır?
steeldriver

Yanıtlar:


2

Tamam, orada bir liste var. Satır içi cevap vereyim

  1. Hata yakalamanın daha iyi hata işlemesi nasıl uygulanır? Kaynaktaki örnek için komut dosyama bakın. Hata / Uyarı durumunda Hata yakalama ve Değiştirme Nasıl Yapılır?

Bu senaryo kavramını hiç sevmiyorum. Takas olarak kullanmaya çalıştığınız harici bir sabit sürücünüz olması sadece kötü bir fikirdir. Bunu düzenli olarak gerçekten yapmak istiyorsanız, uygun bir takas bölümü koymak, bir takas dosyası eklemek veya yalnızca daha büyük bir dahili disk satın almak için bölümlerinizi yeniden boyutlandırın.

  1. Matris boyutu takas boyutunu aşarsa nasıl uyarı verilir?

Sadece matematik yap. Program başlamadan önce matrisin boyutunu biliyorsanız, MiB'de boyutu hesaplayın ve kullanılabilir takas ile karşılaştırın.

  1. Matlab'daki büyük matrisinizi hesaplarken ilerleme çubuğuna nasıl sahip olabilirsiniz?

matlab'ın bir API hakkı var mı? Bunun bu soru için doğru forum olduğunu düşünmüyorum. Bir API'niz olsa bile, IO üzerinde takas yoluyla engellemiş olursunuz, bu da gerçekliği yansıtmayan sarsıntılı bir ilerleme çubuğu olacaktır.

  1. Yoğun ilerlemeyi ve / veya yinelemede -s / swapoff'u nasıl öldürebiliriz (2)?

Yapmazsın. hesaplamayı bitirmiş olmanız, işletim sisteminin ayırdığınız kaynaklarla yapıldığı anlamına gelmez. Takas için yazmayı bitirdiğinde, serbest kalacaktır. O kadar çok bellek tüketdiniz ki birçok uygulama ihtiyaç duydukları belleği alamıyor, bu yüzden de takas kullanıyorlar. Sadece açık bırakın ve işletim sisteminin bir şey yapmasına izin verin. Bir sonraki koşunuzu gerçekleştirmeden önce önbellekleri temizleyin.

echo 3 > /proc/sys/vm/drop_caches 

Muhtemelen bundan daha fazlası var, ben bir Linux VM uzmanı değilim. SLAB / SLUB ayırıcısının nasıl çalıştığını ve büyük bellek gereksinimleriniz için nasıl ayarlayacağınızı araştırmak faydalı olacaktır. Matlab'ı belleğe MLOCK yapabilirsiniz. Bu, işletim sistemini sizin için bellek ayırmaya zorlar veya başlamaz, işiniz bittiğinde kilidini de açmanız gerekir. Bunu C API ile gayet iyi yapabilirim, ancak bunu yeniden derleyemediğim bir işlemin dışında nasıl yapacağınızdan emin değilim, bu biraz araştırma gerektirecektir.

Son olarak, bu EC2 için yapılmış bir şeydi. 16G ihtiyacınız olan şey gibi görünüyor, bir m4.4xlarge saatte 64G $ @ 64G ram'a sahip. Bir fincan kahveden daha az. Bir juju cazibesi veya benzeri kullanarak matlab kurulumunuzu komut dosyasılayın ve her şeyi bir hizmet olarak bir hesaplamaya dönüştürün.

16G 16 GB mı?

  • Evet, normalde sonekten ayrıldığımızda bayt birimi cinsinden base2 sayılarını kastediyoruz. Kısa ve öz isterseniz 16GiB yazarsınız.

"100 GB'den büyük matrislere ihtiyacım var. EC2 ile yapıp yapamayacağınızı bilmiyorum."

Önbelleklerinizi de temizlemeli misiniz echo 3 > /proc/sys/vm/drop_caches?

  • Evet, bunu yapmak her zaman acıtmaz. Linux çekirdeğindeki Documentation / sysctl / vm.txt dosyasına bakın.

Matlab'ı nasıl belleğe alabilirsin?

  • man mlock. Buna rağmen alıntı yaptığım zaman kandırdım. Bu çağrı, istediğiniz tüm belleği ayırabileceğinizi ve takas edilmesini engelleyebildiğinizi garanti eder, asla sanal bellek kullanmaz. İstediğin bu değil.

Sanırım C API'yi Matlab'a bağlayabilirsiniz. - - Süreçlerde herhangi bir başarısızlık varsa takas işlemini kapatma fikriniz var mı?

  • Burada dürüst olacağım, takas dosyalarını önerdiğiniz şekilde yönetme kavramı çok saçma. İşletim sisteminin işi kaynakları yönetmek ve adil ve tutarlı bir şekilde dağıtmaktır. Daha fazla kaynak verdiğinizde, bunları uygun gördüğü gibi kullanacaktır. İşiniz bittiğinde bunu söyleyemezsiniz ve kaynakları altından çıkarırsınız, işletim sistemi ne zaman bittiğini size söyler.

İşletim sisteminden bir bellek adresi alanı istediğimde, bazen her zaman başarılı olmaz, bu tekrar deneyemeyeceğim anlamına gelmez. Matlab'ın malloc'u iki kez çağırmayı anlayamaması matlab'ın sorunudur.

Yani, istediğiniz değişikliği etkilemek için, eğer 100G alan gerçekten bir primdeyse , işletim sistemine bellek ayak izini nasıl düzelteceğini (yeni başlayanlar için önbellekleri temizleyerek) nasıl anlatacağınızı anlamanız gerekir, böylece bellek yöneticisi sağlanan ek takas alanını kullanma gereğini hissedin. Sonra ancak o zaman bellek yöneticisinden takas dosyasını serbest bırakmasını isteyebilirsiniz.

Bellek ve disk gibi şeyleri büyütmek kolaydır, onları küçültmek çok daha zordur. Küçülen, bu alanda ayrılmış kaynakları olan her kullanıcının yeniden dengelenmesini zorlar. Bunun yerine "100 TB depolama dizisine sahibim ama şimdi sadece 60 TB'a ihtiyacım var, dizinin çalışmayı durdurduğu 40 TB disk kaldırdığımda neden var?" Peki, cevap açık olurdu değil mi?

İşte gördüğüm gibi seçenekleriniz.

  1. bu büyük çalışma kümeleri için belleğin nasıl ayrıldığını daha iyi kontrol edip edemeyeceğinizi görmek için matlab C API'sini araştırın.

  2. alt matrisleri veya diğer seyrek veri gösterimlerini kullanarak şimdi sahip olduklarınızı hesaplamak için hesaplamanızı yeniden düzenleyin.

  3. Hesaplama yapmak için orada bulunan lineer cebir kütüphanelerinin bolluğunu kullanarak C / C ++ 'da kendi programınızı yazın ve ihtiyacınız olan adres alanını tahsis etmek için mallocveya mmapanonim kullanın.


Evet, ancak yeterli olmayabilir ve eğer başarılı olursa, başarılı olmadan önce beklemek ve tekrar denemek zorunda kalabilirsiniz.
ppetraki

1
heh, yorumunuzun geri kalanı akıllı telefonumda görünmedi. sudo echo'yu böyle yapamazsınız. echo 3 | sudo tee /proc/sys/vm/drop_caches
ppetraki

Bu cevabı kabul ediyorum çünkü cevabında doğru anlamı var. İstemci'yi ortamın ayarlanmasıyla aynı komut dosyasında çalıştırmak inanılmaz derecede hataya açıktır. Burada daha fazla tartışma unix.stackexchange.com/a/298543/16920 - - Vücudunuzu biraz temizleyebilmeniz harika olurdu.
Léo Léopold Hertz 준영

12

Bir yazılım için takas alamazsınız. Yapabileceğiniz şey takas oluşturan bir kabuk betiği oluşturmak, MATLAB'ı başlatmak ve MATLAB çıktığında takas silmek.

İşte / tmp dizininde 10Mb'lik bir takas yaratan, bağlayan, R'yi başlatan (matlab'ım yok), R çıkışlarını bekleyin, takas dosyasını takıp silen bir örnek komut dosyası.

Lütfen unutmayın: - takas dosyasına kök ait olmadığı için bir uyarı gönderilir. Çünkü sistem herhangi bir yazılım için kullanacak, belki sizin tarafınızdan çalıştırılmayacak ve bu dosyayı okuyabilirsiniz ... düzeltmenize izin veriyorum. - komut dosyası veya oturum kapatma vb. [ctrl] - [c] yaparsanız, takas takılı kalacaktır. Ben de düzeltmene izin verdim.

#!/usr/bin/env bash

SWAP_FILE=/tmp/my_swap_file
SIZE_MB=10
TO_RUN="R"

dd if=/dev/zero of=${SWAP_FILE} bs=1M count=${SIZE_MB}
mkswap ${SWAP_FILE}
chmod 0600 ${SWAP_FILE}
sudo swapon -v ${SWAP_FILE}
echo "Swap enabled. Press enter to continue"; read
${TO_RUN}
echo "I will remove the swap. Press enter to continue"; read
sudo swapoff -v ${SWAP_FILE}
rm -vf ${SWAP_FILE}

1
Aslında, MATLAB'a adanmış değil, geçici olarak daha fazla RAM'e ihtiyaç duyan herhangi bir durum için.
Swapon / swapoff'un

1
Evet sende var. Kök bu şekilde olur.
Michael Hooreman

İyi cevap. Şahsen bu yaklaştı ve bellek yendi zaman bu güzel anlar için kendi add-swap.sh komut dosyası tutmak
Sergiy Kolodyazhnyy

Bu ödülün ödülünü aldım çünkü beni doğru şekilde yaptı. Ancak yanıtı kabul edemiyorum çünkü hata yönetimi çok zor ve eksik. Değiştirmeyi Matlab'ı çalıştırmaktan ayrı olarak ayarlamak en iyisidir, lütfen buradaki cevaba bakın unix.stackexchange.com/a/298543/16920
Léo Léopold Hertz 준영

1

Harici bir sabit sürücü kullanarak SWAP belleğinizi şu şekilde genişletebilirsiniz :

  • İlk olarak, çalıştırarak gerçek SWAP belleğinizi not edin:

    free -m
    
  • İkinci olarak, sabit diskinizin klasörünü elinizde bulundurun. Böyle bir şey olmalı /media/myhdd.

  • Eklemek istediğiniz ekstra SWAP boyutuna karar verin. Diyelim ki, X GB.
  • Miktarın bayt miktarını hesaplayın. GB kullanarak bu: Y = X * 1024 ^ 3 , burada Y hesaplamanızın sonucudur.
  • Dosyanın blok boyutunu seçin (bayt cinsinden). Burada varsayılanı kullanalım: 4096 ( Bununla ilgili daha fazla bilgi edinin) burada bulabilirsiniz ).
  • Dosyanın sahip olacağı blok sayısını hesaplayın: Z = Y / 4096
  • Bir terminalde aşağıdaki komutu kullanarak X GB boyutunda bir dosya oluşturun :

    dd if=/dev/zero of=/media/myhdd/swapfile bs=4096 count=Z
    
  • Dosyayı kullanarak SWAP dosyasını oluşturun:

    sudo mkswap /media/myhdd/swapfile -f
    
  • Son olarak, SWAP'ı etkinleştirin:

    sudo swapon -p 1000 /media/myhdd/swapfile
    

Artık SWAP'iniz arttı. İle tekrar kontrol etfree -m


Bunu etkileşimli olmayan bir komut dosyasında ayarlayabiliriz ( sudogüçler gerekir):

#!/bin/bash

### Inputs ###

swap_GB=$(expr 1) # Enter here size of the swap memory to create, in GB.
swap_bs=$(expr 4096) # Enter here block size, in bytes (must be a multiple of 8).
HDD_folder="/media/myhdd/" # Enter absolute path of HDD inside the brackets.

### Swap creation ###

swap_size=$(expr $swap_GB \* 1024 \* 1024 \* 1024 / $swap_bs)
dd if=/dev/zero of=${HDD_folder}"/swapfile" bs=$swap_bs count=$swap_size
mkswap ${HDD_folder}"/swapfile" -f
swapon -p 1000 ${HDD_folder}"/swapfile"

### EOF ###

Not: mümkünse lütfen optimize edin / düzeltin. Dediğim gibi, bu benim ilk senaryom :)


Takas zaten yavaş, ama USB sürücüsünde takas olduğunu hayal edemiyorum. Cehennem gibi yavaş olacak IMHO
Michael Hooreman

Özet olarak bir senaryo harika olurdu.
Léo Léopold Hertz 준영

1
Daha önce hiç senaryo oluşturmadım ama bir deneme yaptım.

1

En azından sıkıştırılmış RAM'in (zram çekirdek modülü, çekirdek sürüm 3.14'ten beri kullanılabilir) ne kadar iyi çalıştığını test ederim.

Aşağıdaki Arch Linux Wiki talimatları

modprobe zram
echo lz4 > /sys/block/zram0/comp_algorithm
echo 4G > /sys/block/zram0/disksize
mkswap --label zram0 /dev/zram0
swapon --priority 100 /dev/zram0

Benim tahminim sıkıştırılmış RAM'in disk G / Ç'den daha hızlı olması gerektiğidir.

Yeniden başlattıktan sonra da değişikliği sürdürmek için, önyükleme zamanı komutlarını yerleştirin /etc/rc.localve çalıştırın sudo systemctl enable rc-local.service.


Zramın bellek boyutu ve sayfalama hızı üzerindeki etkisi için cevabı unix.stackexchange.com/q/297752/16920'ye uzattım. Bellek boyutu üzerinde, muhtemelen çoğunlukla disk belleği üzerinde herhangi bir etki bulamıyorum. Ancak, runit ile sistemd / ... uyarısı artmıştır. Zram'ın hata oranını bilmek harika olurdu.
Léo Léopold Hertz 준영

Zram0 durumunda, orig_data_size ve compr_data_size dosyalarında / sys / block / zram0 içinde bazı istatistikler vardır . Ben orada çok fazla veri takas yok, ama orada ne için oranı yaklaşık 0.35. Bu oranla 11 GB veri 4 GB RAM'e sığabilir. Bu, diske değiştirilmeyen 7 GB veri anlamına gelebilir.
JJ Hakala

1
Önyükleme zamanı komutlarını /etc/rc.local ve sonrasudo systemctl enable rc-local.service
JJ Hakala

zramHDD / SSD üzerindeki takas için geçerli olmadığını öğrendim, bu yüzden zramburada geçerli değil, lütfen askubuntu.com/a/472227/25388
Léo Léopold Hertz 준영

1

zswapHDD / SSD üzerinde takas bölümleriniz varsa kullanın . Tho modülü zramHDD / SSD üzerinde takas bölümleri içermediğinden Hakala'nın yanıtı geçerli değildir. Konu zram vs zswap vs zcache Ultimate guide: açıklamalar için hangisini kullanacağınız . Ubuntu 16.04 Matlab hesaplaması için başarıyla Zswap etkinleştirmek nasılzswap iş parçacığında açıklandığı gibi Kur ?

  • İlgili satırı aşağıdaki satırla değiştirin /etc/default/grub

    # https://wiki.archlinux.org/index.php/Zswap
    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash zswap.enabled=1 zswap.max_pool_percent=25 zswap.compressor=lzo"
    
  • Koş sudo update-grub.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.