Category: 未分類

【PCクラスタ】【Tensorflow】Harvesterを使って研究室用AWSモドキを作る②

前準備: harvester GUIでの設定 ログイン設定 後々にVMを作った際にユーザー名とパスワードを決めておかないとログインできません。そこでCloud configuration templeteにVMの情報のテンプレートを作っておきます。また、SSHでアクセスするための設定もここに書いておきます。大体こんな感じで書けば良いです。(調整に丸一日費やした)。また、画像は割愛しますが、AdvancedのSSH keysにも同じ内容の公開鍵を登録しておきます。 VMからGPUへアクセスするための設定 AdvancedのPCI Devicesには様々なPCI接続されたデバイスがあります。このうちNvidiaで検索して引っかかったものをかたっぱしからEnabledに変更すると良いでしょう。これをやっておかないとVMを作った後に苦しみます。 ネットワークの設定 後々にSSHでアクセスするためには静的にアドレスを振っておくと都合が良いです。左側のNetworksからVirtual Machine Networksを選択してCreateを押し, Basicsを以下のようにしましょう。またRouteでは静的なアドレスとGatewayを指定します。 VM用imageファイルを取得する VMを作るには, その元となるイメージが必要です。AWSでもUbuntuだったりAmazon Linuxだったりが選べますが, 自作する場合でも同じです。ここで必要になるのはUbuntuのイメージファイルなのですが, 公式のUbuntu24.04などはVM用に最適化されておらず, 起動後に複雑な設定が必要になります。しかも, うまく動かないこともザラです。そこで, cloudに最適化されたUbuntu imageを使用します (https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img)。 harvesterのGUIからimage->createと進んで, URLを記入してください。これでcreateすれば, GUI側でイメージをDLして使用できるようにしてくれます。…

【アプリ開発】Node.jsとPythonを使ったアプリを作る#2

こんにちは。RockinWoolです。前回の続きということで、今回はFrontendのjavascriptとbackendのpythonを同期させて行こうと思います。それでは早速はじめていきましょう。 Flaskのインストールとサーバのセットアップ それではまず、backend環境を作るためにFlaskをインストールしていきます。自分はanaconda環境でやっているのでcondaで入れていきます。 新しいフォルダ構成でアプリを再構築する 前回のcreate-react-appでのReactアプリの構築では、最新のnodejsをビルドできないことが判明したのでビルドツールをviteに変更します。新しくmaze_gameという親フォルダを作ってその中に移動したら次のコマンドでViteプロジェクトを作ります。 ここまででViteサンプルアプリが動くようになります。 迷路側(frontend)の作成 index.html まずはindex.htmlから順番に作っていきます。Viteになったことで最初に起動させるエントリーポイントJavascriptのファイルがmain.jsxになっています。今回も慣例にしたがってmain.jsxを起動させるようにします。 main.jsx エントリーポイントです。ここではReactの初期設定を行い、アプリケーション全体をブラウザにレンダリングします。 2行目のReactDOMとはなんぞや?と思って調べてみたら、DOM(Document Object Model)という概念についてChatGPTが教えてくれました。Reactはhtmlの要素(Node)を動的に変更することで画面を変化させているということを知らなかったので、DOMによってNodeの塊として表現されているhtmlを変化させるためにReactDOMが必要なんだと理解することができました。3行目はルートコンポーネントであるApp.jsxをインポートすることを宣言しているそうですが、拡張子抜きで宣言するのに違和感があります。6行目ではレンダリング対象を宣言していますが、index.htmlで<div id=”root”></div>と宣言したroot要素を対象にすると言っています。<React.StrictMode>は開発モード機能であると宣言しているので、本番ビルドでは対象ではないと言っています。App /はAppをレンダリングするということらしいですので、次はApp.jsxについて見ていきます。 App.jsx 実態はcomponent/Maze.jsxに記述しているので、これは単純に仲介役を果たすファイルです。 最後のexport default App;でfunction App()を他のjsxから呼び出せるようにしています。 component/Maze.jsx 今回の開発で最もキモとなった部分の1つです。前回はここに迷宮情報を格納して迷路を作っていましたが、backend側に迷宮情報を持たさたほうが良いと判断して、frontend起動時にサーバから迷路情報を取得するように変更しました。そして、Enterを押したら自動で決められた動きをするように変更しています。 backend/server.py 最後にbackend側の実装を行っていきます。backend側は迷宮情報を渡すmaze関数と自動移動を行うmavoe関数を実装します。 vite.config.js Viteで起動したときに通信をどうするかを定義します。 ここまでで一通り動くものが作れました。いやーコードばっかりになってしまい申し訳無いです。次回はコードの詳しい解説と自動移動関数の強化学習を目標にしようと思います。それではまた次回!

【アプリ開発】Node.jsとPythonを使ったアプリを作る#1

こんにちはRockinWoolです。最近は頭痛も落ち着いていろいろなことに打ち込めるようになってきました。人生山あり谷ありですが、今は山なんだなあと感じています。さて、今日からはPythonを使ったブラウザアプリを作って行こうと思います。まずはアプリの構成ですが、ChatGPTに質問したら以下のような回答が帰ってきました。 なるほどなるほど。それでは今回はReact.jsを使用してフロントエンドを作って、バックエンドはFlaskという構成でやっていこうと思います。 node.jsのインストール React.jsのインストールをするためには、前提としてnodejsのインストールが必要とのことでした。なので、nodejsを入れていこうと思います。今回の環境はUbuntu20.04です。まずは以下のコマンドを実行します。 ここまで実行すればnodeコマンドやnpmコマンドが実行できるようになると別のサイトには書いてあったのですが、自分の環境では以下のエラーが出ました。 第一感では、このエラーはPATHの通っていないところにnodeがインストールされた結果発生しているのでは無いかと考えられました。なので、地道にPATHが充分か調査してみます。 このコマンドでnodeが存在していることは確定しました。次はnodeのinstallに使ったnの位置です。 こちらにもnodeがいることがわかります。ただし、こちらにある方が本物です。というのもsudo apt install nodejsでインストールできるnodeはversion10と非常に古いのでnコマンド経由で22.12.0をインストールするようにしたのが最初のコマンド群でした。ということで、こちらをPATHに追加していきます。以下のコマンドを.bashrcとターミナルの両方に打ち込んでPATHを登録します。 プロジェクトの作成 React.jsを使ったアプリの作成は以下のコマンドで実行します。 ここで–forceオプションをつけるのはreactのバージョンによってはうまく行かない依存関係が発生してしまうためです。このアプリの名前はmaze_gameとしました。迷路ゲームを作ろうと思っているので。さて、ここで`cd maze_game`してnpm startでアプリを起動!のつもりがまだ依存が解決していないとかで怒られました。私の場合は以下のコマンドで解決できました。 迷路部分の実装 ここから先はあまり詳しくはないので、いろいろ調査しながら作りました。まずnpm startを実行した際の挙動としては というステップを踏んでいます。したがってApp.jsに具体的にフロントエンドで実装したいことを書いていきます。ただし、直接App.jsに書くとsrcディレクトリの中が汚れそうだったのでsrc/componentsディレクトリを作って、その中にMaze.jsという本体を書いていくことにしました。したがってApp.jsとMaze.jsの中身はこんな感じになります。 App.js Maze.js App.jsはMaze.jsを呼び出しているだけなので、今回はそんなに重要ではないです。本題となるのはMaze.jsの方で、ここには大きく分けて3つの要素が含まれています。 迷宮の地図 キーボードを入力した際の動き 最初は1.1の座標からスタートすることを言っています。handleKeyDownはキーボード入力を拾っています。それからplayerPosを直接更新することはせずに一回tempとしてnewPosを定義しています。let newPos = の部分がそれで、playerPos=newPosとするとplayerPos=2としたときにnewPosも2になってしまう問題があるため、PlayerPosの中身(..playerPos)を配列で囲むことによって同じ配列を作っています。後は入力e.keyの種類によってx,yを更新してPlayerPosに入れています。 迷路とプレイヤーの描画…

【Atcoder日記】ABC #329のメモ

こんにちは。最近Pythonとc++の連携ができるようになってからc++の技術が上がってきたと感じているので、今日は久し振りにAtcoderに手を出してみました。Python軸でAtcoderに参加していた時は、制限時間の壁があまりにもキツすぎて解けているのに間に合わないということがよくありました。その点C++であれば問題ない!はず。結果としては60分でABCの3問正解という感じでした。(頭痛のせいで60分以上の作業は正直きつい)それでは、RockinWool自己流の解答をご笑覧あれ。 A問題(Spread) 難易度:超かんたん 入力文字に対して、スペースを開けて返答しろという非常に簡単な問題。A問題の中でも過去一簡単なのでは?と感じました。c++のstringの使い方さえ間違わなければ大丈夫。それと最後の文字以降にスペースを入れてはいけないとのことだったのでif文で分岐させました。(個人的には、この難易度でも20行近く書く必要のあるc++って不便だなと感じるなど) B問題(Next) 難易度: 普通 B問題はごく普通の難易度。もしかしたら過去と比べて簡単な方かもしれない。最大値の次に大きな数を答えるということで、最大値が複数ある場合にも対応できるかどうかが問われている。今回はvectorとsortを使って、入力を降順に並び替えたのちに最大値よりも小さくなった瞬間の数を返答するようにした。 C問題(Count xxx) 難易度: 比較的簡単 C問題は過去と比べかなり簡単な方かも。文字の組み合わせを答えろと言われているが、要は連続した同一文字からなる文字列の長さを足し合わせれば良い。例えばaaabbccだと3+2+2=7という感じ。問題はaaabbaaだと3+2=5となる点(aは3と2のパターンがあるが、大きい方を採用する)。この考え方を実現するにはa:3,b:2のようなpythonで言うdictionary型のデータが必要であることに気づく。ということはunordered_map<char,int>といったデータを用意して代入していけば良い。 この解答で少し不満なのは、ループ部分でi番目の文字とi+1番目の文字を比べている仕様上、最終文字とその直前が違う場合にif文を組まなければならない点。例えば最初のif文では入力が1文字である場合の例外を設けているし、以降にもif(i==inputstr.size()-2)の時に分岐するようにひと手間かけている。もう少し美しく書けたかもしれないが、制限時間中には思いつかなかった。しかし、過去のC問題に比べると例外処理の少なさから、非常に簡単な問題だったと感じる。ただ、個人的にはABC正答できたのは嬉しい。 結び 今回の問題は結構簡単に感じましたが、もしかしたら自分の能力が上がってきているのかもと自信が付きました。これからもpythonとc++をどんどん連携させて、c++をバリバリ書けるようになっていきたいですし、それを記事にしていこうと思いますので温かい目で見守ってください!それでは、よいプログラミング生活を!

DockerDesptopから画面を取るまで

今回はDocker Desktop for Linuxから画面を取るまでの試行錯誤、およびシンプルなdockerからの変更点などを解説します。4/15から4/24までの格闘日誌になります。ちょうど職場でのプレッシャが起因した休職に入ったのですが、今もすごく頭が痛いです。治るのかなこれ? 普通のDockerから画面を取る場合 普通のdockerから画面を取る場合は、下記3つが必要になります。 まずは1つ目、ソケットファイルの共有から解説します。まずはホストにあるソケットファイルの実体ですが、こちらは簡単に見つけることができます。先頭がd(directory)ではなく、s(socket)になっていることが証拠です。 2つめの$DISPLAY変数ですが、こちらはホストでは下記のようになっています。 $DISPLAY変数の構成は(ホスト名):(ディスプレイ番号).(スクリーン番号)で表現されます。今回はローカルホストであるため、ホスト名は省略されており、理由は良くわかりませんがスクリーン番号も省略されています。コンテナから画面を取る際も、localhostの画面へ表示を行いたいので$DISPLAY変数は同じで良いということですね。最後の画面表示の許可ですが、通常Xサーバへは決められたユーザしかログインできないのでそれを解除する作業になります。単純にxhost+と端末で入力するだけなので、非常に簡単な作業ではあります。ここまでの作業を自動でやってくれるプログラムはここで公開してあります。 DockerDesktopではうまく行かない 表題の通り、上記の手法をDockerDesktopで再現しようとしてみてもうまくいきません。エラーメッセージは下記の通りです。 このエラーは$DISPLAYで指定されている:0の画面へアクセスしようとしたら開けなかったというメッセージになり、通常はxhost + を行わなかった時に発生します。念の為xhost + を再度やってみても同じ回答が来るので、今回は違う原因で発生していると推測できます。幸いなことに、前回DockerDesktopは通常版とは違い、VM上で動作している説が発見できているので、今回は「別マシンから自マシン上へ画面を転送する」という技術で解決する必要がありそうです。 DockerDesktopからホストへのSSHを可能にする さて、情報の転送といえばSSHですね。今まで横着してSSH関連についてあまり勉強してこなかったのですが、今回はOpenSSH入門(河本安武さん著)を使ってしっかり活用して行こうと思います。まず、コンテナ側にあるアプリがssh-client, ローカルマシン側がssh-serverになるため、コンテナにopenssh-clientが入っているか確認しました。ここはデフォルトで入っていたので特筆する作業は無いです。一方でローカルホストの方にopenssh-serverが必要なのに入れていなくてかなり長い間格闘しました。ChatGPT先生の介抱もあってなんとか気づけたのですが、皆様もこのような初歩的なミスに引っかからないようにしましょう。ローカルホストへのssh-serverのインストールは下記の通りになります。 sudo apt install openssh-server ホスト上のSSH開通実験 まずはsshが正しく可能かどうか確認しましょう。私の場合、最初にこの開通実験を行っていなかったため、問題の切り分けに時間がかかりました。反省を兼ねてここで当たり前の確認作業を記述します。このセクションでやっておくべきことは「ホスト端末」→「ホスト端末」へのSSHが成功するかどうかの確認になります。これ自体は下記の方法で実行できます。 ssh username@localhost ホスト→コンテナへのSSH ホスト→ホストのSSHが成功することが確認できたあとは、ホスト→コンテナのSSHを試してみましょう。ちなみに私はここで躓きました。まずはエラーメッセージから。 $ssh…

C++とGRPC

2021/05/08こんにちは。RockinWoolです。最近外付けHDDの挙動がおかしかったので、もう一つ買ってきました。これで完璧。さて、今回はGRPC! と行きたいところです。ただ、そもそものC++周りの知識が全然無かったので、ひたすらそれを書いていこうかなという感じです。 まずは今回の目的であるgRPCの導入と、gRPCを使用する際に必要になるprotobufが使えるようにならないといけない。なので、そのあたりの環境構築からはじめる.参考2最初にcmakeのインストールを行う 次にgRPCのインストールを行う。まずはパス通しから .~bashrcにも追記する そして関連ツールのインストール そしてgRPCをクローンしてきてひたすらmakeする.ただし普通にビルドするとPCに負荷がかかり過ぎてフリーズすることがあった。そのため、cgroupで制約を課しながら、システムに余裕を持たせて実行すると良い。\ cgroup-toolsをインストールしたら、/etc/cgconfig.confを作成して、以下のように入力する 最後に設定を反映させたターミナルを起動する ターミナルが起動したら作業ディレクトリまで移動したのち、以下のコマンドを実行してビルドを行う 最後になぜかパーミッションがおかしい.pcファイルたちを移動しつつ権限を変更する それとPKG_CONFIG_PATHを指定しておかないと.pcファイルを読んでくれないので、これも指定する いちおうbashrcにも書いておく。 ここまでで、ようやくgrpcの作成環境が整えることができた。次はプログラミングである。ディレクトリ構成を以下のようにする このprotoディレクトリ内にrandom_walker.protoを用意する これを以下のコマンドでcppとhに変換する これで生成されるproto/random_walker.grpc.pb.hを見ると、134-140行目に関数の定義がされている