hive的TRANSFORM操作

Transform/Map-Reduce Syntax

hive语言中内置的特性是支持用户自定义mappers/redulers的。 用户可以使用TRANSFROM 子句来内嵌mapper/reduer脚本的。

By default, columns will be transformed to STRING and delimited by TAB before feeding to the user script; similarly, all NULL values will be converted to the literal string \N in order to differentiate NULL values from empty strings. The standard output of the user script will be treated as TAB-separated STRING columns, any cell containing only \N will be re-interpreted as a NULL, and then the resulting STRING column will be cast to the data type specified in the table declaration in the usual way. User scripts can output debug information to standard error which will be shown on the task detail page on hadoop. These defaults can be overridden with ROW FORMAT ….

注意:

Formally, MAP … and REDUCE … are syntactic transformations of SELECT TRANSFORM ( … ). In other words, they serve as comments or notes to the reader of the query. BEWARE: Use of these keywords may be dangerous as (e.g.) typing “REDUCE” does not force a reduce phase to occur and typing “MAP” does not force a new map phase!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
clusterBy: CLUSTER BY colName (',' colName)*
distributeBy: DISTRIBUTE BY colName (',' colName)*
sortBy: SORT BY colName (ASC | DESC)? (',' colName (ASC | DESC)?)*

rowFormat
: ROW FORMAT
(DELIMITED [FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[ESCAPED BY char]
[LINES SEPARATED BY char]
|
SERDE serde_name [WITH SERDEPROPERTIES
property_name=property_value,
property_name=property_value, ...])

outRowFormat : rowFormat
inRowFormat : rowFormat
outRecordReader : RECORDREADER className

query:
FROM (
FROM src
MAP expression (',' expression)*
(inRowFormat)?
USING 'my_map_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
( clusterBy? | distributeBy? sortBy? ) src_alias
)
REDUCE expression (',' expression)*
(inRowFormat)?
USING 'my_reduce_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?

FROM (
FROM src
SELECT TRANSFORM '(' expression (',' expression)* ')'
(inRowFormat)?
USING 'my_map_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
( clusterBy? | distributeBy? sortBy? ) src_alias
)
SELECT TRANSFORM '(' expression (',' expression)* ')'
(inRowFormat)?
USING 'my_reduce_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?

转化的例子1:

FROM ( FROM pv_users MAP pv_users.userid, pv_users.date USING 'map_script' AS dt, uid CLUSTER BY dt) map_output INSERT OVERWRITE TABLE pv_users_reduced REDUCE map_output.dt, map_output.uid USING 'reduce_script' AS date, count; FROM ( FROM pv_users SELECT TRANSFORM(pv_users.userid, pv_users.date) USING 'map_script' AS dt, uid CLUSTER BY dt) map_output INSERT OVERWRITE TABLE pv_users_reduced SELECT TRANSFORM(map_output.dt, map_output.uid) USING 'reduce_script' AS date, count;

转化的例子2:

FROM ( FROM src SELECT TRANSFORM(src.key, src.value) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.TypedBytesSerDe' USING '/bin/cat' AS (tkey, tvalue) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.TypedBytesSerDe' RECORDREADER 'org.apache.hadoop.hive.contrib.util.typedbytes.TypedBytesRecordReader' ) tmap INSERT OVERWRITE TABLE dest1 SELECT tkey, tvalue

将TRANSFORM的输出打出来

脚本的输出默认是string,如果想进行类型转换的需要进行如下操作。

SELECT TRANSFORM(stuff) USING 'script' AS thing1, thing2

类型转化
SELECT TRANSFORM(stuff) USING 'script' AS (thing1 INT, thing2 INT)

hive权威指南学习笔记

Hive操作

本篇文章是对 https://cwiki.apache.org/confluence/display/Hive/GettingStarted#GettingStarted-DDLOperations

以及

《Hive编程指南》的学习总结

  1. DDL Operations (data defination language)
  • create table pokes (foo INT, bar STRING);
  • create table invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);

partition column 是一个虚拟列,并不是数据本身的一部分,但是可以获得某一份特定数据集。

  • show tables;
  • show tables ‘.*s’
  • describe invites;
  1. DML Operations (data manipulation language)

2.1 装载数据

  • LOAD DATA LOCAL INPUT ‘./examples/files/kv1.txt’ OVERWRITE INTO TABLE pokes;
  • LOAD DATA LOCAL INPATH ‘./examples/files/kv2.txt’ OVERWRITE INTO TABLE invites PARTITION (ds=’2008-08-15’);
  • LOAD DATA LOCAL INPATH ‘./examples/files/kv3.txt’ OVERWRITE INTO TABLE invites PARTITION (ds=’2008-08-08’);

LOCAL 表明这是在本地文件系统上的文件;如果没有的话,那么就从hdfs上获取文件。

OVERWRITE 表明表中已经存在的数据将会被删除。 如果没有的话,数据文件被添加到已经存在的数据集合中。

2.2 通过查询语句插入数据

  • FROM staged_employees se INSERT OVERWRITE TABLE employee PARTITION (country = 'US' and state = 'OR') select * where se.country = 'US' and se.state = 'OR' INSERT OVERWRITE TABLE employee PARTITION (country = 'US' and state = 'CA') select * where se.country = 'US' and se.state = 'CA'

动态分区插入

前面的语法中有一个问题,即:如果需要创建非常多的分区,那么用户就需要写非常多的SQL。
幸运的是:Hive提供了一个动态分区功能,可以基于查询参数推断出需要创建的分区名称。相比之下,前面看到的都是静态分区。

INSERT OVERWRITE TABLE employees PARTITION (country, state) SELECT ..., se.cnty, se.st FROM staged_employees se;

注意:Hive 根据SELECT语句中最后2列来确定分区字段country和state的值。
而不是根据命名来匹配的。

在SQL语句使用不同的命名就是为了强调源表字段值和输出分区值直接的关系是根据位置而不是根据命名来匹配的。

2.3 单个查询语句中创建表并加载数据

  • create table u_data_v2 as SELECT userid, rating from u_data limit 10;

2.4 导出数据

  • INSERT OVERWRITE LOCAL DIRECTORY ‘/tmp/hive’ SELECT userid, rating FROM u_data;
  1. SQL操作

SELECT … FROM 语句

3.1 数据类型

当用户选择的列是集合数据类型时,Hive会使用JSON语法进行输出。

  • 当列是一个数组时,其值使用一个括在[...]的逗号分隔的列进行表示,如[“Mary Smith”, “Todd Jones”]
  • 当列是一个Map时,使用JSON格式来表达map,即使用一个被括在{...}内的以逗号分隔的键值对列表进行表示;如 {"Federal Taxes":0.2 "State Taxes": 0.05}
  • 当列是一个Struct时,使用map格式来表示,如{"Federal Taxes":0.2 "State Taxes": 0.05}

引用元素的方式:

  • 引用Map元素,使用ARRAY[…]语法;
  • 引用Struct的一个元素,使用符号。

3.2 使用函数

3.3 列别名

如果新产生的结果在源表中不存在的话,通常有必要给这些新产生的列起一个名称,也就是别名。

  • select userid as uid from u_data;

3.4 嵌套SELECT 语句

FROM ( SELECT upper(name), salary ,deductions["Federal Taxes"] as fed_taxes FROM employees ) e SELECT e.name, e.fed_taxes where e.name = "yan"

从这个嵌套语句中可以看到,我们将前面的结果集起了个别名,称之为e,在这个语句外面嵌套查询了name fed_taxes两个字段。 同时约束name必须是yan。

3.5 CASE … WHEN … THEN 句式

CASE .. WHEN .. THEN 语句和if条件语句类似,用于处理单个列的查询结果。

SELECT userid, movieid, CASE WHEN rating <= 1 THEN "low" WHEN rating > 1 and rating <= 3 THEN "middle" ELSE "high" END as level from u_data limit 10;

4. WHERE 语句 (对应Hive编程指南的6.2 WHERE语句)

4.1 WHERE语句不能使用列别名

SELECT name, salary, salary * (1-deductions["Federal Taxes"]) as salary_minus_fed_taxes FROM employees WHERE round(salary * (1-deductions["Federal Taxes"])) > 70000

这个查询语句里面,有重复的表达式。下面的查询语句使用一个列别名来消除重复问题,但是并不能生效。

SELECT name, salary, salary * (1-deductions["Federal Taxes"]) as salary_minus_fed_taxes FROM employees WHERE round(salary_minus_fed_taxes) > 70000; 报错:Invalid table alias or column reference 'salary_minus_fed_taxes'

正如错误信息所提示的,WHERE语句不能使用列别名
不过我们可以使用一个嵌套的SELECT语句

SELECT e.* FROM (SELECT name,salary, salary * (1-deductions["Federal Taxes"]) as salary_minus_fed_taxes FROM employees) e WHERE round(e.salary_minus_fed_taxes) > 70000;

4.2 谓词操作符

4.3 GROUP BY语句

GROUP BY 通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每个组执行聚合操作。

4.4 JOIN 语句

Hive支持通常的SQL JOIN语句,但是只支持等值连接,并且在ON子句中只支持AND。

4.4.1 INNER JOIN

SELECT a.ymd, a.price_close, b.price_close, c.price_close FROM stocks a JOIN stocks b ON a.ymd = b.ymd JOIN stocks c ON a.ymd = c.ymd WHERE a.symbol = 'AAPL' AND b.symbol = 'IBM' AND c.symbol = 'GE';

在这个例子中,会首先启动一个MapReduce job对表a和表b进行连接操作,然后会再启动一个MapReduce job将第一个MapReduce job的输出和表c进行连接操作。

Hive表总是按照从左到右的顺序执行的。

JOIN优化

Hive同时假定查询中最后一个表是最大的那个表。在对每行记录进行连接操作时,它会尝试将其他表缓存起来,然后扫描最后那个表进行计算。

因此用户需要保证连续查询中的表的大小是从左到右依次增加的

LEFT OUTER JOIN

OUTER JOIN

RIGHT OUTER JOIN

FULL OUTER JOIN

LEFT SEMI-JOIN

笛卡尔积JOIN

map-side JOIN

4.5 ORDER BY 和 SORT BY

4.6 含有SORT BY 的DISTRIBUTE BY

4.10 UNION ALL

UNION ALL将2个或多个进行合并。每个union子查询都必须有相同的列,并且每个字段的字段类型必须是一致的。

比如,如果第2个字段是FLOAT类型,那么所有其他子查询的第2个字段必须都是FLOAT类型的。

举例,将日志数据进行合并的例子:

SELECT log.ymd, log.level, log.message FROM( SELECT l1.ymd, l1.level, l1.message, 'Log1' AS source FROM log1 l1 UNION ALL SELECT l2.ymd, l2.level, l2.message, 'Log2' AS source FROM log2 l2 ) log SORT BY log.ymd ASC;

5 视图(hive编程指南第7章 视图)

3.3 一些用法

  • SELECT a.* FROM invites a WHERE a.ds=’2008-08-15’;
  • FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;
  • CREATE TABLE u_data (
    userid INT,
    movieid INT,
    rating INT,
    unixtime STRING)
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ‘\t’
    STORED AS TEXTFILE;

  • LOAD DATA LOCAL INPATH ‘/Users/keything/Downloads/ml-100k/u.data’ OVERWRITE INTO TABLE u_data;

  • SELECT COUNT(*) FROM u_data;

一个简单的例子:

创建表:

1
2
3
4
5
6
7
8
CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

获取数据集

1
2
wget http://files.grouplens.org/datasets/movielens/ml-100k.zip
unzip ml-100k.zip

加载数据集

1
LOAD DATA LOCAL INPATH '<path>/u.data' OVERWRITE INTO TABLE u_data;

创建weekday_mapper.py

1
2
3
4
5
6
7
8
import sys
import datetime

for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split('\t')
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '\t'.join([userid, movieid, rating, str(weekday)])

对于这个脚本是否正确,可以通过自己创建文件来验证。

创建mapper脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

add FILE weekday_mapper.py;

INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (userid, movieid, rating, unixtime)
USING 'python weekday_mapper.py'
AS (userid, movieid, rating, weekday)
FROM u_data;

SELECT weekday, COUNT(*)
FROM u_data_new
GROUP BY weekday;

最后得到

1
2
3
4
5
6
7
1	12254
2 13579
3 14430
4 15114
5 14743
6 18229
7 11651

hadoop权威指南第四版学习笔记

Hadoop权威指南第四版-学习笔记

第二章 关于MapReduce

MapReduce是一种可用于数据处理的编程模型。

Hadoop将MapReduce的输入数据划分成等长的小数据块,称为输入分片(input split) 或简称“分片”。hadoop为每个分片构建一个map任务,并由该任务来运行用户自定义的map函数,从而处理分片中的每条记录。

一个合理的分片大小趋向于HDFS的一个块的大小,默认是128MB。

map任务将其输出写入本地硬盘,而非HDFS。这是为什么呢 ?

因为map的输出是中间结果:该中间结果由reduce任务处理后才产生最终输出结果,而且一旦作业完成,map的输出结果就可以删除。 因此,如果把map输出存储在HDFS中并实现备份,难免有些小题大做。

如果运行map任务的节点在map中间结果传送给reduce任务之前失败,hadoop将在另一个节点重新运行这个map任务以再次构建map中间结果。

reduce任务并不具备数据本地化的优势,单个reduce任务的输入通常来自于所有mapper的输出。

reduce任务的数量并不是由输入数据的大小决定,相反是独立指定的。
如果有多个reduce任务,每个map任务就会针对输出进行分区(partition),即为每个reduce任务建一个分区,每个分区有许多键(及其对应的值),但每个键对应的key-value 都在同一个分区中。 用户可以使用自定义的分区函数控制分区,但通常使用默认的partitioner 通过哈希函数来区分,很高效。

一般情况下,多个reduce任务的数据流如图2-4所示,该图清楚表明了为什么map任务和reduce任务之间的数据流成为shuffle(混洗),因为每个reduce任务的输入都来自许多map任务。shuffle一般比图中所示的更复杂,而且调整混洗参数对作业总执行时间的影响非常大。

第三章 Hadoop分布式文件系统

3.2 HDFS概念

3.2.1 数据块

HDFS同样也有块block的概念,默认是128MB。

3.2.2 namenode和datanode

HDFS集群有两类节点,以 管理节点-工作节点 模式运行,即一个namenode(管理节点)和多个datanode(工作节点)。
namenode 管理文件系统的命名空间。它维护者文件系统树及整颗树内所有的文件和目录。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件和编辑日志文件。

namenode也记录着每个文件中各个块所在的数据节点信息,但它并不用就保存块的位置信息,因为这些信息会在系统启动时根据数据节点信息重建。

datanode是文件系统的工作节点。他们根据需要存储并检索数据块(受客户端或namenode调度),并且定期向namenode发送所存储的块的列表。

3.2.3 块缓存
3.2.4 联邦HDFS
3.2.5 HDFS的高可用性

3.3 命令行接口

3.4 Hadoop 文件系统

3.5 Java接口

3.6 数据流

3.6.1 剖析文件读取
3.6.2 剖析文件写入
3.6.3 一致性模型

第4章 关于YARN

Apache YARN(Yet Another Resource Negotiator的缩写)是Hadoop的集群资源管理系统。

第5章 Hadoop的I/O 操作

5.1 数据完整性
5.2 压缩

5.2.1 codec
5.2.2 压缩和输入分片

5.4 基于文件的数据结构

第6章 MapReduce应用开发

MapReduce编程遵循一个特定的流程。首先写map函数和reduce函数,最好使用单元测试来确保函数的运行符合预期。 然后写一个驱动程序来运行作业。

第7章 MapReduce的工作机制

7.3 shuffle和排序

MapReduce确保每个reducer的输入都是按键排序的。

系统执行排序、将map输出作为输入传给reducer的过程称为shuffle。

7.3.1 map端

map函数开始产生输出时,并不是简单地将它写到磁盘。这个过程更复杂,利用缓冲的方式写到内存并出于效率的考虑进行预排序。
每个map任务都有一个环形内存缓冲区用于存储任务输出。在默认情况下,缓冲区大小是100mb。一旦缓冲内容达到阈值,一个后台线程便开始把内容溢出到splill到磁盘。

在溢出写到磁盘过程中,map输出继续写到缓存区,但如果在此期间缓冲区被填满,map会被阻塞直到写磁盘过程完成。

在写磁盘之前,线程首先根据数据最终要传的reduer 将数据划分成相应的分区(partition)。在每个分区中,后台线程按键进行内存中排序,如果有一个combiner函数,它就在排序后的输出上运行。运行combiner函数使得map输出结果更紧凑。

每次内存缓冲区达到溢出阈值,就会新建一个溢出文件spill file,因此在map任务写完最后一个输出记录之后,会有几个溢出文件。

7.3.2 reduce端

7.4 任务的执行

第8章

8.1 MapReduce的类型

Hadoop的MapReduce中,map函数和reduce函数遵循如下常规格式:

map:(k1, v1) -> list(k2, v2)
combiner: (k2, list(v2)) -> list(k2, v2)
reduce:(k2, list(v2)) -> list(k3, v3)

spark的sql学习

Spark SQL, DataFrames and Datasets Guide

##概述:

Spark SQL时候spark中处理结构化数据的模块。

Spark SQL可以从已经安装好的hive中读取数据,也可以通过命令行 or JDBC/ODBC 读取数据。

Datasets and DataFrames:

Dataset 是数据的分布式集合(A Dataset is a distributed collection of data)。Dataset可以从JVM对象中构建,也可以使用转化进行操作(transformations 如map,flatMap,filter 等等)。

DataFrame 是将Dataset组织为命名列(named columns),在python/R 中等同于关系型数据库中的表(table)。

DataFrame Operations:

df.printSchema()
df.select(“name”).show()
df.select(df[‘name’], df[‘age’] + 1).show()
df.filter(df[‘age’] > 21).show()
df.groupBy(“age”).count().show()

Running SQL Queries Programmatically

在SparkSession中的sql函数会执行sql查询语句,并返回 DataFrame的结果。
sqlDF = spark.sql(“SELECT * FROM people”)
sqlDF.show()

Programmatically Specifying the Schema

官方引导的方式个人感觉有点繁琐。 http://spark.apache.org/docs/latest/sql-programming-guide.html#programmatically-specifying-the-schema

可以使用to.DF()的方式来做。

org.apache.spark.sql.types._
1
2
3
4
5
6
7
8
9
10
11
12
from pyspark.sql import Row

lines = sc.textFile("file:///usr/local/Cellar/spark/2.0.1/examples/src/main/resources/people.txt")
parts = lines.map(lambda l: l.split(","))
peoples = parts.map(lambda p: Row(name=p[0], age=p[1]))
peoples.toDF()

// Creates a temporary view using the DataFrame
peopleDF.createOrReplaceTempView("people")

// SQL can be run over a temporary view created using DataFrames
val results = spark.sql("SELECT name FROM people")

Data Sources

Spark SQL 通过DataFrame接口 支持不同类型的数据源。
将DataFrame注册为一个临时视图(temporary view),允许你可以通过SQL查询数据。
这部分描述的是加载和保存数据的通用方法,并会介绍built-in data sources的特殊选项。

Generic Load/Save Functions

1
2
df = spark.read.load("examples/src/main/resources/users.parquet")
df.select("name", "favorite_color").write.save("namesAndFavColors.parquet")

手工指定特殊参数

1
2
df = spark.read.load("examples/src/main/resources/people.json", format="json")
df.select("name", "age").write.save("namesAndAges.parquet", format="parquet")

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

#-*- coding:utf-8 -*-

import sys
reload(sys)
sys.setdefaultencoding('utf8')
import json
import subprocess
import time
import pandas as pd
from pyspark.sql import Row

import math
from datetime import datetime, timedelta
from pyspark import SparkContext, SparkConf
from pyspark import HiveContext
import collections

def hiveSql():
sql = '''
select param['datatype'] as datatype
from xxx between aaa and bbb
'''
return sql



def parse_poi(row):
# 第二列取值:
# 1 参数错误并且经纬度为0,
# 2 参数错误并且经纬度不是0
# 3 query为空
# 4 其他异常情况
parse_result = "empty\tempty\tempty"
json_str = row.json_str
if type(json_str) != str and type(json_str) != unicode:
return parse_result
try:
res = json.loads(json_str)
except:
return parse_result

if row.searchname != '':
parse_result = '%s\t%s\t%s'%(row.nnn, 0, row.oooo)
return parse_result



def parse_mmm(sc):
hc = HiveContext(sc)

all_sug_poi = sc.parallelize([])
sql = hiveSql()
print sql
df = hc.sql(sql)
mmmm = df.rdd.map(parse_poi).map(lambda x:x.split("\t"))

ooooo = mmmm.map(lambda p: Row(searchname=p[0], stattype=p[1], datatype=p[2]))

dudtf = ooooo.toDF()
dudtf.printSchema()
dudtf.groupBy('stattype').count().show()
dudtf.groupBy('stattype', 'datatype').count().show()


if __name__ == "__main__":
conf = SparkConf()
conf.setAppName('mmmmxxxx')
sc = SparkContext(conf = conf)
parse_mmm(sc)

在这个例子中,

  • 首先查询hive,要使用HiveContext去查询。
  • 再次,由于数据存在一定的污染,因此在进行json.loads之前必须对row.json_str进行类型断言;并且当json.loads抛出异常时,进行捕获。
  • 在执行mmmm.map时使用map,而不是flatMap。

##参考文章:

cpp_libconfig

参考处:

https://hyperrealm.github.io/libconfig/

简单用法

libconfig::Config 的方法

#include <libconfig.h++>
#include <iostream>

int main() {
    try {
        libconfig::Config config;
        config.readFile("config.ini");
        const libconfig::Setting& serverConf = config.lookup("server");
        int serverPort;
        bool flag = serverConf.lookupValue("service_port", serverPort);
        std::cout << "server port " << serverPort << std::endl;
    } catch (const libconfig::ConfigException& e) {
        std::cout << "exception:" << e.what() << std::endl;
    }
}

faiss-install

一、clone faiss项目

git clone https://github.com/facebookresearch/faiss.git

二、安装必要依赖和工具

  • conda install openblas

  • brew install llvm

  • 如果提示:dyld: Library not loaded: @rpath/libomp.dylib

    • ln -s $HOME/anaconda2/lib/libopenblas.dylib /usr/lib/libopenblas.dylib
    • export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/usr/local/opt/llvm/lib/
  • make tests/test_blas

常见错误:

  • fatal error: ‘stdio.h’ file not found

    • 解决:xcode-select –install
  • fatal error: ‘malloc.h’ file not found

    • IndexScalarQuantizer.cpp 中 malloc.h 改成 sys/malloc.h

三、编译安装c++部分

  • make all
  • ./demos/demo_ivfpq_indexing

四、安装faiss的python部分

  • which python

    • /usr/local/Cellar/anaconda2/bin/python
    • 建议使用anaconda的python
  • make py

  • python -c “import faiss”

五、 centos按照

  • 安装依赖

    sudo yum install -y openblas swig

  • 获取 faiss 源代码

    git clone https://github.com/facebookresearch/faiss.git

  • 编译 faiss

    cd faiss
    cp example_makefiles/makefile.inc.Linux makefile.inc
    make all

  • 编译 python 接口

    make py

  • 设置优化选项

    export OMP_WAIT_POLICY=PASSIVE

  • 运行 python 示例代码

    export PYTHONPATH=.
    python tutorial/python/1-Flat.py
    python tutorial/python/2-IVFFlat.py
    python tutorial/python/3-IVFPQ.py

五、参考文章