本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138859732
FunctionCall.h
1 |
|
FunctionCall.cpp
1 |
|
LocalScriptFile.h
1 |
|
LocalScriptFile.cpp
1 |
|
test.lua
1 | getMissingListFont |
使用示例
1 |
|
创作不易,小小的支持一下吧!


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138859732
1 | #include <sstream> |
1 |
|
1 |
|
1 |
|
1 | getMissingListFont |
使用示例
1 | #include "LocalScriptFile.h" |


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138815353
https://github.com/lilipads/gradient_descent_viz
#include <math.h>
#include
namespace Function {
enum FunctionName {
local_minimum, // 许多小坑
global_minimum, // 大坑
saddle_point, // 起伏山路
ecliptic_bowl, // 起伏大坑
hills, // 大坑 + 小坑 + 山谷
plateau // 大坑 + 波纹
};
}
class Point {
public:
Point() : x(0.), z(0.) {}
Point(double x1, double z1) : x(x1), z(z1) {}
double x;
double z;
};
const float kBallRadiusPerGraph = 24.63;
class GradientDescent {
public:
GradientDescent();
virtual ~GradientDescent() {}
double learning_rate = 0.001;
static Function::FunctionName function_name;
// simple getters and setters
Point position() { return p; }
void setStartingPosition(double x, double z) { starting_p.x = x; starting_p.z = z; }
bool isConverged() { return is_converged; };
double gradX() { return grad.x; };
double gradZ() { return grad.z; };
Point gradPosition() { return grad; };
Point delta() { return m_delta; }
// core methods
static double f(double x, double z);
Point takeGradientStep();
void resetPositionAndComputeGradient();
protected:
Point p; // current position
Point starting_p; // starting position
Point m_delta; // movement in each direction after a gradient step
Point grad; // gradient at the current position
bool is_converged = false;
void setPositionAndComputeGradient(double x, double z);
void computeGradient();
virtual void updateGradientDelta() = 0;
virtual void resetState() {}
};
class VanillaGradientDescent : public GradientDescent {
public:
VanillaGradientDescent() {}
protected:
void updateGradientDelta();
};
class Momentum : public GradientDescent {
public:
Momentum() {}
double decay_rate = 0.8;
protected:
void updateGradientDelta();
};
class AdaGrad : public GradientDescent {
public:
AdaGrad() {}
Point gradSumOfSquared() { return grad_sum_of_squared; }
protected:
void updateGradientDelta();
void resetState();
private:
Point grad_sum_of_squared;
};
class RMSProp : public GradientDescent {
public:
RMSProp() {}
double decay_rate = 0.99;
Point decayedGradSumOfSquared() { return decayed_grad_sum_of_squared; }
protected:
void updateGradientDelta();
void resetState();
private:
Point decayed_grad_sum_of_squared;
};
class Adam : public GradientDescent {
public:
Adam() {}
double beta1 = 0.9;
double beta2 = 0.999;
Point decayedGradSum() { return decayed_grad_sum; }
Point decayedGradSumOfSquared() { return decayed_grad_sum_of_squared; }
protected:
void updateGradientDelta();
void resetState();
private:
Point decayed_grad_sum;
Point decayed_grad_sum_of_squared;
};
const double kDivisionEpsilon = 1e-12;
const double kFiniteDiffEpsilon = 1e-12;
const double kConvergenceEpsilon = 1e-2;
Function::FunctionName GradientDescent::function_name = Function::local_minimum;
GradientDescent::GradientDescent()
{
resetPositionAndComputeGradient();
}
double GradientDescent::f(double x, double z) {
switch (function_name) {
case Function::local_minimum: {
z *= 1.4;
return -2 * exp(-((x - 1) * (x - 1) + z * z) / .2) -
6. * exp(-((x + 1) * (x + 1) + z * z) / .2) +
x * x + z * z;
}
case Function::global_minimum: {
return x * x + z * z;
}
case Function::saddle_point: {
return sin(x) + z * z;
}
case Function::ecliptic_bowl: {
x /= 2.;
z /= 2.;
return -exp(-(x * x + 5 * z * z)) + x * x + 0.5 * z * z;
}
case Function::hills: {
z *= 1.4;
return 2 * exp(-((x - 1) * (x - 1) + z * z) / .2) +
6. * exp(-((x + 1) * (x + 1) + z * z) / .2) -
2 * exp(-((x - 1) * (x - 1) + (z + 1) * (z + 1)) / .2) +
x * x + z * z;
}
case Function::plateau: {
x *= 10;
z *= 10;
double r = sqrt(z * z + x * x) + 0.01;
return -sin(r) / r + 0.01 * r * r;
}
}
return 0.;
}
void GradientDescent::computeGradient() {
// use finite difference method
grad.x = (f(p.x + kFiniteDiffEpsilon, p.z) -
f(p.x - kFiniteDiffEpsilon, p.z)) / (2 * kFiniteDiffEpsilon);
grad.z = (f(p.x, p.z + kFiniteDiffEpsilon) -
f(p.x, p.z - kFiniteDiffEpsilon)) / (2 * kFiniteDiffEpsilon);
}
void GradientDescent::resetPositionAndComputeGradient() {
is_converged = false;
m_delta = Point(0, 0);
resetState();
setPositionAndComputeGradient(starting_p.x, starting_p.z);
}
void GradientDescent::setPositionAndComputeGradient(double x, double z) {
/* set position and dirty gradient */
p.x = x;
p.z = z;
computeGradient();
}
Point GradientDescent::takeGradientStep() {
/* take a gradient step. return the new position
* side effects:
* - update delta to the step just taken
* - update position to new position.
* - update grad to gradient of the new position
*/
if (abs(gradX()) < kConvergenceEpsilon &&
abs(gradZ()) < kConvergenceEpsilon) {
is_converged = true;
}
if (is_converged) return p;
updateGradientDelta();
setPositionAndComputeGradient(p.x + m_delta.x, p.z + m_delta.z);
return p;
}
void VanillaGradientDescent::updateGradientDelta() {
m_delta.x = -learning_rate * grad.x;
m_delta.z = -learning_rate * grad.z;
}
void Momentum::updateGradientDelta() {
/* https://en.wikipedia.org/wiki/Stochastic\_gradient\_descent#Momentum */
m_delta.x = decay_rate * m_delta.x - learning_rate * grad.x;
m_delta.z = decay_rate * m_delta.z - learning_rate * grad.z;
}
void AdaGrad::updateGradientDelta() {
/* https://en.wikipedia.org/wiki/Stochastic\_gradient\_descent#AdaGrad */
grad_sum_of_squared.x += pow(grad.x, 2);
grad_sum_of_squared.z += pow(grad.z, 2);
m_delta.x = -learning_rate * grad.x / (sqrt(grad_sum_of_squared.x) + kDivisionEpsilon);
m_delta.z = -learning_rate * grad.z / (sqrt(grad_sum_of_squared.z) + kDivisionEpsilon);
}
void AdaGrad::resetState() {
grad_sum_of_squared = Point(0, 0);
}
void RMSProp::updateGradientDelta() {
/* https://en.wikipedia.org/wiki/Stochastic\_gradient\_descent#RMSProp */
decayed_grad_sum_of_squared.x *= decay_rate;
decayed_grad_sum_of_squared.x += (1 - decay_rate) * pow(grad.x, 2);
decayed_grad_sum_of_squared.z *= decay_rate;
decayed_grad_sum_of_squared.z += (1 - decay_rate) * pow(grad.z, 2);
m_delta.x = -learning_rate * grad.x / (sqrt(decayed_grad_sum_of_squared.x) + kDivisionEpsilon);
m_delta.z = -learning_rate * grad.z / (sqrt(decayed_grad_sum_of_squared.z) + kDivisionEpsilon);
}
void RMSProp::resetState() {
decayed_grad_sum_of_squared = Point(0, 0);
}
void Adam::updateGradientDelta() {
/* https://en.wikipedia.org/wiki/Stochastic\_gradient\_descent#Adam */
// first moment (momentum)
decayed_grad_sum.x *= beta1;
decayed_grad_sum.x += (1 - beta1) * grad.x;
decayed_grad_sum.z *= beta1;
decayed_grad_sum.z += (1 - beta1) * grad.z;
// second moment (rmsprop)
decayed_grad_sum_of_squared.x *= beta2;
decayed_grad_sum_of_squared.x += (1 - beta2) * pow(grad.x, 2);
decayed_grad_sum_of_squared.z *= beta2;
decayed_grad_sum_of_squared.z += (1 - beta2) * pow(grad.z, 2);
m_delta.x = -learning_rate * decayed_grad_sum.x /
(sqrt(decayed_grad_sum_of_squared.x) + kDivisionEpsilon);
m_delta.z = -learning_rate * decayed_grad_sum.z /
(sqrt(decayed_grad_sum_of_squared.z) + kDivisionEpsilon);
}
void Adam::resetState() {
decayed_grad_sum_of_squared = Point(0, 0);
decayed_grad_sum = Point(0, 0);
}
void print(std::string title, const Point& pt) {
double scrollOffset = 2000;
double yOffset = scrollOffset / kBallRadiusPerGraph;
yOffset = 0;
std::cout << title << “(“ << pt.x << “, “ << GradientDescent::f(pt.x, pt.z) + yOffset << “, “ << pt.z << “)” << std::endl;
}
void test() {
// 可用于滑动后缓动慢停止
VanillaGradientDescent vanillaGradientDescent;
vanillaGradientDescent.learning_rate = 0.01; //速度
vanillaGradientDescent.function_name = Function::global_minimum; // 场景
vanillaGradientDescent.setStartingPosition(100, 100); // 顶部起始位置
vanillaGradientDescent.resetPositionAndComputeGradient(); // 更新梯度和当前位置
print(“pt”, vanillaGradientDescent.position());
print(“gradient”, vanillaGradientDescent.gradPosition());
print(“delta”, vanillaGradientDescent.delta());
for (size_t i = 0; i < 60; i++)
{ // 60次
vanillaGradientDescent.takeGradientStep();
print(“pt”, vanillaGradientDescent.position());
print(“gradient”, vanillaGradientDescent.gradPosition());
print(“delta”, vanillaGradientDescent.delta());
}
// 可用于滑动后反弹多次逐渐停止
Momentum momentum;
momentum.learning_rate = 0.01; //速度
momentum.decay_rate = 0.9; // 摩擦系数, 1表示理想情况,无摩擦
momentum.setStartingPosition(100, 100); // 顶部起始位置
momentum.resetPositionAndComputeGradient(); // 更新梯度和当前位置
print(“pt”, momentum.position());
print(“gradient”, momentum.gradPosition());
print(“delta”, momentum.delta());
for (size_t i = 0; i < 60; i++)
{ // 200次
momentum.takeGradientStep();
print(“pt”, momentum.position());
print(“gradient”, momentum.gradPosition());
print(“delta”, momentum.delta());
}
}


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138804447
sketch禁用了lineGap
https://www.sketch.com/docs/designing/text/
http://www.sketchcn.com/sketch-chinese-user-manual.html
https://github.com/sketch-hq/sketch-document
https://developer.sketch.com/file-format/
https://animaapp.github.io/sketch-web-viewer/
https://developer.sketch.com/reference/api/#group
https://sketchplugins.com/
https://unpkg.com/browse/@sketch-hq/sketch-file-format@6.2.0/dist/file-format.schema.json
https://github.com/orgs/sketch-hq/repositories?page=2
https://www.yuque.com/design-engineering/sketch-dev/tt9mzm
https://medium.com/bumble-tech/translating-interfaces-into-almost-fifty-languages-sketch-dc196cf23ee5


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138801794
Oneapi应用——并行排序实践_oneapi和openmpi-CSDN博客
https://github.com/oneapi-src/oneTBB
https://oneapi-src.github.io/oneTBB/
https://www.oneapi.io/open-source/ // 其它异构工具平台
tbbmalloc:内存分配,类似于chrome的tcmalloc
map-reduce: 多线程并行计算
psort: 并行排序
auto test_vector = get_random_vector();
oneapi::tbb::parallel_sort(test_vector, std::greater
graph:流程任务图,任务前置,后置,依赖。
group:任务组
queue:串行任务队列
hash_map:并行查询插入容器
vs编译:
oneTBB\integration\windows\oneapi\vars.bat
https://github.com/AdaptiveCpp/AdaptiveCpp


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138790651
GitHub - sogou/workflow: C++ Parallel Computing and Asynchronous Networking Framework
示例代码:
#include <stdio.h>
#include “workflow/WFHttpServer.h”
#include
#include <condition_variable>
#include
#include “workflow/WFAlgoTaskFactory.h”
#include
#include “workflow/WFTaskFactory.h”
#include “workflow/WFFacilities.h”
#pragma comment(lib, “ws2_32.lib”)
#pragma comment(lib, “libssl.lib”)
#pragma comment(lib, “libcrypto.lib”)
#pragma comment(lib, “Mswsock.lib”)
static void __arr_init(int* arr, int n)
{
srand(time(NULL));
for (int i = 0; i < n; i++)
arr[i] = rand() % 65536;
}
void parallelSort() {
static constexpr int n = 100000;
int* arr = new int[n];
__arr_init(arr, n);
std::mutex mutex;
std::condition_variable cond;
bool done = false;
auto* task = WFAlgoTaskFactory::create_psort_task(“psort”, arr, arr + n, [&mutex, &cond, &done](WFSortTask
int* first = task->get_input()->first;
int* last = task->get_input()->last;
mutex.lock();
done = true;
mutex.unlock();
cond.notify_one();
});
task->start();
std::unique_lockstd::mutex lock(mutex);
while (!done)
cond.wait(lock);
lock.unlock();
delete[]arr;
}
static SubTask* create_task(int& target)
{
static std::atomic
return WFTaskFactory::create_timer_task(0, [&](WFTimerTask*)
{
target = generator++;
});
}
void graphTask() {
WFFacilities::WaitGroup wait_group(1);
auto graph = WFTaskFactory::create_graph_task([&wait_group](WFGraphTask*) { wait_group.done(); });
constexpr int N = 4096 - 1;
auto target = new int[N];
auto node = new WFGraphNode * [N];
for (int i = 0; i < N; i++)
node[i] = &graph->create_graph_node(create_task(target[i]));
for (int i = 1; i < N; i++)
node[i]->precede(*node[(i - 1) / 2]);
graph->start();
wait_group.wait();
delete[] target;
delete[] node;
}
int test()
{
parallelSort();
graphTask();
WFHttpServer server([](WFHttpTask* task) {
task->get_resp()->append_output_body(“Hello World!
});
if (server.start(8888) == 0) { // start server on port 8888
getchar(); // press “Enter” to end.
server.stop();
}
return 0;
}


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138770701


本文作者原创,首发在本博客;CSDN 上的同名文章已标注为转载并回链到本页:https://blog.csdn.net/qq_30220519/article/details/138729514
https://cdrdv2-public.intel.com/772402/onetbb_cookbook_2021.6-772401-772402.pdf
https://cdrdv2-public.intel.com/816904/onetbb_get-started-guide_2021.12-772618-816904.pdf
https://blog.51cto.com/shijianfeng/5152901
// 同构,多进程
https://github.com/microsoft/Microsoft-MPI // 消息传递接口 (MPI)
https://github.com/rabauke/mpl // 同类,Boost.MPI
MPICH | High-Performance Portable MPI
// 同构,多线程任务计算
https://github.com/ClearLove27149/TaskCpp
https://github.com/ddemidov/compute // GPU计算
https://github.com/oneapi-src/oneTBB#stable-releases // tbb
https://github.com/intel/tbb // tbb
// 异构,并行任务计算,支持流程
https://taskflow.github.io/taskflow/index.html
https://github.com/taskflow/taskflow.git
#include <taskflow/taskflow.hpp>
#include
// // Offload Tasks to a GPU
//__global__ void saxpy(int n, float a, float* x, float* y) {
// int i = blockIdx.x * blockDim.x + threadIdx.x;
// if (i < n) {
// y[i] = a * x[i] + y[i];
// }
//}
int test() {
tf::Executor executor;
tf::Taskflow taskflow;
auto [A, B, C, D] = taskflow.emplace( // create four tasks
[]() { std::cout << “TaskA\n”; },
[]() { std::cout << “TaskB\n”; },
[]() { std::cout << “TaskC\n”; },
[]() { std::cout << “TaskD\n”; }
);
tf::Task E = taskflow.emplace([](tf::Subflow& subflow) { // subflow task B
tf::Task B1 = subflow.emplace([]() {}).name(“B1”);
tf::Task B2 = subflow.emplace([]() {}).name(“B2”);
tf::Task B3 = subflow.emplace([]() {}).name(“B3”);
B3.succeed(B1, B2); // B3 runs after B1 and B2
}).name(“B”);
A.precede(B, C); // A runs before B and C
D.succeed(B, C, E); // D runs after B and C
// creates a feedback loop {0: cond, 1: stop}
tf::Task stop = taskflow.emplace([]() {}).name(“stop”);
tf::Task cond = taskflow.emplace([]() { return std::rand() % 2; }).name(“cond”);
cond.precede(cond, stop); // moves on to ‘cond’ on returning 0, or ‘stop’ on 1
//tf::Task cudaflow = taskflow.emplace([&](tf::cudaFlow& cf) {
// tf::cudaTask h2d_x = cf.copy(dx, hx.data(), N).name(“h2d_x”);
// tf::cudaTask h2d_y = cf.copy(dy, hy.data(), N).name(“h2d_y”);
// tf::cudaTask d2h_x = cf.copy(hx.data(), dx, N).name(“d2h_x”);
// tf::cudaTask d2h_y = cf.copy(hy.data(), dy, N).name(“d2h_y”);
// tf::cudaTask saxpy = cf.kernel((N + 255) / 256, 256, 0, saxpy, N, 2.0f, dx, dy)
// .name(“saxpy”); // parameters to the saxpy kernel
// saxpy.succeed(h2d_x, h2d_y)
// .precede(d2h_x, d2h_y);
// }).name(“cudaFlow”);
// Compose Task Graphs
tf::Taskflow f1, f2;
// create taskflow f1 of two tasks
tf::Task f1A = f1.emplace([]() { std::cout << “Task f1A\n”; }).name(“f1A”);
tf::Task f2B = f2.emplace([]() { std::cout << “Task f2B\n”; }).name(“f2B”);
tf::Task f1_module_task = f2.composed_of(f1).name(“module”);
f1_module_task.succeed(f1A, f2B)
.precede(f1A);
// tf::Future
// run_once.get(); // wait on this run to finish
executor.run(taskflow).wait();
// create asynchronous tasks directly from an executor
std::future
std::cout << “async task returns 1\n”;
return 1;
});
executor.silent_async([]() { std::cout << “async task does not return\n”; });
// create asynchronous tasks with dynamic dependencies
tf::AsyncTask AA = executor.silent_dependent_async([]() { printf(“A\n”); });
executor.wait_for_all();
// run the taskflow four times
executor.run_n(taskflow, 4);
// runs the taskflow five times
executor.run_until(taskflow, [ counter = 5]() mutable { return –counter == 0; });
// standard parallel CPU algorithms
//std::vector
//tf::Task task1 = taskflow.for_each( // assign each element to 100 in parallel
// data.begin(), data.end(), [](auto& i) { i = 100; }
//);
//tf::Task task2 = taskflow.reduce( // reduce a range of items in parallel
// data.begin(), data.end(), data.begin(), [](auto a, auto b) { return a + b; }
//);
//tf::Task task3 = taskflow.sort( // sort a range of items in parallel
// data.begin(), data.end(), [](auto a, auto b) { return a < b; }
//);
//// create a pipeline to propagate five tokens through three serial stages
//tf::Pipeline pl(“num_lines”,
// tf::Pipe{ tf::PipeType::SERIAL, [](tf::Pipeflow& pf) {
// if (pf.token() == 5) {
// pf.stop();
// }
// } },
// tf::Pipe{ tf::PipeType::SERIAL, [](tf::Pipeflow& pf) {
// printf(“stage 2: input buffer[%zu] = %d\n”, pf.line(), buffer[pf.line()]);
// } },
// tf::Pipe{ tf::PipeType::SERIAL, [](tf::Pipeflow& pf) {
// printf(“stage 3: input buffer[%zu] = %d\n”, pf.line(), buffer[pf.line()]);
// } }
//);
//taskflow.composed_of(pl)
// executor.run(taskflow).wait();
// dump the graph to a DOT file through std::cout
taskflow.dump(std::cout);
return 0;
}


tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent:
meta: false
pages: false
posts:
title: true
date: true
path: true
text: false
raw: false
content: false
slug: false
updated: false
comments: false
link: false
permalink: false
excerpt: false
categories: false
tags: true