Numpy: numpy 1.19.0์˜ Azure CI (Windows ์ธ์Šคํ„ด์Šค) ์˜ค๋ฅ˜

์— ๋งŒ๋“  2020๋…„ 07์›” 20์ผ  ยท  53์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: numpy/numpy

์•ˆ๋…•ํ•˜์„ธ์š”,
์ตœ๊ทผ Windows ์ธ์Šคํ„ด์Šค ( vmImage: 'windows-2019' )๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Azure Pipelines์—์„œ ๋‚ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด (https://developercommunity.visualstudio.com/content/problem/1102472/azure-pipeline-error-with-windows-vm.html?childToView=1119179#comment-1119179 ๋Œ€ํ™” ์ฐธ์กฐ) ๋ฌธ์ œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์„ค์น˜ํ•  ๋•Œ ์œ ๋ž˜ numpy 1.19.0 ๋Œ€์‹  numpy 1.8.5 - ๋‚˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ numpy 1.19.0 ๋…„ 6 ์›” 20 ์ผ์— PyPI์— ๋„ฃ์–ด ์ด๊ฒƒ์€ ์šฐ๋ฆฌ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜๊ธฐ ์‹œ์ž‘ ๋ฌด๋ ต์ž…๋‹ˆ๋‹ค . ์ด์ „์— ์„ฑ๊ณตํ•œ ๋นŒ๋“œ์—์„œ์™€ ๊ฐ™์ด ํ™˜๊ฒฝ์— numpy 1.8.5 ๋ฅผ ์„ค์น˜ํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๊ด€์ฐฐํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„๋ณด๊ณ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค (๊ทธ๋Ÿฌ๋‚˜ numpy๊ฐ€ ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์ •ํ™•ํžˆ ์ง€์ ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค ...

์—ฌ๋Ÿฌ๋ถ„์˜ ์˜๊ฒฌ์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜์žˆ๋Š” ๊ฒฝ์šฐ ๋‚ด azure ํŒŒ์ดํ”„ ๋ผ์ธ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๊ฒŒ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

์—๋Ÿฌ ๋ฉ”์‹œ์ง€:

์ด ๋นŒ๋“œ๋Š” numpy 1.18.5์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. https://dev.azure.com/matteoravasi/PyLops/_build/results?buildId=46&view=logs&j=011e1ec8-6569-5e69-4f06-baf193d1351e
numpy 1.19.0์„ ์‚ฌ์šฉํ•˜๋Š” ๋™์ผํ•œ ์ปค๋ฐ‹์—์„œ ๋นŒ๋“œ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค : https://dev.azure.com/matteoravasi/PyLops/_build/results?buildId=43&view=results

์˜ค๋ฅ˜๋Š” ๋งค์šฐ ๋ชจํ˜ธํ•˜๋ฉฐ ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋‚ด์šฉ์ด ๋” ๊ด€๋ จ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค.

2020-07-06T13:56:01.6879900Z Windows fatal exception: Current thread 0xaccess violation00001798
2020-07-06T13:56:01.6880280Z 
2020-07-06T13:56:01.6880589Z  (most recent call first):
2020-07-06T13:56:01.6880973Z   File "<__array_function__ internals>", line 6 in vdot
2020-07-06T13:56:05.3412520Z ##[debug]Exit code: -1073741819

๋ชจ๋“  53 ๋Œ“๊ธ€

์ง€์†์ ์œผ๋กœ ์‹คํŒจํ•ฉ๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๊ฐ€๋”์”ฉ ๋งŒ ์‹คํŒจํ•ฉ๋‹ˆ๊นŒ? ๋กœ์ปฌ ์ปดํ“จํ„ฐ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œ ํ•  ์ˆ˜์žˆ๋Š” Windows ๊ฐœ๋ฐœ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š”,
๊ฐ์‚ฌ!

์ผ๊ด€๋˜๊ฒŒ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์‹œ์ ์—์„œ ์ €๋Š” Azure ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฌผ์–ด๋ณผ ์ƒ๊ฐ์„ํ–ˆ์Šต๋‹ˆ๋‹ค (์ดˆ๊ธฐ ์ถ”์ธก์€ VM ์„ค์ •์—์„œ ๋ฌด์–ธ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Œ).

์ด ๋งํฌ์—๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ ํ•œ Microsoft ๊ฐœ๋ฐœ์ž์™€ ๋…ผ์˜ํ•œ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๋งŽ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://developercommunity.visualstudio.com/content/problem/1102472/azure-pipeline-error-with-windows-vm.html? childToView = 1119179 # comment -1119179

๋ถˆํ–‰ํžˆ๋„ ๋กœ์ปฌ Windows ์‹œ์Šคํ…œ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œ ํ•  ์ˆ˜์žˆ๋Š” ์‚ฌ๋žŒ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์žฌํ˜„์„์œ„ํ•œ ๋ช…ํ™•ํ•œ ๋‹จ๊ณ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

azure-pipelines.yml์ด ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์— ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ (https://github.com/equinor/pylops/blob/master/azure-pipelines.yml)์ด ํ˜„์žฌ ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค .Python 3.7์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฝค ํ‘œ์ค€์ ์ธ ์„ค์ •์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. , requirements-dev.txt ํŒŒ์ผ (https://github.com/equinor/pylops/blob/master/requirements-dev.txt)์— ์ข…์†์„ฑ์„ ์„ค์น˜ ํ•œ ๋‹ค์Œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ด๊ฒƒ์„ ์ฃผ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  1.18.5 ๋ชจ๋“  ๊ฒƒ์ด ์‹คํ–‰๋˜๋„๋ก ๊ฐ•์ œํ•˜๋ฉด ์ƒˆ๋กœ์šด 1.19๊ฐ€ ์ค‘๋‹จ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

Azure์—์„œ ์‹คํ–‰๋˜๋Š” ์ด๋ฏธ์ง€์˜ Windows ๋ฒ„์ „ ์ฃผ ๋ฒ„์ „๊ณผ ๋ถ€ ๋ฒ„์ „์€ ๋ฌด์—‡์ธ๊ฐ€์š”? ์ฆ‰, systeminfo ๋Š” OS Version ๋ฌด์—‡์„ ์ธ์‡„ํ•ฉ๋‹ˆ๊นŒ?

Azure Pipelines์—์„œ ์‚ฌ์šฉ๋˜๋Š” Azure VM์˜ ์„ธ๋ถ€ ์ •๋ณด๋Š” https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops&tabs=yaml ๋ฐ ๋‹ค์Œ ๋งํฌ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค์น˜๋œ ์†Œํ”„ํŠธ์›จ์–ด https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md

Azure ํŒŒ์ดํ”„ ๋ผ์ธ์—์„œ systeminfo ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”?

๋ช…๋ น ์ค„์—์„œ ์‹คํ–‰๋˜๊ณ  ์ถœ๋ ฅ์„ ํ„ฐ๋ฏธ๋„์— ๋คํ”„ํ•˜๋ฏ€๋กœ ์‹คํ–‰์— ๋ช…๋ น์œผ๋กœ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CI์—์„œ ์‹คํ–‰๋˜๋Š” PR์—์„œ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 19041 ๋นŒ๋“œ์˜ Windows ๋ฐ pip NumPy์— ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌป์Šต๋‹ˆ๋‹ค.

๋Œ€๋‹ต์€ ๋‘ ๋ฒˆ์งธ ๋งํฌ์— ์žˆ์Šต๋‹ˆ๋‹ค.

OS ๋ฒ„์ „ : 10.0.17763 Build 1282

๊ทธ๋ž˜์„œ ๋‚ด ์ƒ๊ฐ์€ ๊ฒฐ์‹ค์ด ์—†์Šต๋‹ˆ๋‹ค.

Windows ์šฉ ์ตœ์‹  ํ• ํœ ์— ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๊ณ  ๋ง์”€ ํ•˜์…จ๋Š”๋ฐ, ์•„๋งˆ๋„ ๊ทธ์™€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์‹ค์ œ๋กœ๋Š” (์•„๋งˆ๋„) 19041 ๋…„์— ๋„์ž… ๋œ Windows ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค.ํ•˜์ง€๋งŒ ํ›จ์”ฌ ์ด์ „ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์ œ๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Conda NumPy์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฉฐ Windows ๋ฐ OpenBlas์— ๋ฌธ์ œ๊ฐ€์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฏ€๋กœ pip NumPy์—๋งŒ ์˜ํ–ฅ์„์ค๋‹ˆ๋‹ค.

:) 1.9.1์ด ์ถœ์‹œ๋˜์—ˆ๋‹ค๋Š” ์ด๋ฉ”์ผ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ตœ์‹  ๋ฒ„์ „์„ ์„ค์น˜ํ•˜๊ณ  ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” Azure ํŒŒ์ดํ”„ ๋ผ์ธ์„ ๋‹ค์‹œ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

OpenBlas์˜ ๋ฒ„๊ทธ.

๋‹ค์Œ์€ ์žฌํ˜„ ์˜ˆ์ž…๋‹ˆ๋‹ค.

import numpy as np
nr = 12000
v = np.random.randn(nr) + 1j * np.random.randn(nr)
np.vdot(v, v)
# also access violations
v @ v
# also access violations

๊ธฐํ˜ธ๊ฐ€์—†๋Š” ๋””๋ฒ„๊น… ์ •๋ณด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Exception thrown at 0x0000000068DBB8F0 (libopenblas.NOIJJG62EMASZI6NYURL6JBKM4EVBGM7.gfortran-win_amd64.dll)
in python.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

๋ฒ„๊ทธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ ค๋ฉด ์–ด๋ ˆ์ด๊ฐ€ ๊ฝค ์ปค์•ผํ•ฉ๋‹ˆ๋‹ค (10k ํŒจ์Šค, 12k๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Œ).

๋น ๋ฅธ ํ™•์ธ:

$env:OPENBLAS_VERBOSE=2
$env:OPENBLAS_CORETYPE=Prescott

ํ†ต๊ณผํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์ปค๋„ ( Zen )๊ณผ Haswell ๋ฐ Sandybridge ๋ชจ๋‘ ์•ก์„ธ์Šค ์œ„๋ฐ˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  OpenBLAS 0.3.10์„ ์‚ฌ์šฉํ•˜๋Š” numpy HEAD๋„ ์‹คํŒจํ•˜๋Š”์ง€ ํ™•์ธํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ์ด๋ฏธ ํ–ˆ์Šต๋‹ˆ๊นŒ?

@mattip no ์•„์ง ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. pip install git+https://github.com/numpy/numpy ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ์Šคํ„ฐ์—์„œ ์ง์ ‘ bumpy๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‹œ๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค :)

๊ทธ๋ฆฌ๊ณ  ๊ท€ํ•˜์˜ ์งˆ๋ฌธ์— @bashtage (์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ์—์„œ numba๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ? ์ด๋ฉ”์ผ์ด์ง€๋งŒ์ด ์Šค๋ ˆ๋“œ์—์„œ ๋ณผ ์ˆ˜์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ... ์ถฉ๋Œํ•˜๋Š” ํ…Œ์ŠคํŠธ๋Š” numpy ๋ฐ pyfftw ์ž‘์—…์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ‘์ž‘์Šค๋Ÿฐ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์ถฉ๋Œํ•˜๋ฏ€๋กœ ์–ด๋–ค ๋ผ์ธ์—์„œ ์‹ค์ œ๋กœ ์ถฉ๋Œํ•˜๋Š”์ง€ ์•Œ๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ pyfftw ๋Š” numba๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ ์ข…์†์„ฑ ์ค‘ ํ•˜๋‚˜๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

๋‚œ ๊ทธ๋ƒฅ GitHub์˜ ์ €์žฅ์†Œ์—์„œ ์ง์ ‘ NumPy์™€์˜ HEAD ์„ค์น˜์™€ ์‹œ๋„ํ•˜์ง€ํ•˜๊ณ  ์ฐฝ์„ ์™„๋ฃŒ๊นŒ์ง€ ์‹คํ–‰์„ ๊ตฌ์ถ• - ๊ฐ‘์ž‘์Šค๋Ÿฐ ์ถฉ๋Œ : https://dev.azure.com/matteoravasi/PyLops/_build/results?buildId=54&view=logs&j= 011e1ec8-6569-5e69-4f06-baf193d1351e & t = bf6cf4cf-6432-59cf-d384-6b3bcf32ede2

ํฅ๋ฏธ๋กญ๊ฒŒ๋„ NumPy๋ฅผ ์ข…์†์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ œ๋Œ€๋กœ ์„ค์น˜๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™๊ณ  (์ด์œ ๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์Œ) ์ผ๋ถ€ ํ…Œ์ŠคํŠธ๋Š” ๋ชจ๋“  OS์— ๋Œ€ํ•ด ์‹คํŒจํ•˜์ง€๋งŒ ์ ์–ด๋„ ์ด์ „๊ณผ ๊ฐ™์ด ์™„์ „ํ•œ ์ถฉ๋Œ์€ ์•„๋‹™๋‹ˆ๋‹ค.

์•ผ๊ฐ„ ์‚ฌ์šฉ ์˜ค๋ฅ˜ ์—†์Œ :

pip install -i https://pypi.anaconda.org/scipy-wheels-nightly/simple numpy

๋ฐฉ๊ธˆ GitHub ์ €์žฅ์†Œ์—์„œ ์ง์ ‘ NumPy์˜ HEAD ์„ค์น˜๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ช…์‹œ ์ ์œผ๋กœ ๋นŒ๋“œํ•˜์ง€ ์•Š๋Š” ํ•œ ์—ฌ๊ธฐ์—๋Š” OpenBLAS๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ pip install git+https://github.com/numpy/numpy.git ์™€ ํ•จ๊ป˜ ๋Š๋ฆฌ๊ณ  ์ผ๋ฐ˜์ ์ธ BLAS๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

1.19.2 ์šฉ OpenBLAS๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ ค๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Azure์˜ ์ตœ์‹  --pre ๋นŒ๋“œ (numpy-1.20.0.dev0 + a0028bc) ์—์„œ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Current thread 0x000003d0 (most recent call first):
  File "<__array_function__ internals>", line 5 in dot
  File "D:\a\1\s\mne\minimum_norm\inverse.py", line 732 in _assemble_kernel

๋ฌธ์ œ์˜ ์ค„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

K = np.dot(eigen_leads, trans)

๋„์›€์ด๋œ๋‹ค๋ฉด ๋ฐฐ์—ด์„ ๋””์Šคํฌ์— ์ €์žฅํ•˜๊ณ  Azure ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ–ˆ๋˜ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์‚ฌ์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

$env:OPENBLAS_VERBOSE=2

๋˜๋Š”

set OPENBLAS_VERBOSE=2

์–ด๋–ค ์ปค๋„์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•ด ํ…œํ”Œ๋ฆฟ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋„์›€์ด๋œ๋‹ค๋ฉด ๋ฐฐ์—ด์„ ๋””์Šคํฌ์— ์ €์žฅํ•˜๊ณ  Azure ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

dtypes์™€ ์ฐจ์›์„ ์•„๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ข‹์•„์š”, ๊ณฑํ•˜๋Š” ํ–‰๋ ฌ์„ ์ž‘์„ฑํ•œ ๋‹ค์Œ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์—…๋กœ๋“œํ•˜๋Š” numpy + scipy + matplotlib + pytest (๋ฐ deps)๋งŒ์œผ๋กœ ์‹คํŒจํ•œ ํ…Œ์ŠคํŠธ์˜ ๋‹จ์ผ ์‹คํ–‰์—์„œ ์žฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์•„ํ‹ฐํŒฉํŠธ ํƒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

https://dev.azure.com/mne-tools/mne-python/_build/results?buildId=8330&view=artifacts&type=publishedArtifacts

๋งˆ์ง€๋ง‰ .npz ๊ฐ€ ์‹คํŒจํ•œ ๊ฒƒ์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค (27MB). Linux์—์„œ๋Š” ๋กœ์ปฌ๋กœ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

>>> import numpy as np
>>> data = np.load('1595525222.9485037.npz')
>>> np.dot(data['a'], data['b']).shape
(23784, 305)
>>> data['a'].shape, data['a'].dtype, data['b'].shape, data['b'].dtype
((23784, 305), dtype('>f4'), (305, 305), dtype('float64'))
>>> data['a'].flags, data['b'].flags
(  C_CONTIGUOUS : False
  F_CONTIGUOUS : True
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
,   C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False
)

OPENBLAS_VERBOSE ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์ง€๋งŒ pytest -s ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์‹ค์ œ๋กœ ์ „๋‹ฌ๋˜๋Š” ์ถœ๋ ฅ์„ ์บก์ฒ˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ง€ ์šฐ์—ฐ์ผ์ง€๋„ ๋ชจ๋ฅด์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค ...

์›ƒ๊ธฐ์ง€ ๋งŒ ์ง€๊ธˆ ์œ„์˜ ์žฌ์ƒ๊ธฐ๋กœ๋„ ๋ด…๋‹ˆ๋‹ค.

OPENBLAS_CORETYPE ์„ Prescott ๋˜๋Š” Nehalem์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Zen, Sandybridge ๋ฐ Haswell๊ณผ ํ•จ๊ป˜ ๋ด…๋‹ˆ๋‹ค.

Windows์—์„œ npz์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ๋กœ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Windows์—์„œ npz์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ๋กœ ์žฌํ˜„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Azure์˜ FWIW ์ด์ œ ์—ฌ๊ธฐ์—์„œ ์‹คํ–‰ ๋œ ์ฝ”๋“œ์˜ ๋งˆ์ง€๋ง‰์—์„œ ๋‘ ๋ฒˆ์งธ ์ค„์—์„œ ์‹คํŒจํ•˜๋ฏ€๋กœ ์ €์žฅ-๋กœ๋“œ-๋ผ์šด๋“œ ํŠธ๋ฆฝ ๋ฐ์ดํ„ฐ๋กœ ์žฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    import mne, os.path as op, time
    fname = op.join(op.dirname(mne.__file__), '..', 'bad', f'{time.time()}.npz')
    np.savez_compressed(fname, a=eigen_leads, b=trans)
    print(eigen_leads.flags)
    print(trans.flags)
    data = np.load(fname)
    np.dot(data['a'], data['b'])  # <-- fails here
    K = np.dot(eigen_leads, trans)   # <-- used to fail here before I added the above lines

๋”ฐ๋ผ์„œ np.savez / np.load ๋‹จ๊ณ„๋กœ ์ธํ•ด Azure ๋์—์„œ ์†์‹ค๋˜๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜๋„ ๋„์›€์ด๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด OPENBLAS_CORETYPE: 'nehalem' ๋กœ ์‹คํ–‰ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ์‹ค์ œ๋กœ ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฒ„๊ทธ๊ฐ€์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋˜ํ•œ OPENBLAS_VERBOSE: 2 ์ด ํšจ๊ณผ๊ฐ€์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒ์„ธ ์„ค์ • ํ›„ ๋ช…๋ น ์ถ”๊ฐ€

python -c "numpy ๊ฐ€์ ธ ์˜ค๊ธฐ"

Pytest๋Š” ์•„๋งˆ๋„ ์ด๊ฒƒ์„ ๋จน๊ณ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Thu, Jul 23, 2020, 19:04 Eric Larson [email protected] ์ž‘์„ฑ :

๋˜ํ•œ OPENBLAS_VERBOSE : 2 ์„ค์ •์€ ํšจ๊ณผ๊ฐ€์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
ํ™•์‹คํžˆ ์™œ

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/numpy/numpy/issues/16913#issuecomment-663151960 ๋˜๋Š”
๊ตฌ๋… ์ทจ์†Œ
https://github.com/notifications/unsubscribe-auth/ABKTSRNS5QRT6CC3ZQ6DQYDR5B3TTANCNFSM4PCRVE6A
.

์ด ๋ช…๋ น์€ ๋กœ์ปฌ๋กœ๋„ ์ž์„ธํ•œ ์ถœ๋ ฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

OPENBLAS_VERBOSE=2 python -c "import numpy as np, glob; data = np.load(glob.glob('bad/*.npz')[0]); a, b = data['a'], data['b']; print(np.dot(a, b).shape)"

ํ•˜์ง€๋งŒ ๋‚ด ์‹œ์Šคํ…œ OpenBLAS๊ฐ€ ๋„ˆ๋ฌด ์˜ค๋ž˜๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํŒจํ•œ ํ›„ ์ž์ฒด์ ์œผ๋กœ ์‹คํ–‰๋˜๋„๋ก Azure์— ์ปค๋ฐ‹์„ ํ‘ธ์‹œํ•ฉ๋‹ˆ๋‹ค.

Azure์˜ OPENBLAS_VERBOSE๋Š” "Core : Haswell"์ด๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ๊ทธ๊ฒŒ ๋งž๋Š”์ง€ ์•„๋‹Œ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

https://github.com/xianyi/OpenBLAS/issues/2732 ์—์„œ ์˜ค๋ฅ˜๋ฅผ๋ณด๊ณ ํ–ˆ์œผ๋ฉฐ ๋งˆ์Šคํ„ฐ์—์„œ ์ˆ˜์ • ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ œ์•ˆํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/xianyi/OpenBLAS/issues/2728์„ ์ฐธ์กฐ

@mattip ์ด๊ฒƒ์ด MacPython / openblas-libs # 35์— ์˜ํ•ด ๋‹ซํ˜”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ ์ฃผ๊ฐ„์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†๋‚˜์š”?

@charris ์ด ๋ฌธ์ œ๋Š” ์•„์ง ์—ด๋ ค ์žˆ๊ณ  ๋ฐฑ ํฌํŠธ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์žฌํ˜„์ž๋ฅผ ๊ฐ€์ง„ ๋ˆ„๊ตฐ๊ฐ€ ๊ฐ€์ด ์ปค๋ฐ‹ ์œผ๋กœ numpy๋ฅผ ๋นŒ๋“œํ•˜์—ฌ ์ตœ์‹  OpenBLAS ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ž˜์„œ (์˜คํƒ€๊ฐ€์žˆ๋Š” mabe)

git add remote mattip https://github.com/mattip/numpy.git
git fetch mattip  issue-16913
git checkout issue-16913
python tools/openblas_support.py
# copy the output openblas.a to a local directory and make sure numpy uses it
mkdir openblas
copy /path/to/openblas.a openblas
set OPENBLAS=openblas
python -c "from tools import openblas_support; openblas_support.make_init('numpy')"
pip install --no-build-isolation --no-use-pep517 .

์•„์ง ์„ค์น˜ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด choco install -y mingw ์‚ฌ์šฉํ•˜์—ฌ gfortran์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

... ์ด๊ฒƒ์€ Windows ์šฉ์ž…๋‹ˆ๋‹ค.

์•„์ง ์„ค์น˜ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด choco install -y mingw๋กœ gfortran์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

32 ๋น„ํŠธ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ?

https://github.com/numpy/numpy/blob/master/azure-steps-windows.yml#L29 -L31

๋‚œ ๋‹น์‹ ์ด ์œ„์—์„œ ์ œ์•ˆ ๋ฌด์—‡์„ํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๋‹ค choco install -y mingw I๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…ํ•˜๋ฉด /path/to/openblas.a ์ž…๋‹ˆ๋‹ค - ์•„๋งˆ๋„ ์‹คํ–‰ tools/openblas_support.py (?).

์˜ˆ, python tools/openblas_support.py ๋Š” openblas.a ์„ ์ฐพ์„ ์œ„์น˜๋ฅผ ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค.

gfortran์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Azure ๋จธ์‹ ์—๋Š” mingw 64 ๋น„ํŠธ๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 32 ๋น„ํŠธ ์ธ ๊ฒฝ์šฐ ํ˜ธ์ถœ์ด ์•ฝ๊ฐ„ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -m32 ๋„ ์„ค์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค (32 ๋น„ํŠธ์—๋งŒ ํ•ด๋‹น).

๋‚˜๋Š” ๋ฐฉ๊ธˆ NumPy์˜ master ๋ถ„๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ https://github.com/numpy/numpy/blob/master/azure-steps-windows.yml์˜ ๋Œ€๋ถ€๋ถ„์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜์Œ์œผ๋กœ ์žฌํ˜„ํ–ˆ์œผ๋ฉฐ ์„ฑ๊ณต์ ์œผ๋กœ ๊ทธ๊ฒƒ์€ segfault .

๊ทธ๋Ÿฐ ๋‹ค์Œ mattip/issue-16913 ๋กœ ์ „ํ™˜ํ–ˆ๋Š”๋ฐ ๋‹ค์Œ URL ๋‹ค์šด๋กœ๋“œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์‹คํŒจ ํ•ฉ๋‹ˆ๋‹ค.

https://anaconda.org/multibuild-wheels-staging/openblas-libs/v0.3.9-452-g349b722d/download/openblas-v0.3.9-452-g349b722d-win_amd64-gcc_7_1_0.zip

... 64 ๋น„ํŠธ Windows ์šฉ 32 ๋น„ํŠธ OpenBLAS๊ฐ€์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

https://anaconda.org/multibuild-wheels-staging/openblas-libs/files

64 ๋น„ํŠธ OpenBLAS๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

2 ๊ฐœ๊ฐ€ ์žˆ๊ณ  1 ๊ฐœ๋Š” ์•„์ง ๊ฑด์„ค ์ค‘์ž…๋‹ˆ๋‹ค. ํ•œ ์‹œ๊ฐ„ ๋‚ด์— ์ž‘๋™ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋™์•ˆ ๋‚˜๋Š” ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

        NPY_USE_BLAS_ILP64: '1'
        OPENBLAS_SUFFIX: '64_'

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์ž˜ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๋” ์ด์ƒ segfaults๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค ! ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ๋ฒˆ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 32 ๋น„ํŠธ OpenBLAS Win64 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์–ธ์ œ๋“ ์ง€ ์ €์—๊ฒŒ ํ•‘์„ ๋ณด๋‚ด์ฃผ์„ธ์š”.์ด ์ค„์„ ์‰ฝ๊ฒŒ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค์‹œ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ฒด ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ :-)

python -c "import numpy; numpy.test('full')"

32 ๋น„ํŠธ๊ฐ€ ์˜ฌ๋ผ๊ฐ„ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉฐ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค .

์ด์ œ ์ „์ฒด ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

f2py ๊ด€๋ จ ์ด์ƒํ•œ ํ…Œ์ŠคํŠธ ์ˆ˜์ง‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

https://dev.azure.com/mne-tools/mne-python/_build/results?buildId=8372&view=logs&j=a846d25a-e32c-5640-1b53-e815fab94407&t=14a4ea33-5055-5caa-db84-413553e060fb

์ด ๋‹ค๋ฅธ ๋ฌธ์ œ์— ๋” ์ด์ƒ ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ BLAS๊ฐ€์žˆ๋Š” ์ฃผ๊ฐ„์„ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜์— ์ปค๋ฐ‹์„ ํ‘ธ์‹œํ•˜์—ฌ ์–ธ์ œ๋“ ์ง€ ์•ผ๊ฐ„ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์Šต๋‹ˆ๋‹ค. Windows 10 2004์˜ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ ํ•ญ๋ชฉ์ด ํ‘œ์‹œ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

@bashtage ์ด๊ฒƒ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

OpenBLAS๋Š” Windows์˜ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์—์„œ ์—ฌ์ „ํžˆ ์†์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๋‚˜์—๊ฒŒ๋Š” ๋„๊ตฌ ์ฒด์ธ๊ณผ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ๋””๋ฒ„๊น… ์ •๋ณด๋ฅผ ์–ป๋Š” ๊ฒƒ๋„ ๋งค์šฐ ๋น„ํ‘œ์ค€์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰