2024.8.25 ~ 9.3 东京圈夏日生活
あぁ! 夏を今もう一回
いまが最高!
时间追溯到几个月前,之前就一直想去一次ASL现场,没去上23年的觉得还是有点可惜的,所以就在想今年跑一趟。公布阵容的时候发现 day3 的阵容很想看:闹闹,TRUE老师,minori,ReoNa ,爱喵,asaka,还有南球和 fripside。所以拜托马哥帮忙搞票。后来又追加了北宇治和B小町,阵容就更加无敌了。
あぁ! 夏を今もう一回
いまが最高!
时间追溯到几个月前,之前就一直想去一次ASL现场,没去上23年的觉得还是有点可惜的,所以就在想今年跑一趟。公布阵容的时候发现 day3 的阵容很想看:闹闹,TRUE老师,minori,ReoNa ,爱喵,asaka,还有南球和 fripside。所以拜托马哥帮忙搞票。后来又追加了北宇治和B小町,阵容就更加无敌了。
Kokkos 是 C++ library
hierarchy : device
, host-parallel
, host-serial
同步:Kokkos::fence()
两个问题:
DualView : 维护在 device memory 上的 Kokkos::View
和其在 host memory 上的 Kokkos::View
mirror,同时维护在两个不同 memory space 的 data
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()` 后调用
判断 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]);
RandomAccess
: Kokkos::MemoryTraits<Kokkos::RandomAccess>
,当在 Cuda
execution space 中执行时, 如果对于在 CudaSpace
或 CudaUVMSpace
中的 const View,Kokkos 会使用 texture fetch 访问
Unmanaged View
: Kokkos::MemoryTraits<Kokkos::Unmanaged>
, 对于一个 raw pointer, Kokkos 不进行 reference counting 和 deallocation
19 年时候学OOP(?)时候的post,更新一下记录一下遇到的新的设计模式:
用 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;
}
}
静态多态
template
struct base
{
void interface()
{
// ...
static_cast(this)->implementation();
// ...
}
};
struct derived : base
{
void implementation()
{
// ...
}
};
将数据与对数据的操作分离
//前向声明,访问者
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);
};
一些观察者观察一个数据,当数据被改动时通知所有观察者
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() ) );
}
}
It is important to note
so when
essentially
additionally
in addition
moving on to
we observe ...
peak FP64 : 9.7TFLOPS
peak FP32 : 19.5 TFLOPS
peak FP16 : 78 TFLOPS
peak TF32 tensor core : 156 TFLOPS
192KB L1 cache (shared memory) / SM
40MB L2 cache
40GB 主存, 1555GB/s 带宽
PCIe 4 : 31.5GB/s