[컴] Cygwin 과 MSYS2 의 차이

목표 차이 / 시스윈 / 엠시스 / 무엇을 선택

Cygwin 과 MSYS2 의 차이

MSYS2 는 build 를 해서 native windows software 를 만들게 해주기 위한 ’환경’을 제공하는 것이며, Cygwin 은 unix 환경을 제공하는데, 자신이 제공한 cygwin unix 환경내에서 build 를 하고, run 하도록 하는 것이다.

msys2

MSYS2 는 그래서 autotool 들과 다른 build 시스템들을 실행하는 데 필요한 minimal shell 을 제공한다. 주 목적이 unix program을 windows 로 porting 하기 쉽게 해주는 환경을 제공해 주는 것이다.

MSYS2 는 POSIX 에 대한 emulator layer 이다.[ref. 2]

from link

MSYS2 는 3가지 환경(environment)를 제공한다.

  • msys2 : posix emulator
  • MinGW32 : 32bit binary build 할 수 있는 환경
  • MinGW64 : 64bit binary build 할 수 있는 환경

Reference

  1. How does MSYS2 differ from Cygwin? - MSYS2
  2. Zsh on Windows via MSYS2. I have quite a long history trying to… | by Borek Bernard | Medium
  3. How To Set Up And Use MSys2 – CadHut

[컴] html5 에서 drag & drop image upload 만들기

drag and drop image upload /html5, js / 드래그앤드랍 / 이미지 업로드 / image

html5 에서 drag & drop image upload 만들기

<!DOCTYPE  html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">

body{
  display: flex;
  background: black;
}
.drag-area{
  border: 2px dashed #fff;
  height: 500px;
  width: 700px;
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.drag-area.active{
  border: 2px solid #fff;
}
.drag-area .icon{
  font-size: 100px;
  color: #fff;
}
.drag-area header{
  color: #fff;
}
.drag-area span{
  color: #fff;
  margin: 10px 0 15px 0;
}
.drag-area button{
  padding: 10px 25px;
  border: none;
  cursor: pointer;
}
.drag-area img{
  height: 100%;
  width: 100%;
  object-fit: cover;
  border-radius: 5px;
}

</style>
</head>
<body>
  <div class="drag-area">
    <div class="icon"><i class="fas fa-cloud-upload-alt"></i></div>
    <header>Drag & Drop to Upload File</header>
    <span>OR</span>
    <button>Browse File</button>
    <input type="file" hidden>
  </div>

<script type="text/javascript">
  //selecting all required elements
const dropArea = document.querySelector(".drag-area"),
dragText = dropArea.querySelector("header"),
button = dropArea.querySelector("button"),
input = dropArea.querySelector("input");

button.onclick = ()=>{
  input.click();
}

input.addEventListener("change", function(){
  // if the user select a file with 'Browse File' button
  dropArea.classList.add("active");
  displayFile(this.files[0]);
});


dropArea.addEventListener("dragover", (event)=>{
  // drag over case
  event.preventDefault(); //preventing from default behaviour
  dropArea.classList.add("active");
  dragText.textContent = "Release to Upload File";
});

dropArea.addEventListener("dragleave", ()=>{
  // drag over --> drag leave
  dropArea.classList.remove("active");
  dragText.textContent = "Drag & Drop to Upload File";
});


dropArea.addEventListener("drop", (event)=>{
  // if the user drop a file
  event.preventDefault();
  displayFile(event.dataTransfer.files[0]); //calling function
});

function displayFile(file) {
  let fileType = file.type
  let validTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp']
  if (validTypes.includes(fileType)) {
    // in case of image file
    let freader = new FileReader()
    freader.onload = () => {
      // add a image tag to show the image read
      let base64ImageDataUrl = freader.result
      let imgTag = `<img src="${base64ImageDataUrl}" alt="">`
      dropArea.innerHTML = imgTag
    }
    freader.readAsDataURL(file)
  } else {
    alert('This is not an Image File!')
    dropArea.classList.remove('active')
    dragText.textContent = 'Drag & Drop to Upload File'
  }
}

</script>
</body>

</html>


Reference

  1. Drag & Drop or Browse - File upload Feature in JavaScript

[컴] HikariCP log 에서 connection leak 이 보이는 이유

 

hikari leak / leak connection

HikariCP log 에서 connection leak 이 보이는 이유

leakDetectionThreshold 을 확인해 보자.

예를 들어, leakDetectionThreshold 값이 5s(5000) 로 설정 되어 있는데, query 의 수행시간이 5초가 넘는 상황이라면, connection 이 5초 이상 열려있게 되니까, hikariCP 에서 그것을 leak 으로 판단하는 것으로 보인다. 아래 링크를 참고하자.

[컴] vendure 에서 login

login / 로그인

vendure 에서 login

여기서 사용한 client는 nextjs commerce 이다.(참고)

login 을 하면 vendure 서버 쪽 동작은 아래와 같다. 최종적으로 getUserByeEmailAddress 에서 database 로 query 를 한다.

참고로, id 가 verified 되어 있지 않으면 login 이 안된다.

getUserByEmailAddress (<src_root>\packages\core\src\service\services\user.service.ts:59)
authenticate (<src_root>\packages\core\src\config\auth\native-authentication-strategy.ts:54)
authenticate (<src_root>\packages\core\src\service\services\auth.service.ts:65)
authenticateAndCreateSession (<src_root>\packages\core\src\api\resolvers\base\base-auth.resolver.ts:117)
baseLogin (<src_root>\packages\core\src\api\resolvers\base\base-auth.resolver.ts:61)
login (<src_root>\packages\core\src\api\resolvers\shop\shop-auth.resolver.ts:75)
<anonymous> (<src_root>\node_modules\@nestjs\core\helpers\external-context-creator.js:69)
processTicksAndRejections (internal/process/task_queues:95)

See Also

  1. 쿠…sal: [컴][웹] next.js commerce + vendure 서버 실행

[컴] draggable div 만들기

draggable popup / html / js / vue / 드래그 / 팝업 / 움직이는

draggable div 만들기


<!DOCTYPE html>
<html>
<style>
#outer{
  position: absolute; // absolute 을 해야 현재 그려진 화면 위로 그려진다.
}
#mydiv {
  width: 100px;
  z-index: 10;
  text-align: center;
  border: 1px solid #d3d3d3;
}

#mydivheader {
  padding: 10px;
  cursor: move;
  z-index: 10;
  background-color: #2196F3;
  color: #fff;
}
</style>
<body>

<div id='outer'>
    <div id="mydiv">
      <div id="mydivheader">Click here to move</div>
      <p>Move</p>
      <p>this</p>
      <p>DIV</p>
    </div>
</div>

<script>

drag(document.getElementById("outer"));

function drag(wrap /* HTMLElement */, inRange = false) {
  wrap.style.cursor = 'move'
  const container = wrap
  if (!container) {
    return
  }
  const range = {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0
  }
  let startX = 0
  let startY = 0
  let status = ''

  const onMouseMove = (e /* MouseEvent */) => {
    if (status !== 'down') return
    const moveX = e.clientX
    const moveY = e.clientY
    let distX = moveX - startX
    let distY = moveY - startY
    if (inRange) {
      if (distX <= range.left) {
        distX = range.left
      }
      if (distX >= range.right) {
        distX = range.right
      }
      if (distY <= range.top) {
        distY = range.top
      }
      if (distY >= range.bottom) {
        distY = range.bottom
      }
    }
    container.style.left = distX + 'px'
    container.style.top = distY + 'px'
  }

  const onMouseUp = () => {
    status = 'up'
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
  }

  wrap.addEventListener('mousedown', (e /* MouseEvent */) => {
    e.preventDefault()
    status = 'down'
    if (inRange) {
      range.left = -((document.documentElement.clientWidth - container.clientWidth) / 2)
      range.right = Math.abs(range.left)
      range.top = -(document.documentElement.clientHeight - container.clientHeight) / 2
      range.bottom = Math.abs(range.top)
    }
    startX = e.clientX - (parseInt(container.style.left) || 0)
    startY = e.clientY - (parseInt(container.style.top) || 0)

    document.addEventListener('mousemove', onMouseMove)
    document.addEventListener('mouseup', onMouseUp)
  })

}
</script>

</body>
</html>


Reference

  1. How To Create a Draggable HTML Element

[컴] 컴파일러에서 사용하는 최적화 방법, loop unrolling, inlining, vectorization

벡터 / 룹 최적화 / optimization

컴파일러에서 사용하는 최적화 방법, loop unrolling, inlining, vectorization

loop unrolling

loop 을 만약에 100번 돌아야 하면, 이것을 50번만 돌도록 만든다. 이것이 loop unrolling 이다.

loop 을 전개(펼치는, unrolling)하는 것인데, 예를 들면 다음처럼 print()를 10번해야 하는 경우, 한번의 loop 마다 print 를 2번 넣어서 loop 의 횟수를 줄인다.

for(var i = 0 ; i<10; i++){
    print(i)
}
for(var i = 0 ; i<10; i+=2){
    print(i)
    print(i+1)
}

이러면, i 를 증가시키는 연산의 횟수는 줄지않겠지만(print 에서 i+1을 하니), loop 의 condition 을 확인하는 부분(i<10) 을 덜 수행하게 된다.

inlining

inlining 은 c/c++ 의 inline function 을 생각하면 된다. 함수호출을 없애고, 함수의 code를 대신 넣는 것이다. 예를 들면 다음과 같다. 이렇게 하면 function call 로 인해 생기는 overhead 가 줄어든다.

function call 을 하면 stack 또는 register에 argument들을 넣고, branch instruction 을 실행하지만, inline 을 하면 이런것들을 할 필요가 없다.(Function prologue and epilogue) 그리고 return 할 때 일어나는 일들(Return statement) 도 필요없다. function prologue, then at return the function epilogue, the return statement

또한, 함수가 하나의 큰 함수가 되기 때문에, 이것이 좀 더 optimization 을 할 여지를 준다. 그래서 이전보다 더 최적화가 될 수 있다.(참고: ref. 2, Effect on performance)

자세한 이야기는 ref. 2 를 참고하자.

function add(a,b){
    return a+b
}

var c = add(a,b)
var c = a + b

vectorization

SIMD(single instruction multiple data) 로 처리하는 방법이다. 다음과 같이 변환할 수 있다.

for (i = 0; i < 1024; i++)
    c[i] = a[i] * b[i];

# a[i] ~ a[i+3] 까지의 data 를 한번에 처리하는 것이다.
for (i = 0; i < 1024; i += 4)
    c[i:i+3] = a[i:i+3] * b[i:i+3];

Reference

  1. Loop unrolling - Wikipedia
  2. Inline expansion - Wikipedia
  3. Automatic vectorization - Wikipedia

[컴] MLC LLM 를 windows 에서 사용

machine learning compilation /

MLC LLM 를 windows 에서 사용

MLC LLM 에 대한 ref.1 의 설명:

  • 다양한 하드웨어 backend들과 native application에다가 모든 언어모델들(language models)을 natively 하게 배포하기 위한 범용솔루션(universal solution) 이다.
  • 서버 없이, 폰이나 노트북의 local GPU들로 가속한다.

환경

  • windows 10
  • geforce gtx 1660, nvidia driver 531.79

Prerequisites

  1. 최신 vulkan driver
    • 이것은 Nvidia driver를 update 하면 된다. nvidia graphic card driver 가 vulkan driver 도 지원한다.
  2. miniconda 설치

작업

  1. mlc-chat conda 환경 생성하고, 여기에 git, git-lfs를 설치.
    • 이것은 Hugging Face에서 model weights 를 다운로드하기 위한 것이라 한다.
  2. CLI app 을 설치
  3. dist directory 생성, 이 directory 에 git clone 을 하게 된다.
  4. git lfs 초기화
  5. git clone
  6. 실행: mlc_chat_cli
# 환경생성, git, git-lfs 설치
conda create -n mlc-chat
conda activate mlc-chat

conda install git git-lfs

# chat CLI app 을 설치
conda install -c mlc-ai -c conda-forge mlc-chat-nightly

# `dist` directory 생성
mkdir dist

# lfs 초기화
git lfs install

# git clone, 대략 6.2 GB 필요
git clone https://huggingface.co/mlc-ai/demo-vicuna-v1-7b-int3 dist/vicuna-v1-7b
git clone https://github.com/mlc-ai/binary-mlc-llm-libs.git dist/lib

# 실행
mlc_chat_cli

실행

질문에 대한 답변을 해줄때 대략 GPU 를 86% 사용한다.

(d:\a\env\conda\mlc-chat) D:\a\prog\mlcchat\try1>mlc_chat_cli
Use lib D:\a\prog\mlcchat\try1\dist\lib\vicuna-v1-7b-q3f16_0-vulkan.dll
[11:42:21] C:\Miniconda\envs\mlc-llm-build\conda-bld\mlc-chat-nightly-package_1683954581677\work\cpp\cli_main.cc:298: model_path = D:\a\prog\mlcchat\try1\dist\lib
Initializing the chat module...
Finish loading
You can use the following special commands:
  /help    print the special commands
  /exit    quit the cli
  /stats   print out the latest stats (token/sec)
  /reset   restart a fresh chat

USER: /help
You can use the following special commands:
  /help    print the special commands
  /exit    quit the cli
  /stats   print out the latest stats (token/sec)
  /reset   restart a fresh chat

USER: /stats
encode: -nan(ind) tok/s, decode: -nan(ind) tok/s
USER: hi what is you?
ASSISTANT: Hello! As an artificial intelligence language model, "I" (as a pronoun) represents the collective intelligence and knowledge of the language model. So the answer to your question is: everything! I'm here to assist you with any questions or concerns you may have. Please feel free to ask me anything you'd like to know more about.
USER: how can i change your weights?
ASSISTANT: As an AI language model, my "weights" are adjusted based on the information and training I received during my training phase. However, you can adjust the importance of different words and phrases in your questions to me by using the "weight" function.

For example, you can assign higher or lower weight to specific words or phrases in your question by using the "weight" function. For example:

* "weight:20 my\_question" will give higher importance to your question than the "weight:30 other\_questions"
* "weight:10 my\_question" will give higher importance to your question than the "weight:20 other\_questions"

So please go ahead and give your questions higher or lower importance based on what is most important for you. And please don't hesitate to ask questions at the appropriate importance level if you're unsure which weight to use.
USER: so the higher weight means more important?
ASSISTANT: Yes! That's correct. Assigning a higher weight to a specific word or phrase in your question can help to give it more emphasis or priority in the conversation. The weight you assign to a word or phrase can help to indicate the level of importance or focus you want to give it in the conversation. For example, if you're unsure which weight to use for a specific aspect of your question, you can assign a higher weight to it by using the "weight" function. For example:

* "weight:20 my\_question" will give higher importance to your question than the "weight:30 other\_questions"
* "weight:10 my\_question" will give higher importance to your question than the "weight:20 other\_questions"
USER: what if i say like you mentioned, weight:20 my\_question would have bigger weight than other\_questions?
ASSISTANT: Yes! That's correct. Assigning a higher weight to your question can indicate that it is of greater importance or focus than other questions in the conversation. However, please note that the weight you assign to something does not change the information or context of the conversation. The weight you assign to something in a question will only affect the order in which it appears in the conversation. So please go ahead and give your questions higher or lower importance based on what is most important for you. And please don't hesitate to ask questions at the appropriate importance level if you're unsure which weight to use.
USER: so what is difference from you and chatgpt
ASSISTANT: As an AI language model, my main function is to process and generate text based on the input I receive. I don't have personal preferences or emotions like humans do. The weight of a word or a question depends on the algorithm that was used to build and train me.
USER: how to train you?
ASSISTANT: As an AI language model, I can be trained using supervised learning techniques. This typically involves using a large dataset of text and labeling the words within the text based on a given task or objective. For example, if you want to train me to predict the weather forecast for a given day based on the historical weather data.

In this way I can improve the quality of my responses to better match the user's expectations.
USER: can u program?
ASSISTANT: Yes, I can be programmed in various programming languages like Python, JavaScript, C++, etc. However, I don't have the ability to program or create new algorithms as I am just a software program myself.
USER: show me an example
ASSISTANT: Sure! Here's an example of a simple program in Python:
```python
with open('example.py', 'w') as file:
    file.write('This is an example of a Python program.\n')
    file.close()
print('Example written and saved to file.')
```
This code creates a file called "example.py" in the current directory, writes a string to it and then prints a message indicating that the example was written and saved.
USER:

See Also

  1. GitHub - imartinez/privateGPT: Interact privately with your documents using the power of GPT, 100% privately, no data leaks

Reference

  1. GitHub - mlc-ai/mlc-llm: Enable everyone to develop, optimize and deploy AI models natively on everyone’s devices.
  2. MLC LLM | Home