放着女武神final的live 写这一篇游记,女武神真的是神企划,五位都太会唱了,以后会不会再遇到这样的企划了呢?也珍惜跑live的机会吧

这次时隔五年赴日,主要是去看三场 event :

  • 1.26 プロジェクトセカイ COLORFUL LIVE 3rd - Evolve - 東京 1/26 夜公演
  • 1.27 VOCALOCK MANIA ver.2
  • 1.28 リスアニ!LIVE 2024 SUNDAY STAGE

1.23

飞机下午到了羽田,这次全程住在秋叶原附近的 御徒町 urban hotel。
晚上找 widyy 和两位声优厨朋友在秋叶原吃饭,吃了有些奇怪的肉寿司

IMG_20240123_193000.jpg

1.24

一早去了神田明神,买了个御守
上午跟 widyy 大逛秋叶原
下午去新宿看了一场地偶,晚上在新宿逛逛

1.25

白天继续逛秋叶原,下午去了趟浅草寺
晚上去东京塔顺便看 liella! 联动活动
出来之后跑了一下少歌巡礼
IMG_20240125_200155.jpg

1.26

上午和马哥去上野看莫奈展
有一百多幅莫奈的真迹是真的强,看过的展出里含金量最高的一次
晚上跑到幕张去看pjsk live

不得不说这次 pjsk live 如果是从 pjsk 粉丝的角度来看应该是很出色的一场live,各方面的环节都能看出来主办的用心:定制的六芒星call棒,live中的屏幕背景,转场,甚至最后的彩带
与之相比魔法未来就寒酸到有炒冷饭的感觉了。。。
但从术力口粉丝的角度来看,却是明显地感觉到 pjsk 的去术化
全场大多数曲子都是烤的原创曲,术曲的比例相比前两次大大减少了,粉丝群体也是比较饭圈化,实际上让我比较震惊的是参加live的人里女生比例极高,这就是日本原神吗。。。
live之后带着一种复杂的心情,live本身很用心,烤的声优里也有很多我喜欢的,但是还是会让我觉得我不属于这里
带着微妙的心情回到了宾馆
IMG_20240126_203936.jpg

1.27

全天是 VOCALOCK MANIA 的活动,上午在台场简单巡礼了一下虹
是神event,下次还来!
术力口正统在P主活动!

开场是SEE,这位不熟
中间在等mikito大家都没走,果然mikito在日也很火,第一首バレリーコ,最后和锁那唱了小っちゃな私,mikito很帅,锁那很可爱,但好像锁那的麦有点问题
mikito结束之后走了一些人,得以混到前排k看ねじ式,neji穿了件很喜庆的衣服,很多熟悉的歌,蹦得很爽。然后也看了なきそ,本人看起来是社恐角色,但很会打碟。
然后跑去隔壁买场贩,并没有想象中的排队。倒不如说除了mikito其他人都不用排队。先买了一二三的碟,一二三本人十分池面,帮忙签了to签。然后排mikito,mikito这次没卖碟,只好买了一个刺绣钱包要签名,然后跟mikito聊天,日语苦手而且紧张,我说我是中国人,从北京来,mikito直接来了句中文,我惊讶问居然会中文,mikito说会一点,不过当时也不应该奇怪,毕竟是写了一二fanclub的男人。然后去买neji,neji签完之后还特意用袋子把碟装好,非常有职业素养。出来转了会之后又回去帮Ne老师带neji的碟,然后发现可能是买得太多,neji好像认识我了,我说我从中国来,然后neji看起来很感动地说是特意从中国过来跑这个活动吗?我说是(虽然也跑了别的live)neji说他过段时间可能会来上海,我说好好好。这次好像体会到了近战地爽点x
然后去听了 R Sound Design,之后去看シオダ的talk,因为太累了不小心睡着了,对不起シオダ
然后听羽生まぬご的talk,まぬご好会作曲。

Kokkos 是 C++ library

hierarchy :
device, host-parallel, host-serial

同步:
Kokkos::fence()

两个问题:

  1. memory space : device / host
  2. memory layout : LayoutLeft / LayoutRight

DualView : 维护在 device memory 上的 Kokkos::View 和其在 host memory 上的 Kokkos::View mirror,同时维护在两个不同 memory space 的 data

  • template argument:DataType, Layout, Device
  • using view_type = Kokkos::DualView<Scalar**, Kokkos::LayoutLeft, Device>

原子操作相关

scatter-add :两个粒子共享邻居,当两个粒子同时更新邻居时可能造成 race
使用 data replication V.S. 使用 atomic operation 解决 race 问题
ScatterView : 在编译时透明地选择处理原子操作方法,对于 CPU 使用 data replication,对于 GPU 使用 atomic operation

`Kokkos::Experimental::contribute(View &dest, Kokkos::Experimental::ScatterView
const &src) 将 ScatterView 的 reduction 结果放回到 dest,可能在 Kokkos::parallel_reduce()` 后调用

检查 Kokkos 属性

判断 layout :

  if (std::is_same<typename decltype(fpair->f)::traits::array_layout, Kokkos::LayoutLeft>::value) {
    printf("array fpair->f is LayoutLeft\n");
  }
  if (std::is_same<typename decltype(fpair->f)::traits::array_layout, Kokkos::LayoutRight>::value) {
    printf("array fpair->f is LayoutRight\n");
  }

获取 stride :

  int strides[2];
  (fpair->x).stride(strides);
  printf("array fpair->x stride : (%d, %d)\n", strides[0], strides[1]);

Access traits

RandomAccess : Kokkos::MemoryTraits<Kokkos::RandomAccess> ,当在 Cuda execution space 中执行时, 如果对于在 CudaSpaceCudaUVMSpace 中的 const View,Kokkos 会使用 texture fetch 访问

Unmanaged View : Kokkos::MemoryTraits<Kokkos::Unmanaged>, 对于一个 raw pointer, Kokkos 不进行 reference counting 和 deallocation

CPU 结构:
threads per core : 超线程
cores per socket : 每个 socket 核数
sockets

MPI

每个 mpi 进程有 affinity mask,长度为 CPU cores
--bind-to core : affinity mask 中只有对应 core 一位被 set
--bind-to socket : affinity mask 中 socket 对应 所有 core 被 set
--bind-to none

--map-by node
--map-by socket
--map-by node:PE=8 : PE为每个进程分配的物理核数

多机

hostfile :

i1 slots=2 max-slots=8
i2 slots=2 max-slots=8
`which mpirun`  -np 2 --host i1:1,i2:1 hostname
`which mpirun` -np 4 --hostfile ./hostfile hostname

使用脚本时开头要加 #!/bin/bash

OMP

OMP_DISPLAY_ENV=true 输出 OMP 绑定情况
OMP_PLACES=threads, OMP_PLACES=cores,
OMP_PLACES=sockets

hyperthread cpu 分布:/sys/devices/system/cpu/cpu0/topology$ cat thread_siblings_list

#include <omp.h>
#include <sched.h>

    #pragma omp parallel 
    {
        int id = omp_get_thread_num();
        int max_threads = omp_get_num_threads();
        int cpuid = sched_getcpu();
        printf("hello from cpu: %d thread: %d out of %d threads @ rank = %d\n", cpuid, id, max_threads, rank);
    }

19 年时候学OOP(?)时候的post,更新一下记录一下遇到的新的设计模式:

std::enable_if

用 std::enable_if 增加一个新的函数参数
利用 SFINAE (Substitution Failure Is Not An Error)
模板替换失败不会报错,只会使对应模板不存在

template<int val>
void func(int x, typename std::enable_if<val, int>::type y) {
    printf("in func yes %d\n", x);
}

template<int val>
void func(int x, typename std::enable_if<!val, int>::type y) {
    printf("in func no %d\n", x);
}

int main() {
    func<0>(123, 123);
    
}

当 enable_if 为 false 时,std::enable_if<!val, int> 不存在 type 参数,模板替换错误,此时函数不存在

https://www.runoob.com/design-pattern/design-pattern-intro.html

委托模式


class I /*interface*/ {
public:
    virtual void f() = 0;
    virtual void g() = 0;
};

class A : public I {
public:
    void f(){std::cout << "A::f()" << std::endl;}
    void g(){std::cout << "A::g()" << std::endl;}
};

class B : public I {
public:
    void f(){std::cout << "B::f()" << std::endl;}
    void g(){std::cout << "B::g()" << std::endl;}
};


class C : public I {
public:
    C() { m_i = new A();/*delegation*/ }

    void f(){ m_i->f(); }
    void g(){ m_i->g(); }

    // normal attributes
    void toA(){ m_i = new A(); }
    void toB(){ m_i = new B(); }

private:
    I* m_i;
}

工厂模式

public class ShapeFactory {

   //使用 getShape 方法获取形状类型的对象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

CRTP

静态多态



template 
struct base
{
    void interface()
    {
         // ...
         static_cast(this)->implementation();
         // ...
    }
};
 
struct derived : base
{
     void implementation()
     {
         // ...
     }
};

visitor模式

将数据与对数据的操作分离


//前向声明,访问者
class Visitor;

//被访问的抽象类,只有一个接口,用来接受访问者
class Object
{
public:
    virtual void accept(Visitor&v) = 0;
};

//具体的被访问的对象,学生。
class StudentA :public Object
{
    std::string name;
    int score;
public:
    StudentA(std::string name_);
    int getScore();
    std::string getName()
    {
        return name;
    }
    void setScore(int num);
    virtual void StudentA::accept(Visitor & v)
    {
        v.visit(this);
    }
};

//抽象访问者,只有一个接口,访问.
class Visitor
{
public:
    virtual void visit(Object* obj)=0;

};

//具体的访问者一,班主任,实现访问(学生并给学分)
class ClassLeader :public Visitor
{
public:
    virtual void visit(Object* obj);
};
//具体的访问者二,校长,实现访问(学生并批评不及格的学生)
class HeadMaster :public Visitor
{
public:
    virtual void visit(Object* obj);
};

observer模式

一些观察者观察一个数据,当数据被改动时通知所有观察者


public class Subject {
   
   private List observers 
      = new ArrayList();
   private int state;
 
   public int getState() {
      return state;
   }
 
   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }
 
   public void attach(Observer observer){
      observers.add(observer);      
   }
 
   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }  
}
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}
public class BinaryObserver extends Observer{
 
   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "Binary String: " 
      + Integer.toBinaryString( subject.getState() ) ); 
   }
}