ログ

見る価値ありません

【メモ】Proxmox VE 7.4-3でWindows 11 VMへのGPUパススルーに失敗する

TLDR: Windows11のWindowsセキュリティ-コア分離-メモリ整合性を有効化したらGPUパススルーが失敗するようになった


2023-05-20 01:26

https://zenn.dev/eucyt/articles/replace-pve-gpu

https://forum.proxmox.com/threads/problem-with-gpu-passthrough.55918/post-478351

https://forum.proxmox.com/threads/problem-with-gpu-passthrough.55918/post-474131


2023-05-20 19:50

以上の記事は参考になったが関係はなかった

CPU typeがEPYCだとGPUパススルーに成功し、hostに変更すると失敗する(誤ってCPU type EPYCの設定でVMを立て、Windowsをインストールしていた)

結局VMを削除して、CPU type hostで立て直したら治った


2023-05-20 20:33

Windows11のコア分離のメモリ整合性を有効化したら再発した

RDPつないでオフにして再起動したら治った

Nested Virtualizationは…?

NetworkManager + Softether VPN Client のメモ

なぜかホームディレクトリの片隅に落ちていたメモ

消そうと思ったけど一応上げとこう

NetworkManager + Softether VPN Client

VPN Client 起動

# vpnclient start

VPN 接続

$ vpncmd
> AccountConnect <connect>
> AccountStatusGet <connect>

dhcp 取得

# dhcpcd <virtual nic>

routing 追加

# ip route add <server ip> via <local gateway> dev <local nic>

NetworkManager

なぜかこれでmetric値が下がる

# nmcli connect reload
# nmcli connect up <virtual nic>

参考

https://blog.tiqwab.com/2021/09/22/setup-softether-client-linux.html

TypeScript で Web Components な modal をつくった

CC0-1.0 です

github.com

type ModalProps = 'open';

export class Modal extends HTMLElement {
  private _root: ShadowRoot;

  constructor() {
    super();
    this._root = this.attachShadow({ mode: 'closed' });
  }

  connectedCallback(): void {
    this.open = !['false', 'null', '0', '', null].includes(this.getAttribute('open'));
    this.render();
  }

  attributeChangedCallback(prop: ModalProps, oldValue: string, newValue: string): void {
    this.render();
  }

  static get observedAttributes(): ModalProps[] {
    return ['open'];
  }

  get open(): boolean {
    return this.hasAttribute('open');
  }

  set open(value) {
    if (value) {
      this.setAttribute('open', 'true');
    } else {
      this.removeAttribute('open');
    }
  }

  render(): void {
    const coverHTML = this.open ? '<div class="cover" id="cover"></div>' : '';
    const modalHTML = this.open ? '<div class="modal" id="modal"><slot></slot></div>' : '';
    const styleHTML = `
    <style>
    .cover {
      display: block;
      position: fixed;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
      background: rgba(0, 0, 0, 0.8);
      z-index: 2;
    }
    .modal {
      position: fixed;
      top: 100px;
      right: 0;
      left: 0;
      background: #fff;
      width: 600px;
      border-radius: 0.5em;
      margin: auto;
      padding: 2em;
      z-index: 3;
    }
    </style>
    `;
    this._root.innerHTML = `${styleHTML}<div>${coverHTML}${modalHTML}</div>`;

    const closeModal = () => {
      this.open = false;
    };
    const coverElm = this._root.getElementById('cover');
    coverElm?.addEventListener('click', closeModal);
  }
}

参考

Web Components

web.dev

modal

colers.jp

Windowsをインストールしたあとにやること

インストール時注意事項

ローカルアカウントでログインするために、インストール時にインターネット接続を行わない

インストール後

  • インターネット接続
  • プロダクトキー登録
  • Windowsアップデート
  • Chromeインストール
  • Caps2Ctrlインストール
  • Google日本語入力インストール
  • VSCodeインストール
  • WSL2/Ubuntuインストール
  • apt install git vim tmux ssh build-essential

JavaScriptのPromiseでループする

Promiseで、というのはasync/awaitを用いないという意味

これはasync/awaitを用いた1秒おきに30までFizzBuzzを表示し続けるコード

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const fizzBuzz = n => n % 15 === 0 ? 'FizzBuzz' : n % 3 === 0 ? 'Fizz' : n % 5 === 0 ? 'Buzz' : n;

let count = 1;
while(count <= 30) {
  await sleep(1000);
  console.log(fizzBuzz(count));
  count++;
}

これと概ね同じ動作を async/await を用いず、 Promise を陽に扱って実現したい

こうする

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const fizzBuzz = n => n % 15 === 0 ? 'FizzBuzz' : n % 3 === 0 ? 'Fizz' : n % 5 === 0 ? 'Buzz' : n;

const loop = count => {
  return sleep(1000).then(() => {
    console.log(fizzBuzz(count));
    return count + 1;
  }).then(count => {
    if(count > 30) { return; }
    return loop(count);
  });
};
loop(1);

キューに突っ込む順番とか違いそうだけど概ね同じ動作をする

TypeScript/JavaScript で Union Find (Disjoint Set)

使うために書いたので型付けとか適当

export type UnionFind = {
  readonly size: number;
  parents: number[];
  ranks: number[];
  tree_sizes: number[];
}

export const UnionFind = {
  new(n: number): UnionFind {
    return {
      size: n,
      parents: [...Array(n)].map((v, i) => i),
      ranks: [...Array(n)].map(() => 0),
      tree_sizes: [...Array(n)].map(() => 1),
    };
  },

  size(uf: UnionFind): number {
    return uf.size;
  },

  unite(uf: UnionFind, a: number, b: number): boolean {
    let aroot = UnionFind.root(uf, a);
    let broot = UnionFind.root(uf, b);
    if (aroot === broot) { return false; }
    if (uf.ranks[aroot] < uf.ranks[broot]) {
      [aroot, broot] = [broot, aroot];
    }
    if (uf.ranks[aroot] === uf.ranks[broot]) {
      uf.ranks[aroot]++;
    }
    uf.tree_sizes[aroot] += uf.tree_sizes[broot];
    uf.parents[broot] = aroot;
    return true;
  },

  are_united(uf: UnionFind, a: number, b: number): boolean {
    return UnionFind.root(uf, a) === UnionFind.root(uf, b);
  },

  group_size(uf: UnionFind, n: number): number {
    return uf.tree_sizes[UnionFind.root(uf, n)];
  },

  groups(uf: UnionFind): number[][] {
    const groups = [...Array(uf.size)].map((): number[] => []);
    [...Array(uf.size)].forEach((_, i) => UnionFind.root(uf, i));
    uf.parents.forEach((p, i) => groups[p].push(i));
    return groups.filter(a => a.length !== 0);
  },

  root(uf: UnionFind, n: number): number {
    const p = uf.parents[n];
    if (p == n) {
      return n;
    }
    return uf.parents[n] = UnionFind.root(uf, p);
  }
};

github.com

call/ccでジェネレータを実装

最初に特化したジェネレータを返す関数を実装し、それを一般化する

数値をインクリメントしつつ無限ループする関数を返す関数を書く

(define (make-counter)
  (lambda ()
    (let rec ((c 0))
      (rec (+ c 1)))))

これに途中で中断できるように call/cc を追加する

(define (make-counter)
  (lambda ()
    (call/cc (lambda (return)
      (let rec ((c 0))
        (return c)
        (rec (+ c 1)))))))

また再開できるように call/cc を追加し、継続を保存して値を返す

(define (make-counter)
  (let ((restart #f))
    (lambda ()
      (call/cc (lambda (return)
        (let rec ((c 0))
          (call/cc (lambda (restart-cont)
            (set! restart restart-cont)
            (return c)))
          (rec (+ c 1))))))))

2回目以降の呼び出しは再開用継続を呼び出すようにする

(define (make-counter)
  (let ((restart #f))
    (lambda ()
      (if restart
          (restart)
          (call/cc (lambda (return)
            (let rec ((c 0))
              (call/cc (lambda (restart-cont)
                (set! restart restart-cont)
                (return c)))
              (rec (+ c 1)))))))))

またreturn用継続を呼び出しごとに更新する

(define (make-counter)
  (let ((return #f ) (restart #f))
    (lambda ()
      (call/cc (lambda (return-cont)
        (set! return return-cont)
        (if restart
            (restart)
            (let rec ((c 0))
              (call/cc (lambda (restart-cont)
                (set! restart restart-cont)
                (return c)))
              (rec (+ c 1)))))))))

これで数値をインクリメントしつつ返すジェネレータを実装できたので、これを一般化する

ジェネレータ本体部分で再開用継続を保存しつつ値を返せればいいので、これをクロージャにして引数として本体に渡して完成

(define (make-generator proc)
  (let ((return #f) (restart #f))
    (lambda ()
      (call/cc (lambda (return-cont)
        (set! return return-cont)
        (if restart
            (restart)
            (proc (lambda (x)
              (call/cc (lambda (cc)
                (set! restart cc)
                (return x)))))))))))

使い方

(define counter
        (make-generator (lambda (yield)
          (let rec ((c 0))
            (yield c)
            (rec (+ c 1))))))

(counter) ;; => 0
(counter) ;; => 1
(counter) ;; => 2